diff --git a/.changeset/README.md b/.changeset/README.md new file mode 100644 index 000000000..e5b6d8d6a --- /dev/null +++ b/.changeset/README.md @@ -0,0 +1,8 @@ +# Changesets + +Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works +with multi-package repos, or single-package repos to help you version and publish your code. You can +find the full documentation for it [in our repository](https://github.com/changesets/changesets) + +We have a quick list of common questions to get you started engaging with this project in +[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 000000000..765c9d223 --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", + "changelog": "@changesets/cli/changelog", + "commit": false, + "fixed": [], + "linked": [], + "access": "public", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": { + "onlyUpdatePeerDependentsWhenOutOfRange": true + }, + "ignore": [] +} diff --git a/.env.example b/.env.example index fdf442b9d..764c9ab79 100644 --- a/.env.example +++ b/.env.example @@ -1,7 +1,7 @@ E2E_PRIVATE_KEY_ONE= E2E_PRIVATE_KEY_TWO= -E2E_BICO_PAYMASTER_KEY_MUMBAI= +BUNDLER_URL=https://bundler.biconomy.io/api/v2/80002/cJPK7B3ru.dd7f7861-190d-45ic-af80-6877f74b8f44 +E2E_BICO_PAYMASTER_KEY_AMOY= E2E_BICO_PAYMASTER_KEY_BASE= -E2E_BICO_PAYMASTER_KEY_OP= -BICONOMY_SDK_DEBUG=true -WITH_MAINNET_TESTS=false \ No newline at end of file +CHAIN_ID=80002 +CODECOV_TOKEN= \ No newline at end of file diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index bc013db12..000000000 --- a/.eslintignore +++ /dev/null @@ -1,14 +0,0 @@ -# Ignore node_modules in the root and in all packages -**/node_modules/ - -# Ignore build or dist directories -**/dist/ -**/build/ -**/coverage/ - -# Ignore any auto-generated files -**/typechain/ - -# Ignore any config files -*.config.js -*.config.ts \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index ce0d3c84a..000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,49 +0,0 @@ -module.exports = { - parser: "@typescript-eslint/parser", - extends: [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended", - "airbnb-typescript/base", - "plugin:import/typescript", - "plugin:@typescript-eslint/eslint-recommended", - "plugin:prettier/recommended", - ], - parserOptions: { - ecmaVersion: 2020, - sourceType: "module", - project: "./tsconfig.eslint.json", - }, - env: { - node: true, - es6: true, - }, - plugins: ["@typescript-eslint", "prettier", "security", "import"], - rules: { - "prettier/prettier": "error", - "no-var": "error", - "prefer-const": "error", - "no-unused-vars": ["warn", { argsIgnorePattern: "^_" }], // needs to be set to "error" later - "no-console": "warn", - "@typescript-eslint/naming-convention": "off", // needs to be removed later - "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/explicit-module-boundary-types": "off", - "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }], - "security/detect-object-injection": "warn", - "security/detect-unsafe-regex": "error", - "security/detect-object-injection": "off", // turning off Injection Sink rule - "@typescript-eslint/no-throw-literal": "off", // temp deactivated needs to be removed once fixed - "@typescript-eslint/ban-ts-ignore": "off", - "@typescript-eslint/ban-ts-comment": "off", - "import/extensions": ["error", "ignorePackages"], - "import/no-unresolved": "off", - }, - settings: {}, - overrides: [ - { - files: ["*.ts", "*.tsx"], - rules: { - "@typescript-eslint/explicit-function-return-type": ["warn", { allowExpressions: true }], - }, - }, - ], -}; diff --git a/.github/ISSUE_TEMPLATE/1_general_issue.yml b/.github/ISSUE_TEMPLATE/1_general_issue.yml new file mode 100644 index 000000000..1e2fac688 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/1_general_issue.yml @@ -0,0 +1,26 @@ +name: 💡 General Inquiry & Suggestions +description: Share general questions or suggestions that don't fit other categories +title: "[GENERAL] " +labels: ["question", "enhancement"] +body: + - type: markdown + attributes: + value: "Got a question or suggestion? We're all ears!" + - type: textarea + attributes: + label: Inquiry or Suggestion + description: What would you like to share with us? + placeholder: "I'm wondering about..." + validations: + required: false + - type: input + attributes: + label: Relevant Links or References + description: Optionally, add any relevant links or references. + placeholder: "e.g., https://github.com/example" + - type: checkboxes + attributes: + label: Code of Conduct + options: + - label: I agree to follow this project's Code of Conduct. + required: true diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/2_bug_report.yml similarity index 94% rename from .github/ISSUE_TEMPLATE/bug_report.yml rename to .github/ISSUE_TEMPLATE/2_bug_report.yml index 45f4d6bf0..038107e78 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/2_bug_report.yml @@ -1,6 +1,7 @@ -name: Bug Report -description: File a bug/issue -title: "bug: " +name: 🐛 Bug Report & Test Failures +description: Report unexpected behaviors or failing tests +title: "[BUG] " +labels: ["bug", "help wanted"] body: - type: markdown attributes: diff --git a/.github/ISSUE_TEMPLATE/3_feature_request.yml b/.github/ISSUE_TEMPLATE/3_feature_request.yml new file mode 100644 index 000000000..9d1cc0b6e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/3_feature_request.yml @@ -0,0 +1,31 @@ +name: ✨ Feature Requests & Performance Improvements +description: Suggest a new feature or performance enhancement +title: "[FEATURE] " +labels: ["enhancement", "good first issue"] +body: + - type: markdown + attributes: + value: "Your suggestions inspire us to improve. Share your ideas below!" + - type: input + attributes: + label: Feature or Improvement Description + description: Describe the feature or improvement you're suggesting. + placeholder: "e.g., Add support for platform Z." + validations: + required: true + - type: textarea + attributes: + label: Benefits & Outcomes + description: Explain the benefits of your suggestion and the expected outcomes. + placeholder: "This improvement will improve performance by 30%..." + - type: input + attributes: + label: Any References? + description: Provide links or references to similar features or standards. + placeholder: "EIP-1234, https://github.com/example" + - type: checkboxes + attributes: + label: Code of Conduct + options: + - label: I agree to follow this project's Code of Conduct. + required: true diff --git a/.github/ISSUE_TEMPLATE/4_security_report.yml b/.github/ISSUE_TEMPLATE/4_security_report.yml new file mode 100644 index 000000000..6fc0ef4fa --- /dev/null +++ b/.github/ISSUE_TEMPLATE/4_security_report.yml @@ -0,0 +1,31 @@ +name: 🔒 Security Pre-Screening +description: Pre-screening for security-related reports +title: "[SECURITY PRE-SCREEN] " +labels: ["security", "triage needed"] +body: + - type: markdown + attributes: + value: "Security is our top priority. If you've discovered a potential security issue please proceed." + - type: checkboxes + attributes: + label: Security Level Acknowledgement + options: + - label: "I understand this issue will be public. It is NOT critical or high risk and does not endanger deployed contracts. If it is please email: security@biconomy.io" + required: true + - type: input + attributes: + label: Overview + description: Provide a summary of the non-critical security concern or question. + placeholder: "e.g., Questions about the audit process." + validations: + required: true + - type: textarea + attributes: + label: Additional Details + description: Offer more detail on your concern or question. + placeholder: "Provide any additional context..." + - type: input + attributes: + label: Suggestions for Mitigation + description: (Optional) Suggest ways to address the concern. + placeholder: "Potential mitigation steps include..." diff --git a/.github/ISSUE_TEMPLATE/5_document_improvement.yml b/.github/ISSUE_TEMPLATE/5_document_improvement.yml new file mode 100644 index 000000000..a4b0b5257 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/5_document_improvement.yml @@ -0,0 +1,33 @@ +name: 📚 Documentation Improvement +description: Propose improvements or report issues with documentation +title: "[DOCS] " +labels: ["documentation"] +body: + - type: markdown + attributes: + value: "Help us enhance our documentation for everyone." + - type: input + attributes: + label: Documentation Page/Section + description: Which page or section are you referring to? + placeholder: "e.g., README.md, TSDoc guidelines." + validations: + required: true + - type: textarea + attributes: + label: Suggested Improvements + description: Detail the improvements or corrections needed. + placeholder: "The section on XYZ could clarify..." + validations: + required: true + - type: input + attributes: + label: Additional Comments + description: Any other comments or suggestions? + placeholder: "Consider adding examples for..." + - type: checkboxes + attributes: + label: Code of Conduct + options: + - label: I agree to follow this project's Code of Conduct. + required: true diff --git a/.github/ISSUE_TEMPLATE/6_build_deployment_issue.yml b/.github/ISSUE_TEMPLATE/6_build_deployment_issue.yml new file mode 100644 index 000000000..e0034b17e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/6_build_deployment_issue.yml @@ -0,0 +1,33 @@ +name: 🛠 Build & Deployment Issues +description: Report issues +title: "[BUILD/DEPLOY] " +labels: ["bug", "help wanted"] +body: + - type: markdown + attributes: + value: "Help us identify build or deployment problems to improve our processes." + - type: input + attributes: + label: Issue Summary + description: Briefly describe the issue encountered. + placeholder: "e.g., Failed to deploy contract due to..." + validations: + required: true + - type: textarea + attributes: + label: Error Logs & Messages + description: Provide any error logs or messages seen. + placeholder: "Error: Failed to..." + validations: + required: true + - type: input + attributes: + label: Environment & Tools + description: Mention the tools and environment where the issue occurred. + placeholder: "e.g., Truffle v5.3, Rinkeby testnet" + - type: checkboxes + attributes: + label: Code of Conduct + options: + - label: I agree to follow this project's Code of Conduct. + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index 5b7de7d5d..000000000 --- a/.github/ISSUE_TEMPLATE/config.yml +++ /dev/null @@ -1,8 +0,0 @@ -blank_issues_enabled: false -contact_links: - - name: Ask Question - url: https://github.com/bcnmy/biconomy-client-sdk/discussions - about: Ask questions and discuss with other community members - - name: Request Feature - url: https://github.com/bcnmy/biconomy-client-sdk/discussions - about: Requests features or brainstorm ideas for new functionality diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 3e93355fb..000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -name: Feature Request -about: Propose an enhancement or new feature to improve the project -title: "Feature: <Your Feature>" -labels: feature-request, needs-review -assignees: "" ---- - -**Problem You're Facing** - -<!-- Briefly describe the problem you're trying to solve or the limitation you've encountered. --> - -**Proposed Solution** - -<!-- What would you like to see happen? --> - -**Alternatives Considered** - -<!-- Any other solutions or features you've considered. --> - -## Use Cases - -<!-- Help us understand the broader context by providing some typical use cases where this feature would be helpful. --> - -**Additional Info** - -<!-- Provide any additional details, context, or screenshots about the feature request. --> diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md new file mode 100644 index 000000000..35e920656 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md @@ -0,0 +1,22 @@ +## Pull Request for SDK Improvement + +**Describe your changes:** + +<!-- Briefly describe what you're changing or fixing. --> + +**Link any related issues:** + +<!-- Link any related issues here. --> + +**Testing:** + +<!-- Describe how the changes were tested. Include steps if applicable. --> + +**Note:** Please ensure all tests and lint checks pass before requesting a review. If there are any errors, fix them prior to submission. + +**Checklist:** + +- [ ] I have performed a self-review of my own code. +- [ ] I have added tests that prove my fix is effective or that my feature works. +- [ ] I have made corresponding changes to the documentation, if applicable. +- [ ] My changes generate no new warnings or errors. diff --git a/.github/actions/build/action.yml b/.github/actions/build/action.yml new file mode 100644 index 000000000..1cd962cb5 --- /dev/null +++ b/.github/actions/build/action.yml @@ -0,0 +1,16 @@ +name: "Build" +description: "Prepare repository, all dependencies and build" + +runs: + using: "composite" + steps: + - name: Set up Bun + uses: oven-sh/setup-bun@v1 + + - name: Install dependencies + shell: bash + run: bun install --frozen-lockfile + + - name: Build + shell: bash + run: bun run build diff --git a/.github/actions/install-dependencies/action.yml b/.github/actions/install-dependencies/action.yml new file mode 100644 index 000000000..3dbb2bd0b --- /dev/null +++ b/.github/actions/install-dependencies/action.yml @@ -0,0 +1,13 @@ +name: "Install dependencies" +description: "Prepare repository and all dependencies" + +runs: + using: "composite" + steps: + - name: Set up Bun + uses: oven-sh/setup-bun@v1 + + - name: Install dependencies + shell: bash + run: | + bun install --frozen-lockfile diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md deleted file mode 100644 index 9b66596c9..000000000 --- a/.github/pull_request_template.md +++ /dev/null @@ -1,35 +0,0 @@ -# Summary - -<!-- Please provide a brief summary of the changes and the issue number this PR addresses. --> - -Related Issue: # (issue number) - -## Change Type - -- [ ] Bug Fix -- [ ] Refactor -- [ ] New Feature -- [ ] Breaking Change -- [ ] Documentation Update -- [ ] Performance Improvement -- [ ] Other - -# Checklist - -- [ ] My code follows this project's style guidelines -- [ ] I've reviewed my own code -- [ ] I've added comments for any hard-to-understand areas -- [ ] I've updated the documentation if necessary -- [ ] My changes generate no new warnings -- [ ] I've added tests that prove my fix is effective or my feature works -- [ ] All unit tests pass locally with my changes -- [ ] Any dependent changes have been merged and published - -# Additional Information - -<!-- Any additional information or context about the PR. --> - -# Branch Naming - -<!-- Make sure your branch name follows the pattern: `features/`, `fixes/`, or `releases/`. --> -<!-- **Note**: The person creating the PR is responsible for merging and deleting the branch. Ensure the code has been tested, commented, linted, and documents updated if needed. --> diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..08c18cd34 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,14 @@ +name: build +on: + workflow_dispatch: + pull_request: + types: [opened, reopened, synchronize, ready_for_review] +jobs: + build: + name: build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Build + uses: ./.github/actions/build diff --git a/.github/workflows/check_branch_name.yml b/.github/workflows/check_branch_name.yml deleted file mode 100644 index 39422432d..000000000 --- a/.github/workflows/check_branch_name.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Check Branch Name - -on: - create: - types: [branch] - -jobs: - check-branch-name: - runs-on: ubuntu-latest - if: github.event.ref_type == 'branch' - steps: - - name: Ensure branch name follows GitFlow conventions - run: | - BRANCH_NAME="${{ github.ref#refs/heads/ }}" - echo "Created branch: $BRANCH_NAME" - - # Checking against GitFlow naming conventions for branches - if [[ ! $BRANCH_NAME =~ ^(features/|fixes/|releases/) ]]; then - echo "error: Branch names should follow GitFlow naming convention (features/, fixes/, releases/)." - exit 1 - fi diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 000000000..653e7b1e3 --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,44 @@ +name: coverage +on: + workflow_dispatch: + push: + branches: + - main +jobs: + coverage: + name: coverage + permissions: write-all + runs-on: ubuntu-latest + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + steps: + - uses: actions/checkout@v3 + + - name: Install dependencies + uses: ./.github/actions/install-dependencies + + - name: Run the tests + run: bun run test:coverage + env: + E2E_PRIVATE_KEY_ONE: ${{ secrets.E2E_PRIVATE_KEY_ONE }} + E2E_PRIVATE_KEY_TWO: ${{ secrets.E2E_PRIVATE_KEY_TWO }} + BUNDLER_URL: https://bundler.biconomy.io/api/v2/80002/cJPK7B3ru.dd7f7861-190d-45ic-af80-6877f74b8f44 + E2E_BICO_PAYMASTER_KEY_BASE: ${{ secrets.E2E_BICO_PAYMASTER_KEY_BASE }} + E2E_BICO_PAYMASTER_KEY_AMOY: ${{ secrets.E2E_BICO_PAYMASTER_KEY_AMOY }} + CHAIN_ID: 80002 + + - name: report coverage + uses: davelosert/vitest-coverage-report-action@v2 + with: + json-summary-path: ./coverage/coverage-summary.json + json-final-path: "./coverage/coverage-final.json" + vite-config-path: ./tests/vitest.config.ts + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v4.0.1 + with: + token: ${{ secrets.CODECOV_TOKEN }} + verbose: true + slug: bcnmy/biconomy-client-sdk diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 188b963b1..078b083ba 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -1,26 +1,30 @@ -name: Build and Deploy Documentation +name: deploy docs on: workflow_dispatch: push: branches: - - docs + - main permissions: contents: write jobs: - build-docs-and-deploy: + deploy-docs: runs-on: ubuntu-latest steps: - - name: Checkout 🛎️ - uses: actions/checkout@v3 + - uses: actions/checkout@v3 + - run: git config --global user.email "gh@runner.com" + - run: git config --global user.name "gh-runner" - - name: Install and Build - run: | - yarn - yarn build - yarn --cwd ./packages/account docs + - name: Install dependencies + uses: ./.github/actions/install-dependencies + + - name: Set remote url + run: git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/bcnmy/biconomy-client-sdk.git + + - name: Run the tests + run: bun run docs:deploy - name: Deploy 🚀 uses: JamesIves/github-pages-deploy-action@v4 with: - folder: ./packages/account/docs + folder: ./docs diff --git a/.github/workflows/mainnet_tests.yml b/.github/workflows/mainnet_tests.yml deleted file mode 100644 index 3118a1e94..000000000 --- a/.github/workflows/mainnet_tests.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: E2E Test workflow - with mainnet tests -on: - workflow_dispatch: -jobs: - e2e_test: - name: E2E tests - with mainnet tests - runs-on: ubuntu-latest - strategy: - matrix: - node-version: [18.x] - - steps: - - name: Checkout - uses: "actions/checkout@main" - - - name: Set Node.js - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - - - name: Install dependencies - run: yarn install --frozen-lockfile && yarn build - - - name: Run tests - env: - E2E_PRIVATE_KEY_ONE: ${{ secrets.E2E_PRIVATE_KEY_ONE }} - E2E_PRIVATE_KEY_TWO: ${{ secrets.E2E_PRIVATE_KEY_TWO }} - E2E_BICO_PAYMASTER_KEY_MUMBAI: ${{ secrets.E2E_BICO_PAYMASTER_KEY_MUMBAI }} - E2E_BICO_PAYMASTER_KEY_BASE: ${{ secrets.E2E_BICO_PAYMASTER_KEY_BASE }} - E2E_BICO_PAYMASTER_KEY_OP: ${{ secrets.E2E_BICO_PAYMASTER_KEY_OP }} - WITH_MAINNET_TESTS: true - run: yarn test:e2e diff --git a/.github/workflows/mark_stale.yml b/.github/workflows/mark_stale.yml deleted file mode 100644 index 1864296c5..000000000 --- a/.github/workflows/mark_stale.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: Mark Inactive Issues and PRs - -on: - schedule: - - cron: "0 0 * * *" - -jobs: - stale: - runs-on: ubuntu-latest - permissions: - issues: write - pull-requests: write - - steps: - - uses: actions/stale@v5 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: "This issue has been inactive for 30 days. It will be closed due to inactivity. If this issue is still relevant, please comment to keep it open. Alternatively, you can create a new issue with updated information." - stale-pr-message: "This PR has been inactive for 30 days. If it's waiting for a review, please reach out to the team. Otherwise, please update the PR or it will be closed due to inactivity." - stale-issue-label: "inactive-issue" - stale-pr-label: "inactive-pr" - days-before-stale: 30 diff --git a/.github/workflows/pr-lint.yml b/.github/workflows/pr-lint.yml new file mode 100644 index 000000000..3e77f7837 --- /dev/null +++ b/.github/workflows/pr-lint.yml @@ -0,0 +1,17 @@ +name: pr lint +on: + workflow_dispatch: + pull_request: + types: [opened, reopened, synchronize, ready_for_review, edited] +jobs: + enforce_title: + name: pr lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Install dependencies + uses: ./.github/actions/install-dependencies + + - name: Use commitlint to check PR title + run: echo "${{ github.event.pull_request.title }}" | bun commitlint diff --git a/.github/workflows/pull_request_approved.yml b/.github/workflows/pull_request_approved.yml deleted file mode 100644 index 84688b90b..000000000 --- a/.github/workflows/pull_request_approved.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: E2E Test workflow -on: - pull_request_review: - types: [submitted] - workflow_dispatch: -jobs: - e2e_test: - if: github.event.review.state == 'approved' - name: E2E tests - runs-on: ubuntu-latest - strategy: - matrix: - node-version: [18.x] - - steps: - - name: Checkout - uses: "actions/checkout@main" - - - name: Set Node.js - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - - - name: Install dependencies - run: yarn install --frozen-lockfile && yarn build - - - name: Run tests - env: - E2E_PRIVATE_KEY_ONE: ${{ secrets.E2E_PRIVATE_KEY_ONE }} - E2E_PRIVATE_KEY_TWO: ${{ secrets.E2E_PRIVATE_KEY_TWO }} - E2E_BICO_PAYMASTER_KEY_MUMBAI: ${{ secrets.E2E_BICO_PAYMASTER_KEY_MUMBAI }} - E2E_BICO_PAYMASTER_KEY_BASE: ${{ secrets.E2E_BICO_PAYMASTER_KEY_BASE }} - E2E_BICO_PAYMASTER_KEY_OP: ${{ secrets.E2E_BICO_PAYMASTER_KEY_OP }} - run: yarn test:e2e diff --git a/.github/workflows/push_check.yml b/.github/workflows/push_check.yml deleted file mode 100644 index 35705a430..000000000 --- a/.github/workflows/push_check.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: Test workflow -on: [push, workflow_dispatch] - -jobs: - lint: - name: Lint sources - runs-on: ubuntu-latest - strategy: - matrix: - node-version: [18.x] - - steps: - - name: Checkout - uses: "actions/checkout@main" - - - name: Set Node.js - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - - name: Install dependencies - run: yarn install --frozen-lockfile - - name: Lint sources - run: yarn run lint - - unit_test: - name: Unit tests - runs-on: ubuntu-latest - strategy: - matrix: - node-version: [18.x] - - steps: - - name: Checkout - uses: "actions/checkout@main" - - - name: Set Node.js - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - - - name: Install dependencies - run: yarn install --frozen-lockfile && yarn build - - name: Run tests - run: yarn test diff --git a/.github/workflows/size-report.yml b/.github/workflows/size-report.yml new file mode 100644 index 000000000..0cbdac716 --- /dev/null +++ b/.github/workflows/size-report.yml @@ -0,0 +1,34 @@ +name: size report +on: + workflow_dispatch: + pull_request: + types: [opened, reopened, synchronize, ready_for_review] + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + size-report: + name: size report + runs-on: ubuntu-latest + timeout-minutes: 5 + permissions: write-all + + steps: + - name: Clone repository + uses: actions/checkout@v3 + + - name: Set up Bun + uses: oven-sh/setup-bun@v1 + + - name: Install dependencies + shell: bash + run: | + bun install --frozen-lockfile + + - name: Report bundle size + uses: andresz1/size-limit-action@master + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + package_manager: bun diff --git a/.github/workflows/test-read.yml b/.github/workflows/test-read.yml new file mode 100644 index 000000000..4a36c8c45 --- /dev/null +++ b/.github/workflows/test-read.yml @@ -0,0 +1,28 @@ +name: test-read +on: + workflow_dispatch: + pull_request: + types: [opened, reopened, synchronize, ready_for_review] +jobs: + test-read: + name: test-read + permissions: write-all + runs-on: ubuntu-latest + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + steps: + - uses: actions/checkout@v3 + + - name: Install dependencies + uses: ./.github/actions/install-dependencies + + - name: Run the tests + run: bun run test:ci -t=Read + env: + E2E_PRIVATE_KEY_ONE: ${{ secrets.E2E_PRIVATE_KEY_ONE }} + E2E_PRIVATE_KEY_TWO: ${{ secrets.E2E_PRIVATE_KEY_TWO }} + BUNDLER_URL: https://bundler.biconomy.io/api/v2/80002/cJPK7B3ru.dd7f7861-190d-45ic-af80-6877f74b8f44 + E2E_BICO_PAYMASTER_KEY_BASE: ${{ secrets.E2E_BICO_PAYMASTER_KEY_BASE }} + E2E_BICO_PAYMASTER_KEY_AMOY: ${{ secrets.E2E_BICO_PAYMASTER_KEY_AMOY }} + CHAIN_ID: 80002 diff --git a/.github/workflows/test-write.yml b/.github/workflows/test-write.yml new file mode 100644 index 000000000..ee749bdbe --- /dev/null +++ b/.github/workflows/test-write.yml @@ -0,0 +1,60 @@ +name: test-write +on: + workflow_dispatch: + pull_request_review: + types: [submitted] + pull_request: + types: [opened] +jobs: + test-write: + name: test-write + permissions: write-all + runs-on: ubuntu-latest + concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-test-write + cancel-in-progress: true + steps: + - uses: actions/checkout@v3 + + - name: Install dependencies + uses: ./.github/actions/install-dependencies + + - name: Run the account tests + run: bun run test:ci -t=Account:Write + env: + E2E_PRIVATE_KEY_ONE: ${{ secrets.E2E_PRIVATE_KEY_ONE }} + E2E_PRIVATE_KEY_TWO: ${{ secrets.E2E_PRIVATE_KEY_TWO }} + BUNDLER_URL: https://bundler.biconomy.io/api/v2/80002/cJPK7B3ru.dd7f7861-190d-45ic-af80-6877f74b8f44 + E2E_BICO_PAYMASTER_KEY_BASE: ${{ secrets.E2E_BICO_PAYMASTER_KEY_BASE }} + E2E_BICO_PAYMASTER_KEY_AMOY: ${{ secrets.E2E_BICO_PAYMASTER_KEY_AMOY }} + CHAIN_ID: 80002 + + - name: Run the bundler tests + run: bun run test:ci -t=Bundler:Write + env: + E2E_PRIVATE_KEY_ONE: ${{ secrets.E2E_PRIVATE_KEY_ONE }} + E2E_PRIVATE_KEY_TWO: ${{ secrets.E2E_PRIVATE_KEY_TWO }} + BUNDLER_URL: https://bundler.biconomy.io/api/v2/80002/cJPK7B3ru.dd7f7861-190d-45ic-af80-6877f74b8f44 + E2E_BICO_PAYMASTER_KEY_BASE: ${{ secrets.E2E_BICO_PAYMASTER_KEY_BASE }} + E2E_BICO_PAYMASTER_KEY_AMOY: ${{ secrets.E2E_BICO_PAYMASTER_KEY_AMOY }} + CHAIN_ID: 80002 + + - name: Run the paymaster tests + run: bun run test:ci -t=Paymaster:Write + env: + E2E_PRIVATE_KEY_ONE: ${{ secrets.E2E_PRIVATE_KEY_ONE }} + E2E_PRIVATE_KEY_TWO: ${{ secrets.E2E_PRIVATE_KEY_TWO }} + BUNDLER_URL: https://bundler.biconomy.io/api/v2/80002/cJPK7B3ru.dd7f7861-190d-45ic-af80-6877f74b8f44 + E2E_BICO_PAYMASTER_KEY_BASE: ${{ secrets.E2E_BICO_PAYMASTER_KEY_BASE }} + E2E_BICO_PAYMASTER_KEY_AMOY: ${{ secrets.E2E_BICO_PAYMASTER_KEY_AMOY }} + CHAIN_ID: 80002 + + - name: Run the modules tests + run: bun run test:ci -t=Modules:Write + env: + E2E_PRIVATE_KEY_ONE: ${{ secrets.E2E_PRIVATE_KEY_ONE }} + E2E_PRIVATE_KEY_TWO: ${{ secrets.E2E_PRIVATE_KEY_TWO }} + BUNDLER_URL: https://bundler.biconomy.io/api/v2/80002/cJPK7B3ru.dd7f7861-190d-45ic-af80-6877f74b8f44 + E2E_BICO_PAYMASTER_KEY_BASE: ${{ secrets.E2E_BICO_PAYMASTER_KEY_BASE }} + E2E_BICO_PAYMASTER_KEY_AMOY: ${{ secrets.E2E_BICO_PAYMASTER_KEY_AMOY }} + CHAIN_ID: 80002 diff --git a/.gitignore b/.gitignore index ac3583499..41980e0af 100644 --- a/.gitignore +++ b/.gitignore @@ -1,75 +1,180 @@ +_cjs +_esm +_types + # Logs + logs -*.log +_.log +npm-debug.log_ yarn-debug.log* yarn-error.log* -lockfiles +lerna-debug.log* +.pnpm-debug.log* + +# Caches + +.cache # Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json -# Coverage directory used by tools like istanbul +report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json + +# Runtime data + +pids +_.pid +_.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover coverage +lib-cov + +# Coverage directory used by tools like istanbul *.lcov # nyc test coverage + .nyc_output -# Compiled binary addons -build/ -dist/ +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) + +.grunt + +# Bower dependency directory (https://bower.io/) + +bower_components + +# node-waf configuration + +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) + +build/Release # Dependency directories + node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) + +web_modules/ + +# TypeScript cache + +*.tsbuildinfo # Optional npm cache directory + .npm # Optional eslint cache + .eslintcache +# Optional stylelint cache + +.stylelintcache + +# Microbundle cache + +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history + +.node_repl_history + +# Output of 'npm pack' + +*.tgz + # Yarn Integrity file + .yarn-integrity -# dotenv environment variables file +# dotenv environment variable files + .env -.env.test +.env.development.local +.env.test.local +.env.production.local .env.local +# parcel-bundler cache (https://parceljs.org/) + +.parcel-cache + +# Next.js build output + +.next +out + +# Nuxt.js build / generate output + +.nuxt +dist + +# Gatsby files + +# Comment in the public line in if your project uses Gatsby and not Next.js + +# https://nextjs.org/blog/next-9-1#public-directory-support + +# public + +# vuepress build output + +.vuepress/dist + +# vuepress v2.x temp and cache directory + +.temp + +# Docusaurus cache and generated files + +.docusaurus + +# Serverless directories + +.serverless/ + +# FuseBox cache + +.fusebox/ + +# DynamoDB Local files + +.dynamodb/ + +# TernJS port file + +.tern-port + # Stores VSCode versions used for testing VSCode extensions + .vscode .vscode-test # yarn v2 + .yarn/cache .yarn/unplugged .yarn/build-state.yml .yarn/install-state.gz .pnp.* -# macOS +# IntelliJ based IDEs +.idea + +# Finder (MacOS) folder config .DS_Store -# Hardhat files -cache -artifacts -deployments - -# lockfiles -packages/account/package-lock.json -packages/modules/package-lock.json -packages/bundler/package-lock.json -packages/paymaster/package-lock.json -packages/particle-auth/package-lock.json -packages/transak/package-lock.json -package-lock.json - -#ignore sessionStorageData files -packages/modules/tests/utils/sessionStorageData/* -#except sessionStorageData folder -!packages/modules/tests/utils/sessionStorageData/.gitkeep - -openapi/ - -# docs -packages/account/docs/* \ No newline at end of file +docs + +tests/sessionStorageData \ No newline at end of file diff --git a/.nvmrc b/.nvmrc deleted file mode 100644 index b1215e876..000000000 --- a/.nvmrc +++ /dev/null @@ -1 +0,0 @@ -v18.16.0 \ No newline at end of file diff --git a/.nycrc.json b/.nycrc.json deleted file mode 100644 index 5d9f97afe..000000000 --- a/.nycrc.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "include": ["src/**/*.ts"] -} diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index bc013db12..000000000 --- a/.prettierignore +++ /dev/null @@ -1,14 +0,0 @@ -# Ignore node_modules in the root and in all packages -**/node_modules/ - -# Ignore build or dist directories -**/dist/ -**/build/ -**/coverage/ - -# Ignore any auto-generated files -**/typechain/ - -# Ignore any config files -*.config.js -*.config.ts \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json deleted file mode 100644 index 6b3f54736..000000000 --- a/.prettierrc.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "printWidth": 150, - "semi": true, - "singleQuote": false, - "trailingComma": "all", - "tabWidth": 2 -} diff --git a/.size-limit.json b/.size-limit.json new file mode 100644 index 000000000..a2bdf369c --- /dev/null +++ b/.size-limit.json @@ -0,0 +1,37 @@ +[ + { + "name": "core (esm)", + "path": "./dist/_esm/index.js", + "limit": "60 kB", + "import": "*" + }, + { + "name": "core (cjs)", + "path": "./dist/_cjs/index.js", + "limit": "60 kB" + }, + { + "name": "account (tree-shaking)", + "path": "./dist/_esm/index.js", + "limit": "60 kB", + "import": "{ createSmartAccountClient }" + }, + { + "name": "bundler (tree-shaking)", + "path": "./dist/_esm/bundler/index.js", + "limit": "5 kB", + "import": "{ createBundler }" + }, + { + "name": "paymaster (tree-shaking)", + "path": "./dist/_esm/paymaster/index.js", + "limit": "5 kB", + "import": "{ createPaymaster }" + }, + { + "name": "modules (tree-shaking)", + "path": "./dist/_esm/modules/index.js", + "limit": "60 kB", + "import": "{ createSessionKeyManagerModule }" + } +] diff --git a/CHANGELOG.md b/CHANGELOG.md index b950ebfb7..96cc7c818 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,25 +1,202 @@ -# Change Log +# @biconomy/account -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## 4.2.0 + +### Minor Changes + +- Features: + + - Improved getBalances utility helper ([da340f](https://github.com/bcnmy/biconomy-client-sdk/pull/479/commits/da340fbcc20778c9810dd8980061a6bb7b4cf097)) + - Added 1271 Signature support ([fd832fe](https://github.com/bcnmy/biconomy-client-sdk/pull/479/commits/fd832fe2e286a5d3e57d3292cfa395e388b07b96)) + - Added withdrawal utility helper ([7a93d87](https://github.com/bcnmy/biconomy-client-sdk/pull/479/commits/7a93d871ecefbce8ed5ef63349c055072877189e)) + - Reduce bundle size ([7c594fa](https://github.com/bcnmy/biconomy-client-sdk/pull/479/commits/7c594fa74e81650b4cb5043afb4cd1153e638a19)) + - Integrate [AAErrors](https://github.com/bcnmy/aa-errors) ([7c594fa](https://github.com/bcnmy/biconomy-client-sdk/pull/479/commits/7c594fa74e81650b4cb5043afb4cd1153e638a19)) + - Added 6492 Signature support ([fd832fe](https://github.com/bcnmy/biconomy-client-sdk/pull/479/commits/fd832fe2e286a5d3e57d3292cfa395e388b07b96)) + - Added Token Balances to getSupportedTokens payload ([869436](https://github.com/bcnmy/biconomy-client-sdk/pull/479/commits/8694366165208cac6bbf7e560fe2abefce0eaa3a)) + - Added gas estimates utility helper ([950a521](https://github.com/bcnmy/biconomy-client-sdk/pull/479/commits/950a521af63d7a719edcbae4df57259d3fe110e7)) + - Added dummy pnd override ([8d34d14](https://github.com/bcnmy/biconomy-client-sdk/pull/479/commits/8d34d148862510fdb76c58852c55a48bc7c20b4c)) + + Chores: + + - Modernise tooling ([7c594fa](https://github.com/bcnmy/biconomy-client-sdk/pull/479/commits/7c594fa74e81650b4cb5043afb4cd1153e638a19)) + - Add changesets + - Migrate tests to Amoy + - Add pr lint + - Add size report + - Add tree shaking + - Add code of conduct + - Update README (table of contents) + - Add SECURITY.md + - Replace prettier with biome + - Replace yarn with bun + - Remove deprecated Base class + - Added "NEXT_PUBLIC_BICONOMY_SDK_DEBUG" to support NextJS debugging information + - Replace jest with vitest + - Added size threshold checks to PRs + - Added test coverage checks to PRs + - Added tsdoc auto-deploy + + Fixes: + + - Fix wrong falsy check for user op nonce ([f2567](https://github.com/bcnmy/biconomy-client-sdk/pull/479/commits/f256712bbf7dc0de40b82c70ad183c59bf5f39f9)) + +## 4.1.1 (2023-07-03) + +- Added missing extensions ([fdbec6](https://github.com/bcnmy/biconomy-client-sdk/pull/451/commits/fdbec68625f4d7f436dc39d4c1779cdbb7c53e6d)) +- Fixed issue reporting format ([815e9440](https://github.com/bcnmy/biconomy-client-sdk/pull/450/commits/815e9440db03ebae98bb24edfcb3bbcabf9b2a61)) + +## 4.1.0 (2023-04-03) + +Features: + +- Added Speed optimisation, removing redundant gasEstimate call to bundler ([2371b2](https://github.com/bcnmy/biconomy-client-sdk/pull/447/commits/2371b230cd5806ec4c7c95ba604d6f924b4be768)) +- Added smartAccount.getBalances() method ([4b8bae](https://github.com/bcnmy/biconomy-client-sdk/pull/447/commits/4b8bae412577b846e700b168976cefa6b0803ff6)) +- Added smartAccount.getSupportedTokens() method ([6d2fb27](https://github.com/bcnmy/biconomy-client-sdk/pull/447/commits/6d2fb27d6f9b424e440e45990ea06820a9d16d4b)) +- Added smartAccount.deploy() method ([be9dc4](https://github.com/bcnmy/biconomy-client-sdk/pull/447/commits/be9dc4d74a3e5a22e69416983436997cf2ea417c)) +- Increased checking of the chainId from the bundler, paymaster and the provider ([5d2f3](https://github.com/bcnmy/biconomy-client-sdk/pull/447/commits/5d2f34d8f0fb4f9ff7c7ddc00336471e57efdcfd)) +- Added entity name to Logger calls ([9278ec](https://github.com/bcnmy/biconomy-client-sdk/pull/447/commits/9278ecc21e060ef75ab29a0d054d95d69cd4ae27)) +- Export a 'getChain' by id helper, which returns a viem chain ([ab2ba](https://github.com/bcnmy/biconomy-client-sdk/pull/449/commits/ab2ba2c518ce867c52bf90b9018dfc1b4ec3b4d4)) +- Add "stateOverride" optional param ([20fd54](https://github.com/bcnmy/biconomy-client-sdk/pull/447/commits/20fd54c817d2dcbc6b7d9a247d890d91b19a9c2f)) + +Fixes: + +- Fix for encodeAbiParameters inside batched session module ([b27061](https://github.com/bcnmy/biconomy-client-sdk/pull/447/commits/b27061e2eec7bafb0620e88e6d94e56e9a13cb76)) +- added flag to skip calldata approval patch ([75698](https://github.com/bcnmy/biconomy-client-sdk/pull/447/commits/75698c827015533e32acb1f535bdf6b738876217)) +- Fixed the particle auth build + +Chores: + +- Added tests for ecdsa module ([1a8f29](https://github.com/bcnmy/biconomy-client-sdk/pull/447/commits/1a8f296c26c9fedd57023f8f6423d7662a3adfee)) +- Increased test coverage ([329003](https://github.com/bcnmy/biconomy-client-sdk/pull/447/commits/329003cebb6b4034496e41651985804cdec0d311)) +- Improved issue reporting guidelines ([8b9fb5d](https://github.com/bcnmy/biconomy-client-sdk/pull/447/commits/8b9fb5de9556870611307c12e57df333619d9252)) +- Added e2e tests for optimism, ran from GH actions ([5051ba](https://github.com/bcnmy/biconomy-client-sdk/pull/447/commits/5051ba5ff14220ad616f1ec3bc93a3f42d6f8887)) +- Added ABI SVM test ([49c96](https://github.com/bcnmy/biconomy-client-sdk/pull/447/commits/49c968220e2db0aeee5cc6419f45df2b98f9792c)) +- Added tests for batched session router testing ([2eb9765](https://github.com/bcnmy/biconomy-client-sdk/pull/447/commits/2eb9765d066fcb7b35d08223257aeb9b38c7a78b)) + +## 4.0.3 (2023-28-02) + +VERSION Bump Only. + +## 4.0.2 (2023-26-02) ### Bug Fixes -- init param ([6bbccfb](https://github.com/bcnmy/biconomy-client-sdk/commit/6bbccfbff8834fa96160685f80bab7d64ec0f135)) +Particle Auth Fix + +## 4.0.1 (2023-02-22) + +### Bug Fixes + +- Fix for RPC endpoints (Quiknode, Blast Sepolia etc) failing to respond because of custom headers being set + +## 4.0.0 (2023-02-06) + +### Features + +- Export bundler / paymaster instances + helpers from master package ([1d1f9d](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/1d1f9dafddf11bde0e1a75383bc935b22448bedd)) +- Export modules aliases from master package ([d6205c](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/d6205c4d76ab846ecdc10843c65e0277f3ceab00)) +- Added sendTransaction abstraction for buildUserOp + sendUserOp ([335c6e](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/335c6e7bfc5ca1ad240e7cbfd678d905c7f16812)) +- Reduced bundle size ([765a3e3](https://github.com/bcnmy/biconomy-client-sdk/commit/765a3e337fb9ad8f1f8dc92b5edcb1ed0940f94d)) +- Added bundler abstraction during SmartAccount init ([591bbb4](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/591bbb4e37774b16cbe801d583d31b3a14608bc1)) +- Added e2e tests that speak with prod bundler / paymasters ([4b4a53a](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/4b4a53aabdf9e22485599872332b3d63e8ddd87a)) +- Added support for simultaneous ethers + viem signers ([8e4b2c8](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/8e4b2c86b871130befbf3b733cf503d24f7226a5)) +- E2E tests for multichain modules ([ecc86e2](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/ecc86e2c7146046a981c3b6fd4bb29e4828b278b)) +- E2E tests for session validation modules ([4ad7ea7](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/4ad7ea7f8eb6a28854dcce83834b2b7ff9ad3287)) +- Added [TSDoc](https://bcnmy.github.io/biconomy-client-sdk) ([638dae](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/638daee0ed6924f67c5151a2d0e5a02d32e4bf23)) +- Make txs more typesafe and default with valueOrData ([b1e5b5e](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/b1e5b5e02ab3a7fb99faa1d45b55e3cbe8d6bc93)) +- Added createSmartAccountClient alias ([232472](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/232472c788bed0619cf6295ade076b6ec3a9e0f8)) +- Improve dx of using paymster to build userOps ([bb54888](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/bb548884e76a94a20329e49b18994503de9e3888)) +- Add ethers v6 signer support ([9727fd](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/9727fd51e47d62904399d17d48f5c9d6b9e591e5)) +- Improved dx of using gas payments with erc20 ([741806](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/741806da68457eba262e1a49be77fcc24360ba36)) + +### Chores + +- Removed SmartAccount Base class in favour of Alchemy's ([be82732](https://github.com/bcnmy/biconomy-client-sdk/commit/be827327fafa858b1551ade0c8389293034cacbb)) +- Migrate to viem v2 ([8ce04a](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/8ce04a56f6dcdfd1f44d9534f43e3c6eb8b3885d)) +- Remove common + core-types dependencies ([673514](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/6735141fbd21a855aadf69011bc06c69e20f811b)) +- Reincluded simulation flags ([25d2be](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/25d2bee339afd9d8c143fe6dad1898e28034be17)) + +### Bug Fixes + +- Make silently failing paymaster calls throw an error instead ([693bf0](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/693bf08591427c03e317d64d0491e23b1c96ea30)) +- Added string as a supported Transaction value type ([b905dc](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/b905dcf3f7849396573fc8b51f808cc68061ee11)) +- Removed skipBundlerGasEstimation option ([b905dc](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/b905dcf3f7849396573fc8b51f808cc68061ee11)) +- Ingest rpcUrl from SupportedSigners (ethers + viem) ([f56b4d](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/f56b4da08f47af577c01a641b81a3ef9e354cf97)) + +## 3.1.3 (2023-12-28) + +VERSION Bump Only. + +## 3.1.2 (2023-12-28) + +### Features + +- Make entryPointAddress optional in config([cf35c4a](https://github.com/bcnmy/biconomy-client-sdk/pull/336/commits/cf35c4a8266d27648035d8c9d63f1b9157553128)) + +### Bug Fixes + +- use undefined in place of ! + check on limits returned by paymaster and throw ([0376901](https://github.com/bcnmy/biconomy-client-sdk/commit/0376901b7aec8c268a6a3c654d147335974d78f3)) +- change receipt status type from boolean to string to be compatible with bundler response. ([317f986](https://github.com/bcnmy/biconomy-client-sdk/pull/342/commits/317f986b7e8f08d3ccf1e68f12a0696f1116de6b)) + +## 3.1.1 (2023-11-09) + +### Bug Fixes + +- optimistic implementation for getNonce() and cache for isAccountDeployed ([5b1d4bf](https://github.com/bcnmy/biconomy-client-sdk/commit/5b1d4bfd7b5062d05bbb97286b833d879cd972b0)) + +### Reverts + +- update paymaster check in estimateUserOpGas ([2eb0237](https://github.com/bcnmy/biconomy-client-sdk/commit/2eb0237b37425da3558801bbe9d0ce5d6fd696c9)) + +## 3.1.0 (2023-09-20) + +Modular Account Abstraction is here. Contains BiconomySmartAccountV2 - an API for modular smart account. + +### Bug Fixes + +- add 10sec timeout limit for a test ([5d12fe7](https://github.com/bcnmy/biconomy-client-sdk/commit/5d12fe7d4b32e5c4628b971d22f6fc9cfcc6b414)) +- avoid sending populated values of gas prices when estimating from bundler ([c58c9fc](https://github.com/bcnmy/biconomy-client-sdk/commit/c58c9fc29ee83978e1a90305e839002431db2b7b)) +- BiconomySmartAccountV2 API Specs ([69a580e](https://github.com/bcnmy/biconomy-client-sdk/commit/69a580ea9e309141b500274aa95e20e24365b522)) +- build errors ([9fb0475](https://github.com/bcnmy/biconomy-client-sdk/commit/9fb047534935b0600bd08a4de7e68fd91a8a089a)) +- comments [#296](https://github.com/bcnmy/biconomy-client-sdk/issues/296) ([55b7376](https://github.com/bcnmy/biconomy-client-sdk/commit/55b7376336886226967b5bec5f11ba3ab750c5b6)) +- estimation without bundler ([5e49473](https://github.com/bcnmy/biconomy-client-sdk/commit/5e49473e7745c2e87e241731ef8ca1f65ee90388)) +- gitInitCode cache issue ([4df3502](https://github.com/bcnmy/biconomy-client-sdk/commit/4df3502204e3c6c0c6faa90ba2c8aa0d6e826e48)) +- lint warning and errors ([2135498](https://github.com/bcnmy/biconomy-client-sdk/commit/2135498896beb54d25add820c1521ffa22d5db7c)) +- unshift error for batch ([4d090e8](https://github.com/bcnmy/biconomy-client-sdk/commit/4d090e8fbc7e7bcc03805d8dd28c738d5c95dae7)) + +### Features + +- get fee quote or data method in biconomy paymaster ([47748a6](https://github.com/bcnmy/biconomy-client-sdk/commit/47748a6384c2b74e1d9be4d570554098e1ac02e7)) +- update responses to support calculateGasLimits flag + update interfaces ([55bbd38](https://github.com/bcnmy/biconomy-client-sdk/commit/55bbd38b4ef8acaf8da1d52e36846557b134aba4)) +- using hybrid paymaster interface ([5fc56a7](https://github.com/bcnmy/biconomy-client-sdk/commit/5fc56a7db2de4a3f4bb87cd4d75584e79010b206)) + +## 3.0.0 (2023-08-28) + +VERSION Bump Only. + +Modular SDK - consists stable version of below updates done in Alphas. + +## 3.1.1-alpha.0 (2023-08-02) + +### Bug Fixes + +VERSION Bump Only. + +# 3.1.0-alpha.0 (2023-07-24) + +### Bug Fixes + +- avoid sending populated values of gas prices when estimating from bundler ([c58c9fc](https://github.com/bcnmy/biconomy-client-sdk/commit/c58c9fc29ee83978e1a90305e839002431db2b7b)) + +## 3.0.0-alpha.0 (2023-07-12) ### Bug Fixes -- build ([6fb012a](https://github.com/bcnmy/biconomy-client-sdk/commit/6fb012a7d2004d5a5bad616a0ed025f1ee0a93b8)) -- optional sign flag ([0d689d2](https://github.com/bcnmy/biconomy-client-sdk/commit/0d689d214fc7abf32f4f2deabcce61041b73d642)) -- smart account response type ([f457f79](https://github.com/bcnmy/biconomy-client-sdk/commit/f457f794e27999ccc069c4afb7eb7644e224b61e)) -- ui bugs ([f7a4f47](https://github.com/bcnmy/biconomy-client-sdk/commit/f7a4f47c6076fd78515131ec59b128f312687a06)) +- estimation without bundler ([5e49473](https://github.com/bcnmy/biconomy-client-sdk/commit/5e49473e7745c2e87e241731ef8ca1f65ee90388)) +- unshift error for batch ([4d090e8](https://github.com/bcnmy/biconomy-client-sdk/commit/4d090e8fbc7e7bcc03805d8dd28c738d5c95dae7)) ### Features -- added email input and light mode ([741301a](https://github.com/bcnmy/biconomy-client-sdk/commit/741301a526774ed45805e477fac461b1d6afd8ac)) -- increased bg opacity ([aabbb2f](https://github.com/bcnmy/biconomy-client-sdk/commit/aabbb2fc7bab637de7a6c29fead0636979e6f6d0)) -- smart account signer ([9fcb5b1](https://github.com/bcnmy/biconomy-client-sdk/commit/9fcb5b106519b1d8fe658ab0924d722b0d102351)) -- social login ui added ([4772065](https://github.com/bcnmy/biconomy-client-sdk/commit/477206546e0518af5a1d835f7370d70d586420c0)) -- transak wrapper module ([102e6eb](https://github.com/bcnmy/biconomy-client-sdk/commit/102e6eb5f179e4aff77d1e91973e0b32fa7b8f9a)) -- web3auth modal UI ([7b7e510](https://github.com/bcnmy/biconomy-client-sdk/commit/7b7e5104ad5b1828e083f70a185328b566e9d456)) -- whitelist logic added ([53c2140](https://github.com/bcnmy/biconomy-client-sdk/commit/53c2140ef9b9d79d9d9c0e0c2c80e82b1df7f8b9)) +- get fee quote or data method in biconomy paymaster ([47748a6](https://github.com/bcnmy/biconomy-client-sdk/commit/47748a6384c2b74e1d9be4d570554098e1ac02e7)) +- update responses to support calculateGasLimits flag + update interfaces ([55bbd38](https://github.com/bcnmy/biconomy-client-sdk/commit/55bbd38b4ef8acaf8da1d52e36846557b134aba4)) +- using hybrid paymaster interface ([5fc56a7](https://github.com/bcnmy/biconomy-client-sdk/commit/5fc56a7db2de4a3f4bb87cd4d75584e79010b206)) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..6d58094ee --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,46 @@ +# Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +- The use of sexualized language or imagery and unwelcome sexual attention or advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at graeme.barnes@biconomy.io or joe.pegler@biconomy.io. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other project leadership members. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [https://contributor-covenant.org/version/1/4][version] + +[homepage]: https://contributor-covenant.org +[version]: https://contributor-covenant.org/version/1/4/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index a0c7d7050..000000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,64 +0,0 @@ -# Contributing to Biconomy Projects 🚀 - -First off, thank you for considering contributing to Biconomy! We truly appreciate your effort and contributions from the community are what make Biconomy awesome. 🙌 - -Your contributions are valued and will help in driving the decentralized web forward. - -> If you're passionate about our mission but can't contribute directly, there are other ways to support: -> - ⭐ Star our projects on GitHub -> - 🐦 [Tweet about Biconomy](https://twitter.com/biconomy/) -> - 📌 Reference Biconomy in your project's readme -> - 🗣️ Share about Biconomy at meetups or with peers - -## Table of Contents - -- [Contributing to Biconomy Projects 🚀](#contributing-to-biconomy-projects-) - - [Table of Contents](#table-of-contents) - - [Have a Question?](#have-a-question) - - [Ready to Contribute?](#ready-to-contribute) - - [Legal Notice 📜](#legal-notice-) - - [Reporting Bugs 🐛](#reporting-bugs-) - - [Suggesting Enhancements 💡](#suggesting-enhancements-) - - [First Time Contributing? 🌱](#first-time-contributing-) - - [Improving Documentation 📚](#improving-documentation-) - - [Commit Messages 📝](#commit-messages-) - - [Join Biconomy's Team! 🚀](#join-biconomys-team-) - -## Have a Question? - -Before reaching out, please ensure you've gone through our [Documentation](https://docs.biconomy.io/). If you still have questions: - -1. Search for existing [Issues](https://github.com/bcnmy/scw-contracts/issues) that might answer your question. -2. Check out our [Forum](https://forum.biconomy.io/). -3. Join our [Discord](https://discord.com/invite/biconomy) or [Telegram](https://t.me/biconomy) communities. - -If you still need assistance, feel free to open an [Issue](https://github.com/bcnmy/scw-contracts/issues/new) with your question. - -## Ready to Contribute? - -### Legal Notice 📜 -By contributing, you agree that you've authored your contribution and that it can be provided under the project's license. - -### Reporting Bugs 🐛 - -Before submitting a bug report, ensure you're using the latest version and that you've read our [documentation](https://docs.biconomy.io/). If you've identified a bug that hasn't been reported, open a new [Issue](https://github.com/bcnmy/scw-contracts/issues/new) detailing the bug. - -### Suggesting Enhancements 💡 - -Have a feature in mind? First, ensure it aligns with Biconomy's mission and hasn't been suggested before. Then, open an [Issue](https://github.com/bcnmy/scw-contracts/issues/new) to discuss your enhancement. - -### First Time Contributing? 🌱 - -Welcome! We're thrilled to have you. If you're unsure where to start, look for issues labeled `good first issue`. - -### Improving Documentation 📚 - -Good documentation is key! If you spot areas for improvement or errors in our documentation, we'd love your input. If you wish to suggest changes, feel free to raise a PR on our [documentation repository](https://github.com/bcnmy/docs). - -### Commit Messages 📝 - -Ensure your commit messages are clear and descriptive. - -## Join Biconomy's Team! 🚀 - -Interested in joining our mission full-time? Check out our [current job openings](https://jobs.lever.co/biconomy). \ No newline at end of file diff --git a/LICENSE.md b/LICENSE similarity index 97% rename from LICENSE.md rename to LICENSE index cf907e971..84dbcc863 100644 --- a/LICENSE.md +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2023 Biconomy +Copyright (c) 2024 Biconomy Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index b58116402..8d8bd5bca 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,47 @@ -# Biconomy SDK +[![Biconomy](https://img.shields.io/badge/Made_with_%F0%9F%8D%8A_by-Biconomy-ff4e17?style=flat)](https://biconomy.io) [![License MIT](https://img.shields.io/badge/License-MIT-blue?&style=flat)](./LICENSE) [![codecov](https://codecov.io/gh/bcnmy/biconomy-client-sdk/graph/badge.svg?token=DTdIR5aBDA)](https://codecov.io/gh/bcnmy/biconomy-client-sdk) -![Biconomy SDK](https://img.shields.io/badge/Biconomy-SDK-blue.svg) -![TypeScript](https://img.shields.io/badge/-TypeScript-blue) -![Test Coverage](https://img.shields.io/badge/Coverage-79.82%25-green.svg) +# SDK 🚀 -## 👋 Introduction +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/bcnmy/biconomy-client-sdk) The Biconomy SDK is your all-in-one toolkit for building decentralized applications (dApps) with **ERC4337 Account Abstraction** and **Smart Accounts**. It is designed for seamless user experiences and offers non-custodial solutions for user onboarding, sending transactions (userOps), gas sponsorship and much more. +## 📚 Table of Contents + +- [SDK 🚀](#sdk-) + + - [📚 Table of Contents](#-table-of-contents) + - [🛠️ Quickstart](#-quickstart) + + - [Prerequisites](#prerequisites) + - [Installation](#installation) + + - [📄 Documentation and Resources](#-documentation-and-resources) + - [💼 Examples](#-examples) + + - [🛠️ Initialise a smartAccount](#-initialise-a-smartAccount) + - [📨 send some eth with sponsorship](#-send-some-eth-with-sponsorship) + - [🔢 send a multi tx and pay gas with a token](#️-send-a-multi-tx-and-pay-gas-with-a-token) + + - [License](#license) + - [Connect with Biconomy 🍊](#connect-with-biconomy-🍊) + ## 🛠️ Quickstart +### Installation + +1. **Add the package and install dependencies:** + +```bash +bun add @biconomy/account viem +``` + +2. **Install dependencies:** + +```bash +bun i +``` + ```typescript import { createSmartAccountClient } from "@biconomy/account"; @@ -23,39 +55,30 @@ const { wait } = await smartAccount.sendTransaction({ to: "0x...", value: 1 }); const { receipt: { transactionHash }, - userOpHash, + success, } = await wait(); ``` -## 🌟 Features +## Documentation and Resources -- **ERC4337 Account Abstraction**: Simplify user operations and gas payments. -- **Smart Accounts**: Enhance user experience with modular smart accounts. -- **Paymaster Service**: Enable third-party gas sponsorship. -- **Bundler Infrastructure**: Ensure efficient and reliable transaction bundling. +For a comprehensive understanding of our project and to contribute effectively, please refer to the following resources: -For a step-by-step guide on integrating **ERC4337 Account Abstraction** and **Smart Accounts** into your dApp using the Biconomy SDK, refer to the [official documentation](https://docs.biconomy.io). You can also start with Quick start [here](https://docs.biconomy.io/quickstart). +- [**Biconomy Documentation**](https://docs.biconomy.io) +- [**Biconomy Dashboard**](https://dashboard.biconomy.io) +- [**API Documentation**](https://bcnmy.github.io/biconomy-client-sdk) +- [**Contributing Guidelines**](./CONTRIBUTING.md): Learn how to contribute to our project, from code contributions to documentation improvements. +- [**Code of Conduct**](./CODE_OF_CONDUCT.md): Our commitment to fostering an open and welcoming environment. +- [**Security Policy**](./SECURITY.md): Guidelines for reporting security vulnerabilities. +- [**Changelog**](./CHANGELOG.md): Stay updated with the changes and versions -## 📚 Resources +## 💼 Examples -- [Biconomy Documentation](https://docs.biconomy.io/) -- [Biconomy Dashboard](https://dashboard.biconomy.io) -- [TSDoc](https://bcnmy.github.io/biconomy-client-sdk) - -## ⚙️ installation - -```bash -npm i @biconomy/account -``` - -## 💼 Example Usages - -### [Initialise the smartAccount](https://bcnmy.github.io/biconomy-client-sdk/functions/createSmartAccountClient.html) +### [Initialise a smartAccount](https://bcnmy.github.io/biconomy-client-sdk/functions/createSmartAccountClient.html) | Key | Description | | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | | [signer](https://bcnmy.github.io/biconomy-client-sdk/packages/account/docs/interfaces/SmartAccountSigner.html) | This signer will be used for signing userOps for any transactions you build. Will accept ethers.JsonRpcSigner as well as a viemWallet | -| [paymasterUrl](https://dashboard.biconomy.io) | You can pass in a paymasterUrl necessary for sponsoring transactions (retrieved from the biconomy dashboard) | +| [paymasterUrl](https://dashboard.biconomy.io) | You can pass in a paymasterUrl necessary for sponsoring transactions (retrieved from the biconomy dashboard) | | [bundlerUrl](https://dashboard.biconomy.io) | You can pass in a bundlerUrl (retrieved from the biconomy dashboard) for sending transactions | ```typescript @@ -74,7 +97,7 @@ const smartAccount = await createSmartAccountClient({ }); ``` -### [Send some ETH, have gas sponsored](https://bcnmy.github.io/biconomy-client-sdk/classes/BiconomySmartAccountV2.html#sendTransaction) +### [Send some eth with sponsorship](https://bcnmy.github.io/biconomy-client-sdk/classes/BiconomySmartAccountV2.html#sendTransaction) | Key | Description | | --------------------------------------------------------------------------------- | -------------------------------------------------------------- | @@ -85,16 +108,19 @@ const smartAccount = await createSmartAccountClient({ const oneOrManyTx = { to: "0x...", value: 1 }; const { wait } = await smartAccount.sendTransaction(oneOrManyTx, { - mode: PaymasterMode.SPONSORED, + paymasterServiceData: { + mode: PaymasterMode.SPONSORED, + }, }); const { receipt: { transactionHash }, userOpHash, + success, } = await wait(); ``` -### [Mint two NFTs, pay gas with token](https://bcnmy.github.io/biconomy-client-sdk/classes/BiconomySmartAccountV2.html#getTokenFees) +### [Send a multi tx and pay gas with a token](https://bcnmy.github.io/biconomy-client-sdk/classes/BiconomySmartAccountV2.html#getTokenFees) | Key | Description | | -------------------------------------------------------------------------------------------------------- | ------------------------------------------ | @@ -103,36 +129,40 @@ const { ```typescript import { encodeFunctionData, parseAbi } from "viem"; - -const encodedCall = encodeFunctionData({ - abi: parseAbi(["function safeMint(address to) public"]), - functionName: "safeMint", - args: ["0x..."], -}); +const preferredToken = "0x747A4168DB14F57871fa8cda8B5455D8C2a8e90a"; // USDC const tx = { to: nftAddress, - data: encodedCall, + data: encodeFunctionData({ + abi: parseAbi(["function safeMint(address to) public"]), + functionName: "safeMint", + args: ["0x..."], + }), }; -const oneOrManyTx = [tx, tx]; // Mint twice -const paymasterServiceData = { - mode: PaymasterMode.ERC20, - preferredToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC + +const buildUseropDto = { + paymasterServiceData: { + mode: PaymasterMode.ERC20, + preferredToken, + }, }; -const buildUseropDto = { paymasterServiceData }; -const { wait } = await smartAccount.sendTransaction(oneOrManyTx, buildUseropDto); +const { wait } = await smartAccount.sendTransaction( + [tx, tx] /* Mint twice */, + buildUseropDto +); const { receipt: { transactionHash }, userOpHash, + success, } = await wait(); ``` -## 🤝 Contributing +## License -Community contributions are welcome! For guidelines on contributing, please read our [contribution guidelines](./CONTRIBUTING.md). +This project is licensed under the MIT License. See the [LICENSE](./LICENSE) file for details -## 📜 License +## Connect with Biconomy 🍊 -This project is licensed under the MIT License. See the [LICENSE.md](./LICENSE.md) file for details. +[![Website](https://img.shields.io/badge/🍊-Website-ff4e17?style=for-the-badge&logoColor=white)](https://biconomy.io) [![Telegram](https://img.shields.io/badge/Telegram-2CA5E0?style=for-the-badge&logo=telegram&logoColor=white)](https://t.me/biconomy) [![Twitter](https://img.shields.io/badge/Twitter-1DA1F2?style=for-the-badge&logo=twitter&logoColor=white)](https://twitter.com/biconomy) [![LinkedIn](https://img.shields.io/badge/LinkedIn-0077B5?style=for-the-badge&logo=linkedin&logoColor=white)](https://www.linkedin.com/company/biconomy) [![Discord](https://img.shields.io/badge/Discord-7289DA?style=for-the-badge&logo=discord&logoColor=white)](https://discord.gg/biconomy) [![YouTube](https://img.shields.io/badge/YouTube-FF0000?style=for-the-badge&logo=youtube&logoColor=white)](https://www.youtube.com/channel/UC0CtA-Dw9yg-ENgav_VYjRw) [![GitHub](https://img.shields.io/badge/GitHub-181717?style=for-the-badge&logo=github&logoColor=white)](https://github.com/bcnmy/) diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..74aa0598b --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,57 @@ +# Security Policy + +## Reporting a Vulnerability + +The safety and security of our sdk is our top priority. If you have discovered a security vulnerability, we appreciate your help in disclosing it to us responsibly. + +### Contact Us Directly for Critical or High-Risk Findings + +For critical or high-impact vulnerabilities that could affect our users, **please contact us directly** at: + +- Email: security@biconomy.io + +We'll work with you to assess and understand the scope of the issue. + +### For Other Issues + +For vulnerabilities that are less critical and do not immediately affect our users: + +1. Open an issue in our GitHub repository (`https://github.com/bcnmy/biconomy-client-sdk/issues`). + +2. Provide detailed information about the issue and steps to reproduce. + +If your findings are eligible for a bounty, we will follow up with you on the payment process. + +### Scope + +The bounty program covers code in the `main` branch of our repository. The vulnerability must not have already been addressed or fixed in the `develop` branch. + +### Eligibility + +To be eligible for a bounty, researchers must: + +- Report a security bug that has not been previously reported. + +- Not violate our testing policies (detailed below). + +- Follow responsible disclosure guidelines. + +### Testing Policies + +- Do not conduct testing on the mainnet or public testnets. Local forks should be used for testing. + +- Avoid testing that generates significant traffic or could lead to denial of service. + +- Do not disclose the vulnerability publicly until we have had the chance to address it. + +### Out of Scope + +- Known issues listed in the issue tracker or already fixed in the `develop` branch. + +- Issues in third-party components. + +## Legal Notice + +By submitting a vulnerability report, you agree to comply with our responsible disclosure process. Public disclosure of the vulnerability without consent from us will render the vulnerability ineligible for a bounty. + +Thank you for helping to keep Biconomy 🍊 and the blockchain community safe! diff --git a/assets/readme/biconomy-client-sdk.png b/assets/readme/biconomy-client-sdk.png deleted file mode 100644 index ffe67d367..000000000 Binary files a/assets/readme/biconomy-client-sdk.png and /dev/null differ diff --git a/assets/readme/biconomy-sdk.png b/assets/readme/biconomy-sdk.png deleted file mode 100644 index 6c1fe2bcf..000000000 Binary files a/assets/readme/biconomy-sdk.png and /dev/null differ diff --git a/biome.json b/biome.json new file mode 100644 index 000000000..dfd9300dc --- /dev/null +++ b/biome.json @@ -0,0 +1,47 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.5.3/schema.json", + "files": { + "ignore": [ + "node_modules", + "**/node_modules", + "cache", + "coverage", + "tsconfig.json", + "tsconfig.*.json", + "_cjs", + "_esm", + "_types", + "bun.lockb", + "docs", + "dist" + ] + }, + "organizeImports": { + "enabled": true + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + "suspicious": { + "noExplicitAny": "warn" + }, + "style": { + "noUnusedTemplateLiteral": "warn" + } + } + }, + "formatter": { + "enabled": true, + "formatWithErrors": true, + "lineWidth": 80, + "indentWidth": 2, + "indentStyle": "space" + }, + "javascript": { + "formatter": { + "semicolons": "asNeeded", + "trailingComma": "none" + } + } +} diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 000000000..1784ac93e Binary files /dev/null and b/bun.lockb differ diff --git a/jest.config.e2e.ts b/jest.config.e2e.ts deleted file mode 100644 index 2fff1ca6d..000000000 --- a/jest.config.e2e.ts +++ /dev/null @@ -1,6 +0,0 @@ -import config from "./jest.config"; -const e2eConfig = { ...config }; -e2eConfig.testMatch = ["**/*.e2e.spec.ts"]; -e2eConfig.setupFilesAfterEnv = ["<rootDir>/tests/setup-e2e-tests.ts"]; - -export default e2eConfig; diff --git a/jest.config.ts b/jest.config.ts deleted file mode 100644 index 844398aba..000000000 --- a/jest.config.ts +++ /dev/null @@ -1,198 +0,0 @@ -/** - * For a detailed explanation regarding each configuration property, visit: - * https://jestjs.io/docs/configuration - */ - -import type { Config } from "jest"; - -const config: Config = { - // All imported modules in your tests should be mocked automatically - // automock: false, - - // Stop running tests after `n` failures - // bail: 0, - - // The directory where Jest should store its cached dependency information - // cacheDirectory: "/private/var/folders/_y/33lkcttj3w3fd6v6xvg7f33m0000gn/T/jest_dx", - - // Automatically clear mock calls, instances, contexts and results before every test - clearMocks: true, - - // Indicates whether the coverage information should be collected while executing the test - collectCoverage: false, - - // An array of glob patterns indicating a set of files for which coverage information should be collected - collectCoverageFrom: ["packages/**/*.{js,ts}", "!packages/**/node_modules/**", "!packages/**/dist/**"], - - // The directory where Jest should output its coverage files - coverageDirectory: "coverage", - - // An array of regexp pattern strings used to skip coverage collection - // coveragePathIgnorePatterns: [ - // "/node_modules/" - // ], - - // Indicates which provider should be used to instrument code for coverage - coverageProvider: "v8", - - // A list of reporter names that Jest uses when writing coverage reports - // coverageReporters: [ - // "json", - // "text", - // "lcov", - // "clover" - // ], - - // An object that configures minimum threshold enforcement for coverage results - // coverageThreshold: undefined, - - // A path to a custom dependency extractor - // dependencyExtractor: undefined, - - // Make calling deprecated APIs throw helpful error messages - // errorOnDeprecated: false, - - // The default configuration for fake timers - // fakeTimers: { - // "enableGlobally": false - // }, - - // Force coverage collection from ignored files using an array of glob patterns - // forceCoverageMatch: [], - - // A path to a module which exports an async function that is triggered once before all test suites - // globalSetup: undefined, - - // A path to a module which exports an async function that is triggered once after all test suites - // globalTeardown: undefined, - - // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers. - // maxWorkers: "50%", - - // An array of directory names to be searched recursively up from the requiring module's location - // moduleDirectories: [ - // "node_modules" - // ], - - workerThreads: true, - // This is experimental feature. Keep in mind that the worker threads use structured clone instead of JSON.stringify() to serialize messages. - // This means that built-in JavaScript objects as BigInt, Map or Set will get serialized properly. - // However extra properties set on Error, Map or Set will not be passed on through the serialization step. - // For more details see the article on structured clone. - - // An array of file extensions your modules use - moduleFileExtensions: ["js", "mjs", "cjs", "jsx", "ts", "tsx", "json", "node"], - - // A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module - moduleNameMapper: { - '^(?!bn\.js$|hash\.js$)(.+)\\.js$': '$1' - }, - - extensionsToTreatAsEsm: ['.ts'], - - // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader - // modulePathIgnorePatterns: [], - - // Activates notifications for test results - // notify: false, - - // An enum that specifies notification mode. Requires { notify: true } - // notifyMode: "failure-change", - - // A preset that is used as a base for Jest's configuration - preset: "ts-jest", - - // Run tests from one or more projects - // projects: undefined, - - // Use this configuration option to add custom reporters to Jest - // reporters: undefined, - - // Automatically reset mock state before every test - // resetMocks: false, - - // Reset the module registry before running each individual test - // resetModules: false, - - // A path to a custom resolver - // resolver: undefined, - - // Automatically restore mock state and implementation before every test - // restoreMocks: false, - - // The root directory that Jest should scan for tests and modules within - // rootDir: undefined, - - // A list of paths to directories that Jest should use to search for files in - roots: ["<rootDir>/packages/"], - - // Allows you to use a custom runner instead of Jest's default test runner - // runner: "jest-runner", - - // The paths to modules that run some code to configure or set up the testing environment before each test - // setupFiles: [], - - // A list of paths to modules that run some code to configure or set up the testing framework before each test - setupFilesAfterEnv: ["<rootDir>/tests/setup-unit-tests.ts"], - - // The number of seconds after which a test is considered as slow and reported as such in the results. - // slowTestThreshold: 5, - - // A list of paths to snapshot serializer modules Jest should use for snapshot testing - // snapshotSerializers: [], - - // The test environment that will be used for testing - testEnvironment: "node", - - // Options that will be passed to the testEnvironment - // testEnvironmentOptions: {}, - - // Adds a location field to test results - // testLocationInResults: false, - - // The glob patterns Jest uses to detect test files - testMatch: ["**/*.spec.ts", "!**/*.e2e.spec.ts"], - - // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped - // testPathIgnorePatterns: [ - // "/node_modules/" - // ], - - // The regexp pattern or array of patterns that Jest uses to detect test files - // testRegex: [], - - // This option allows the use of a custom results processor - // testResultsProcessor: undefined, - - // This option allows use of a custom test runner - // testRunner: "jest-circus/runner", - - // A map from regular expressions to paths to transformers - transform: { - "^.+\\.tsx?$": ["ts-jest", { useESM: true }], - }, - - // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation - // transformIgnorePatterns: [ - // "/node_modules/", - // "\\.pnp\\.[^\\/]+$" - // ], - - // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them - // unmockedModulePathPatterns: undefined, - - // Indicates whether each individual test should be reported during the run - verbose: true, - - // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode - // watchPathIgnorePatterns: [], - - // Whether to use watchman for file crawling - // watchman: true, - - globals: { - testDataPerChain: [], - } -}; - -export default config; \ No newline at end of file diff --git a/lerna.json b/lerna.json deleted file mode 100644 index be069a470..000000000 --- a/lerna.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "packages": ["packages/*"], - "npmClient": "yarn", - "version": "independent", - "command": { - "publish": { - "conventionalCommits": true - } - }, - "ignoreChanges": ["**/CHANGELOG.md", "**/node_modules/**", "**/*.md", "**/perf/**"] -} diff --git a/link.sh b/link.sh deleted file mode 100755 index beaca34a1..000000000 --- a/link.sh +++ /dev/null @@ -1,5 +0,0 @@ -!/bin/sh -npm run unbuild -npm run build -npm link - diff --git a/linkAll.sh b/linkAll.sh deleted file mode 100755 index 3597ec1c0..000000000 --- a/linkAll.sh +++ /dev/null @@ -1,3 +0,0 @@ -!/bin/sh -for dir in ./packages/*; do (cd "$dir" && yarn link); done -cd ./packages/account && yarn link '@biconomy/bundler' '@biconomy/modules' '@biconomy/paymaster' '@biconomy/common' \ No newline at end of file diff --git a/package.json b/package.json index 72746e0a2..361af2fe7 100644 --- a/package.json +++ b/package.json @@ -1,86 +1,119 @@ { - "name": "biconomy-sdk", - "version": "1.0.0", + "type": "module", + "main": "./dist/_cjs/index.js", + "module": "./dist/_esm/index.js", + "types": "./dist/_types/index.d.ts", + "typings": "./dist/_types/index.d.ts", + "homepage": "https://biconomy.io", + "sideEffects": false, + "name": "@biconomy/account", + "author": "Biconomy", + "version": "4.2.0", "description": "SDK for Biconomy integration with support for account abstraction, smart accounts, ERC-4337.", "keywords": [ - "biconomy", - "sdk", - "blockchain", - "integration", + "erc-7579", + "modular smart account", "account abstraction", - "smart accounts", - "erc-4337", - "crosschain", - "cross-chain", - "metatransactions" + "biconomy", + "sdk" ], "license": "MIT", - "homepage": "https://biconomy.io/docs", - "bugs": { - "url": "https://github.com/bcnmy/biconomy-client-sdk/issues" - }, - "repository": { - "type": "git", - "url": "https://github.com/bcnmy/biconomy-client-sdk" + "repository": "github:bcnmy/biconomy-client-sdk", + "exports": { + ".": { + "types": "./dist/_types/index.d.ts", + "import": "./dist/_esm/index.js", + "default": "./dist/_cjs/index.js" + }, + "./account": { + "types": "./_types/account/index.d.ts", + "import": "./_esm/account/index.js", + "default": "./_cjs/account/index.js" + }, + "./bundler": { + "types": "./_types/bundler/index.d.ts", + "import": "./_esm/bundler/index.js", + "default": "./_cjs/bundler/index.js" + }, + "./paymaster": { + "types": "./_types/paymaster/index.d.ts", + "import": "./_esm/paymaster/index.js", + "default": "./_cjs/paymaster/index.js" + }, + "./modules": { + "types": "./_types/modules/index.d.ts", + "import": "./_esm/modules/index.js", + "default": "./_cjs/modules/index.js" + } }, - "author": "Biconomy (https://biconomy.io)", - "private": true, + "files": [ + "dist/*", + "README.md" + ], "scripts": { - "dev": "yarn rebuild && yarn install && lerna run build && yarn link:all", - "rebuild": "./rebuild.sh", - "link:all": "./linkAll.sh", - "build": "yarn rebuild && yarn install && lerna run build", - "clean": "lerna clean && lerna run unbuild", - "format": "lerna run format --npm-client=yarn", - "prettier": "npx prettier --write .", - "lint": "eslint -c .eslintrc.js 'packages/*/src/**/*.{ts,tsx}'", - "lint:fix": "eslint -c .eslintrc.js 'packages/*/src/**/*.{ts,tsx}' --fix", - "test:run": "yarn jest --runInBand", - "test": "concurrently -k --success first 'yarn start:ganache' 'yarn test:run' && exit 0", - "start:ganache": "ganache -m 'direct buyer cliff train rice spirit census refuse glare expire innocent quote'", - "test:ci": "FORCE_COLOR=1 lerna run test:ci --stream --npm-client=yarn", - "test:coverage": "concurrently -k --success first 'yarn start:ganache' 'yarn jest --runInBand --coverage'", - "test:e2e": "yarn test:run --config=jest.config.e2e.ts", - "diff": "lerna diff", - "release": "lerna version patch --no-git-tag-version --no-push --conventional-commits --yes" + "format": "biome format . --write", + "lint": "biome check .", + "lint:fix": "bun run lint --apply", + "dev": "concurrently \"bun run esm:watch\" \"bun run cjs:watch\" \"bun run esm:watch:aliases\" \"bun run cjs:watch:aliases\"", + "build": "bun run clean && bun run build:cjs && bun run build:esm && bun run build:types", + "clean": "rimraf ./dist/_esm ./dist/_cjs ./dist/_types ./dist/tsconfig", + "test": "vitest dev -c ./tests/vitest.config.ts", + "test:readOnly": "bun run test read", + "test:watch": "bun run test --watch", + "test:watch:readOnly": "bun run test:readOnly --watch", + "test:coverage": "CI=true vitest -c ./tests/vitest.config.ts --coverage", + "test:ci": "CI=true vitest -c ./tests/vitest.config.ts", + "size": "size-limit", + "docs": "typedoc --tsconfig ./tsconfig/tsconfig.esm.json", + "docs:deploy": "bun run docs && gh-pages -d docs", + "changeset": "changeset", + "changeset:release": "bun run build && changeset publish", + "changeset:version": "changeset version && bun install --lockfile-only", + "esm:watch": "tsc --project ./tsconfig/tsconfig.esm.json --watch", + "cjs:watch": "tsc --project ./tsconfig/tsconfig.cjs.json --watch", + "esm:watch:aliases": "tsc-alias -p ./tsconfig/tsconfig.esm.json --watch", + "cjs:watch:aliases": "tsc-alias -p ./tsconfig/tsconfig.cjs.json --watch", + "build:cjs": "tsc --project ./tsconfig/tsconfig.cjs.json && tsc-alias -p ./tsconfig/tsconfig.cjs.json && echo > ./dist/_cjs/package.json '{\"type\":\"commonjs\"}'", + "build:esm": "tsc --project ./tsconfig/tsconfig.esm.json && tsc-alias -p ./tsconfig/tsconfig.esm.json && echo > ./dist/_esm/package.json '{\"type\": \"module\",\"sideEffects\":false}'", + "build:types": "tsc --project ./tsconfig/tsconfig.types.json && tsc-alias -p ./tsconfig/tsconfig.types.json" }, - "changelog": { - "labels": { - "feature": "New Feature", - "bug": "Bug Fix" - } + "devDependencies": { + "@biomejs/biome": "1.6.0", + "@changesets/cli": "^2.27.1", + "@commitlint/cli": "^19.0.3", + "@commitlint/config-conventional": "^19.0.3", + "@ethersproject/abi": "^5.7.0", + "@ethersproject/providers": "^5.7.2", + "@ethersproject/wallet": "^5.7.0", + "@size-limit/esbuild-why": "^11", + "@size-limit/preset-small-lib": "^11", + "@types/bun": "latest", + "@vitest/coverage-v8": "^1.3.1", + "concurrently": "^8.2.2", + "gh-pages": "^6.1.1", + "rimraf": "^5.0.5", + "simple-git-hooks": "^2.9.0", + "size-limit": "^11", + "tsc-alias": "^1.8.8", + "tslib": "^2.6.2", + "typedoc": "^0.25.9", + "vitest": "^1.3.1", + "buffer": "^6.0.3" + }, + "peerDependencies": { + "typescript": "^5", + "viem": "^2" }, - "workspaces": { - "packages": [ - "packages/*" + "commitlint": { + "extends": [ + "@commitlint/config-conventional" ] }, - "dependencies": { - "node-gyp": "^9.4.0", - "typescript": "^5.3.3" + "simple-git-hooks": { + "pre-commit": "bun run format && bun run lint:fix", + "commit-msg": "npx --no -- commitlint --edit ${1}" }, - "devDependencies": { - "@types/debug": "^4.1.9", - "@types/jest": "^29.5.4", - "@typescript-eslint/eslint-plugin": "^6.7.0", - "@typescript-eslint/parser": "^6.6.0", - "concurrently": "^8.2.2", - "eslint": "^8.48.0", - "eslint-config-airbnb-base": "15.0.0", - "eslint-config-airbnb-typescript": "17.1.0", - "eslint-config-prettier": "^9.0.0", - "eslint-plugin-import": "^2.28.1", - "eslint-plugin-prettier": "^5.0.0", - "eslint-plugin-security": "^1.7.1", - "ganache": "^7.9.2", - "hardhat": "^2.17.3", - "jest": "^29.7.0", - "lerna": "^7.2.0", - "lerna-changelog": "^2.2.0", - "nx": "^16.8.1", - "prettier": "^3.0.3", - "rimraf": "^5.0.1", - "ts-jest": "^29.1.1", - "ts-node": "^10.9.1" + "dependencies": { + "merkletreejs": "^0.3.11" } } diff --git a/packages/account/.esbuild.js b/packages/account/.esbuild.js deleted file mode 100644 index ca355e346..000000000 --- a/packages/account/.esbuild.js +++ /dev/null @@ -1,58 +0,0 @@ -const esbuildPluginTsc = require("esbuild-plugin-tsc"); -const esbuild = require("esbuild"); -const { dependencies, peerDependencies = {} } = require("./package.json"); -const { Generator } = require("npm-dts"); - -const COMMON_SETTINGS = { - entryPoints: ["src/index.ts"], - minify: true, - bundle: true, - plugins: [esbuildPluginTsc({ force: true })], -}; - -const ESM_SETTINGS = { - ...COMMON_SETTINGS, - sourcemap: true, - outfile: "dist/esm/index.js", - platform: "browser", - target: "esnext", - format: "esm", - mainFields: ["browser", "module", "main"], -}; -const buildForESM = async () => await esbuild.build(ESM_SETTINGS); - -const CJS_SETTINGS = { - ...COMMON_SETTINGS, - format: "cjs", - sourcemap: false, - outfile: "dist/cjs/index.js", - platform: "node", -}; - -const watchForCJS = async () => { - let ctx = await esbuild.context(CJS_SETTINGS); - await ctx.watch(); - await ctx.serve({ servedir: "dist/src" }); - console.log("watching..."); -}; - -const buildForCJS = async () => await esbuild.build(CJS_SETTINGS); -const buildForTYP = async () => await new Generator({ entry: "src/index.ts", output: "dist/types/index.d.ts" }).generate(); - -(async () => { - const buildType = process.argv.slice(2)[0]; - const shouldWatch = process.argv.slice(3)[0] === "--watch"; - if (!buildType) { - console.log("No build type provided"); - process.exit(1); - } - console.log(`Building for ${buildType}`); - if (buildType === "ESM") { - await buildForESM(); - } else if (buildType === "CJS") { - console.log("watching? " + shouldWatch); - await (shouldWatch ? watchForCJS : buildForCJS)(); - } else if (buildType === "TYP") { - await buildForTYP(); - } -})(); diff --git a/packages/account/CHANGELOG.md b/packages/account/CHANGELOG.md deleted file mode 100644 index 59678fcca..000000000 --- a/packages/account/CHANGELOG.md +++ /dev/null @@ -1,166 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## 4.1.1 (2023-07-03) - -- Added missing extensions ([fdbec6](https://github.com/bcnmy/biconomy-client-sdk/pull/451/commits/fdbec68625f4d7f436dc39d4c1779cdbb7c53e6d)) -- Fixed issue reporting format ([815e9440](https://github.com/bcnmy/biconomy-client-sdk/pull/450/commits/815e9440db03ebae98bb24edfcb3bbcabf9b2a61)) - - -## 4.1.0 (2023-04-03) - -Features: - -- Added Speed optimisation, removing redundant gasEstimate call to bundler ([2371b2](https://github.com/bcnmy/biconomy-client-sdk/pull/447/commits/2371b230cd5806ec4c7c95ba604d6f924b4be768)) -- Added smartAccount.getBalances() method ([4b8bae](https://github.com/bcnmy/biconomy-client-sdk/pull/447/commits/4b8bae412577b846e700b168976cefa6b0803ff6)) -- Added smartAccount.getSupportedTokens() method ([6d2fb27](https://github.com/bcnmy/biconomy-client-sdk/pull/447/commits/6d2fb27d6f9b424e440e45990ea06820a9d16d4b)) -- Added smartAccount.deploy() method ([be9dc4](https://github.com/bcnmy/biconomy-client-sdk/pull/447/commits/be9dc4d74a3e5a22e69416983436997cf2ea417c)) -- Increased checking of the chainId from the bundler, paymaster and the provider ([5d2f3](https://github.com/bcnmy/biconomy-client-sdk/pull/447/commits/5d2f34d8f0fb4f9ff7c7ddc00336471e57efdcfd)) -- Added entity name to Logger calls ([9278ec](https://github.com/bcnmy/biconomy-client-sdk/pull/447/commits/9278ecc21e060ef75ab29a0d054d95d69cd4ae27)) -- Export a 'getChain' by id helper, which returns a viem chain ([ab2ba](https://github.com/bcnmy/biconomy-client-sdk/pull/449/commits/ab2ba2c518ce867c52bf90b9018dfc1b4ec3b4d4)) -- Add "stateOverride" optional param ([20fd54](https://github.com/bcnmy/biconomy-client-sdk/pull/447/commits/20fd54c817d2dcbc6b7d9a247d890d91b19a9c2f)) - -Fixes: - -- Fix for encodeAbiParameters inside batched session module ([b27061](https://github.com/bcnmy/biconomy-client-sdk/pull/447/commits/b27061e2eec7bafb0620e88e6d94e56e9a13cb76)) -- added flag to skip calldata approval patch ([75698](https://github.com/bcnmy/biconomy-client-sdk/pull/447/commits/75698c827015533e32acb1f535bdf6b738876217)) -- Fixed the particle auth build - -Chores: - -- Added tests for ecdsa module ([1a8f29](https://github.com/bcnmy/biconomy-client-sdk/pull/447/commits/1a8f296c26c9fedd57023f8f6423d7662a3adfee)) -- Increased test coverage ([329003](https://github.com/bcnmy/biconomy-client-sdk/pull/447/commits/329003cebb6b4034496e41651985804cdec0d311)) -- Improved issue reporting guidelines ([8b9fb5d](https://github.com/bcnmy/biconomy-client-sdk/pull/447/commits/8b9fb5de9556870611307c12e57df333619d9252)) -- Added e2e tests for optimism, ran from GH actions ([5051ba](https://github.com/bcnmy/biconomy-client-sdk/pull/447/commits/5051ba5ff14220ad616f1ec3bc93a3f42d6f8887)) -- Added ABI SVM test ([49c96](https://github.com/bcnmy/biconomy-client-sdk/pull/447/commits/49c968220e2db0aeee5cc6419f45df2b98f9792c)) -- Added tests for batched session router testing ([2eb9765](https://github.com/bcnmy/biconomy-client-sdk/pull/447/commits/2eb9765d066fcb7b35d08223257aeb9b38c7a78b)) - -## 4.0.3 (2023-28-02) - -VERSION Bump Only. - -## 4.0.2 (2023-26-02) - -### Bug Fixes - -Particle Auth Fix - -## 4.0.1 (2023-02-22) - -### Bug Fixes - -- Fix for RPC endpoints (Quiknode, Blast Sepolia etc) failing to respond because of custom headers being set - -## 4.0.0 (2023-02-06) - -### Features - -- Export bundler / paymaster instances + helpers from master package ([1d1f9d](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/1d1f9dafddf11bde0e1a75383bc935b22448bedd)) -- Export modules aliases from master package ([d6205c](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/d6205c4d76ab846ecdc10843c65e0277f3ceab00)) -- Added sendTransaction abstraction for buildUserOp + sendUserOp ([335c6e](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/335c6e7bfc5ca1ad240e7cbfd678d905c7f16812)) -- Reduced bundle size ([765a3e3](https://github.com/bcnmy/biconomy-client-sdk/commit/765a3e337fb9ad8f1f8dc92b5edcb1ed0940f94d)) -- Added bundler abstraction during SmartAccount init ([591bbb4](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/591bbb4e37774b16cbe801d583d31b3a14608bc1)) -- Added e2e tests that speak with prod bundler / paymasters ([4b4a53a](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/4b4a53aabdf9e22485599872332b3d63e8ddd87a)) -- Added support for simultaneous ethers + viem signers ([8e4b2c8](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/8e4b2c86b871130befbf3b733cf503d24f7226a5)) -- E2E tests for multichain modules ([ecc86e2](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/ecc86e2c7146046a981c3b6fd4bb29e4828b278b)) -- E2E tests for session validation modules ([4ad7ea7](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/4ad7ea7f8eb6a28854dcce83834b2b7ff9ad3287)) -- Added [TSDoc](https://bcnmy.github.io/biconomy-client-sdk) ([638dae](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/638daee0ed6924f67c5151a2d0e5a02d32e4bf23)) -- Make txs more typesafe and default with valueOrData ([b1e5b5e](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/b1e5b5e02ab3a7fb99faa1d45b55e3cbe8d6bc93)) -- Added createSmartAccountClient alias ([232472](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/232472c788bed0619cf6295ade076b6ec3a9e0f8)) -- Improve dx of using paymster to build userOps ([bb54888](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/bb548884e76a94a20329e49b18994503de9e3888)) -- Add ethers v6 signer support ([9727fd](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/9727fd51e47d62904399d17d48f5c9d6b9e591e5)) -- Improved dx of using gas payments with erc20 ([741806](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/741806da68457eba262e1a49be77fcc24360ba36)) - -### Chores - -- Removed SmartAccount Base class in favour of Alchemy's ([be82732](https://github.com/bcnmy/biconomy-client-sdk/commit/be827327fafa858b1551ade0c8389293034cacbb)) -- Migrate to viem v2 ([8ce04a](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/8ce04a56f6dcdfd1f44d9534f43e3c6eb8b3885d)) -- Remove common + core-types dependencies ([673514](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/6735141fbd21a855aadf69011bc06c69e20f811b)) -- Reincluded simulation flags ([25d2be](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/25d2bee339afd9d8c143fe6dad1898e28034be17)) - -### Bug Fixes - -- Make silently failing paymaster calls throw an error instead ([693bf0](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/693bf08591427c03e317d64d0491e23b1c96ea30)) -- Added string as a supported Transaction value type ([b905dc](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/b905dcf3f7849396573fc8b51f808cc68061ee11)) -- Removed skipBundlerGasEstimation option ([b905dc](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/b905dcf3f7849396573fc8b51f808cc68061ee11)) -- Ingest rpcUrl from SupportedSigners (ethers + viem) ([f56b4d](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/f56b4da08f47af577c01a641b81a3ef9e354cf97)) - -## 3.1.3 (2023-12-28) - -VERSION Bump Only. - -## 3.1.2 (2023-12-28) - -### Features - -- Make entryPointAddress optional in config([cf35c4a](https://github.com/bcnmy/biconomy-client-sdk/pull/336/commits/cf35c4a8266d27648035d8c9d63f1b9157553128)) - -### Bug Fixes - -- use undefined in place of ! + check on limits returned by paymaster and throw ([0376901](https://github.com/bcnmy/biconomy-client-sdk/commit/0376901b7aec8c268a6a3c654d147335974d78f3)) -- change receipt status type from boolean to string to be compatible with bundler response. ([317f986](https://github.com/bcnmy/biconomy-client-sdk/pull/342/commits/317f986b7e8f08d3ccf1e68f12a0696f1116de6b)) - -## 3.1.1 (2023-11-09) - -### Bug Fixes - -- optimistic implementation for getNonce() and cache for isAccountDeployed ([5b1d4bf](https://github.com/bcnmy/biconomy-client-sdk/commit/5b1d4bfd7b5062d05bbb97286b833d879cd972b0)) - -### Reverts - -- update paymaster check in estimateUserOpGas ([2eb0237](https://github.com/bcnmy/biconomy-client-sdk/commit/2eb0237b37425da3558801bbe9d0ce5d6fd696c9)) - -## 3.1.0 (2023-09-20) - -Modular Account Abstraction is here. Contains BiconomySmartAccountV2 - an API for modular smart account. - -### Bug Fixes - -- add 10sec timeout limit for a test ([5d12fe7](https://github.com/bcnmy/biconomy-client-sdk/commit/5d12fe7d4b32e5c4628b971d22f6fc9cfcc6b414)) -- avoid sending populated values of gas prices when estimating from bundler ([c58c9fc](https://github.com/bcnmy/biconomy-client-sdk/commit/c58c9fc29ee83978e1a90305e839002431db2b7b)) -- BiconomySmartAccountV2 API Specs ([69a580e](https://github.com/bcnmy/biconomy-client-sdk/commit/69a580ea9e309141b500274aa95e20e24365b522)) -- build errors ([9fb0475](https://github.com/bcnmy/biconomy-client-sdk/commit/9fb047534935b0600bd08a4de7e68fd91a8a089a)) -- comments [#296](https://github.com/bcnmy/biconomy-client-sdk/issues/296) ([55b7376](https://github.com/bcnmy/biconomy-client-sdk/commit/55b7376336886226967b5bec5f11ba3ab750c5b6)) -- estimation without bundler ([5e49473](https://github.com/bcnmy/biconomy-client-sdk/commit/5e49473e7745c2e87e241731ef8ca1f65ee90388)) -- gitInitCode cache issue ([4df3502](https://github.com/bcnmy/biconomy-client-sdk/commit/4df3502204e3c6c0c6faa90ba2c8aa0d6e826e48)) -- lint warning and errors ([2135498](https://github.com/bcnmy/biconomy-client-sdk/commit/2135498896beb54d25add820c1521ffa22d5db7c)) -- unshift error for batch ([4d090e8](https://github.com/bcnmy/biconomy-client-sdk/commit/4d090e8fbc7e7bcc03805d8dd28c738d5c95dae7)) - -### Features - -- get fee quote or data method in biconomy paymaster ([47748a6](https://github.com/bcnmy/biconomy-client-sdk/commit/47748a6384c2b74e1d9be4d570554098e1ac02e7)) -- update responses to support calculateGasLimits flag + update interfaces ([55bbd38](https://github.com/bcnmy/biconomy-client-sdk/commit/55bbd38b4ef8acaf8da1d52e36846557b134aba4)) -- using hybrid paymaster interface ([5fc56a7](https://github.com/bcnmy/biconomy-client-sdk/commit/5fc56a7db2de4a3f4bb87cd4d75584e79010b206)) - -## 3.0.0 (2023-08-28) - -VERSION Bump Only. - -Modular SDK - consists stable version of below updates done in Alphas. - -## 3.1.1-alpha.0 (2023-08-02) - -### Bug Fixes - -VERSION Bump Only. - -# 3.1.0-alpha.0 (2023-07-24) - -### Bug Fixes - -- avoid sending populated values of gas prices when estimating from bundler ([c58c9fc](https://github.com/bcnmy/biconomy-client-sdk/commit/c58c9fc29ee83978e1a90305e839002431db2b7b)) - -## 3.0.0-alpha.0 (2023-07-12) - -### Bug Fixes - -- estimation without bundler ([5e49473](https://github.com/bcnmy/biconomy-client-sdk/commit/5e49473e7745c2e87e241731ef8ca1f65ee90388)) -- unshift error for batch ([4d090e8](https://github.com/bcnmy/biconomy-client-sdk/commit/4d090e8fbc7e7bcc03805d8dd28c738d5c95dae7)) - -### Features - -- get fee quote or data method in biconomy paymaster ([47748a6](https://github.com/bcnmy/biconomy-client-sdk/commit/47748a6384c2b74e1d9be4d570554098e1ac02e7)) -- update responses to support calculateGasLimits flag + update interfaces ([55bbd38](https://github.com/bcnmy/biconomy-client-sdk/commit/55bbd38b4ef8acaf8da1d52e36846557b134aba4)) -- using hybrid paymaster interface ([5fc56a7](https://github.com/bcnmy/biconomy-client-sdk/commit/5fc56a7db2de4a3f4bb87cd4d75584e79010b206)) diff --git a/packages/account/Readme.md b/packages/account/Readme.md deleted file mode 100644 index dedd3e2e6..000000000 --- a/packages/account/Readme.md +++ /dev/null @@ -1,138 +0,0 @@ -# Biconomy SDK - -![Biconomy SDK](https://img.shields.io/badge/Biconomy-SDK-blue.svg) -![TypeScript](https://img.shields.io/badge/-TypeScript-blue) -![Test Coverage](https://img.shields.io/badge/Coverage-79.82%25-green.svg) - -## 👋 Introduction - -The Biconomy SDK is your all-in-one toolkit for building decentralized applications (dApps) with **ERC4337 Account Abstraction** and **Smart Accounts**. It is designed for seamless user experiences and offers non-custodial solutions for user onboarding, sending transactions (userOps), gas sponsorship and much more. - -## ⚙️ installation - -```bash -npm i @biconomy/account -``` - -## 🛠️ Quickstart - -```typescript -import { createSmartAccountClient } from "@biconomy/account"; - -const smartAccount = await createSmartAccountClient({ - signer: viemWalletOrEthersSigner, - bundlerUrl: "", // From dashboard.biconomy.io - paymasterUrl: "", // From dashboard.biconomy.io -}); - -const { wait } = await smartAccount.sendTransaction({ to: "0x...", value: 1 }); - -const { - receipt: { transactionHash }, - userOpHash, -} = await wait(); -``` - -## 🌟 Features - -- **ERC4337 Account Abstraction**: Simplify user operations and gas payments. -- **Smart Accounts**: Enhance user experience with modular smart accounts. -- **Paymaster Service**: Enable third-party gas sponsorship. -- **Bundler Infrastructure**: Ensure efficient and reliable transaction bundling. - -For a step-by-step guide on integrating **ERC4337 Account Abstraction** and **Smart Accounts** into your dApp using the Biconomy SDK, refer to the [official documentation](https://docs.biconomy.io/docs/overview). You can also start with Quick start [here](https://docs.biconomy.io/quickstart). - -## 📚 Resources - -- [Biconomy Documentation](https://docs.biconomy.io/) -- [Biconomy Dashboard](https://dashboard.biconomy.io) -- [TSDoc](https://bcnmy.github.io/biconomy-client-sdk) - -## 💼 Example Usages - -### [Initialise the smartAccount](https://bcnmy.github.io/biconomy-client-sdk/functions/createSmartAccountClient.html) - -| Key | Description | -| -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | -| [signer](https://bcnmy.github.io/biconomy-client-sdk/packages/account/docs/interfaces/SmartAccountSigner.html) | This signer will be used for signing userOps for any transactions you build. Will accept ethers.JsonRpcSigner as well as a viemWallet | -| [paymasterUrl](https://dashboard.biconomy.io) | You can pass in a paymasterUrl necessary for sponsoring transactions (retrieved from the biconomy dashboard) | -| [bundlerUrl](https://dashboard.biconomy.io) | You can pass in a bundlerUrl (retrieved from the biconomy dashboard) for sending transactions | - -```typescript -import { createSmartAccountClient } from "@biconomy/account"; -import { createWalletClient, http, createPublicClient } from "viem"; -import { privateKeyToAccount, generatePrivateKey } from "viem/accounts"; -import { mainnet as chain } from "viem/chains"; - -const account = privateKeyToAccount(generatePrivateKey()); -const signer = createWalletClient({ account, chain, transport: http() }); - -const smartAccount = await createSmartAccountClient({ - signer, - bundlerUrl, - paymasterUrl, -}); -``` - -### [Send some ETH, have gas sponsored](https://bcnmy.github.io/biconomy-client-sdk/classes/BiconomySmartAccountV2.html#sendTransaction) - -| Key | Description | -| --------------------------------------------------------------------------------- | -------------------------------------------------------------- | -| [oneOrManyTx](https://bcnmy.github.io/biconomy-client-sdk/types/Transaction.html) | Submit multiple or one transactions | -| [userOpReceipt](https://bcnmy.github.io/biconomy-client-sdk/types/UserOpReceipt) | Returned information about your tx, receipts, userOpHashes etc | - -```typescript -const oneOrManyTx = { to: "0x...", value: 1 }; - -const { wait } = await smartAccount.sendTransaction(oneOrManyTx, { - mode: PaymasterMode.SPONSORED, -}); - -const { - receipt: { transactionHash }, - userOpHash, -} = await wait(); -``` - -### [Mint two NFTs, pay gas with token](https://bcnmy.github.io/biconomy-client-sdk/classes/BiconomySmartAccountV2.html#getTokenFees) - -| Key | Description | -| -------------------------------------------------------------------------------------------------------- | ------------------------------------------ | -| [buildUseropDto](https://bcnmy.github.io/biconomy-client-sdk/types/BuildUserOpOptions.html) | Options for building a userOp | -| [paymasterServiceData](https://bcnmy.github.io/biconomy-client-sdk/types/PaymasterUserOperationDto.html) | PaymasterOptions set in the buildUseropDto | - -```typescript -import { encodeFunctionData, parseAbi } from "viem"; - -const encodedCall = encodeFunctionData({ - abi: parseAbi(["function safeMint(address to) public"]), - functionName: "safeMint", - args: ["0x..."], -}); - -const tx = { - to: nftAddress, - data: encodedCall, -}; -const oneOrManyTx = [tx, tx]; // Mint twice -const paymasterServiceData = { - mode: PaymasterMode.ERC20, - preferredToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC -}; -const buildUseropDto = { paymasterServiceData }; - -const { wait } = await smartAccount.sendTransaction(oneOrManyTx, buildUseropDto); - -const { - receipt: { transactionHash }, - userOpHash, -} = await wait(); -``` - -## 🤝 Contributing - -Community contributions are welcome! For guidelines on contributing, please read our [contribution guidelines](./CONTRIBUTING.md). - -## 📜 License - -This project is licensed under the MIT License. See the [LICENSE.md](./LICENSE.md) file for details. diff --git a/packages/account/package.json b/packages/account/package.json deleted file mode 100644 index 408ff4cef..000000000 --- a/packages/account/package.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "name": "@biconomy/account", - "version": "4.1.1", - "description": "This package provides apis for ERC-4337 based smart account implementations", - "main": "./dist/cjs/index.js", - "module": "./dist/esm/index.js", - "types": "./dist/types/index.d.ts", - "typings": "./dist/types/index.d.ts", - "exports": { - ".": { - "import": "./dist/esm/index.js", - "types": "./dist/types/index.d.ts", - "default": "./dist/cjs/index.js" - }, - "./package.json": "./package.json" - }, - "keywords": [ - "Ethereum", - "Smart Account", - "ERC-4337", - "Account Abstraction", - "Smart Contract Wallets", - "Biconomy", - "SDK" - ], - "scripts": { - "docs": "typedoc", - "unbuild": "rimraf dist *.tsbuildinfo", - "build:watch": "yarn build:tsc --watch", - "dist:minify": "esbuild ./dist/esm/**/*.js ./dist/esm/*.js --minify --outdir=./dist/esm --bundle=false --allow-overwrite", - "build": "yarn unbuild && yarn build:tsc", - "build:esbuild": "yarn build:esbuild:cjs && yarn build:esbuild:esm && yarn build:typ", - "build:tsc:cjs": "tsc --project tsconfig.build.json --module commonjs --outDir ./dist/cjs --removeComments --verbatimModuleSyntax false && echo > ./dist/cjs/package.json '{\"type\":\"commonjs\"}'", - "build:tsc:esm": "tsc --project tsconfig.build.json --module esnext --outDir ./dist/esm --removeComments && echo > ./dist/esm/package.json '{\"type\":\"module\"}'", - "build:esbuild:cjs": "node .esbuild.js CJS && echo > ./dist/cjs/package.json '{\"type\":\"commonjs\"}'", - "build:esbuild:esm": "node .esbuild.js ESM && echo > ./dist/esm/package.json '{\"type\":\"module\"}'", - "build:typ": "tsc --project tsconfig.build.json --module esnext --declarationDir ./dist/types --emitDeclarationOnly --declaration --declarationMap", - "build:tsc": "yarn build:tsc:cjs && yarn build:tsc:esm && yarn build:typ && yarn dist:minify", - "test:concurrently": "concurrently -k --success first 'yarn start:ganache' 'yarn test'", - "test:cov": "jest --coverage", - "test": "jest tests/**/*.spec.ts --runInBand", - "test:run": "yarn test:concurrently", - "start:ganache": "ganache -m 'direct buyer cliff train rice spirit census refuse glare expire innocent quote'", - "format": "prettier --write \"{src,tests}/**/*.ts\"", - "lint": "tslint -p tsconfig.json", - "docs:deploy": "yarn docs && gh-pages -d docs" - }, - "author": "Biconomy", - "license": "MIT", - "files": [ - "dist/*", - "README.md" - ], - "publishConfig": { - "access": "public" - }, - "devDependencies": { - "@ethersproject/providers": "^5.7.2", - "@ethersproject/wallet": "^5.7.0", - "@types/node": "^20.11.10", - "esbuild": "^0.19.11", - "esbuild-plugin-tsc": "^0.4.0", - "gh-pages": "^6.1.1", - "lru-cache": "^10.0.1", - "nock": "^13.2.9", - "npm-dts": "^1.3.12", - "typedoc": "^0.25.7" - }, - "dependencies": { - "@alchemy/aa-core": "^3.1.1", - "@biconomy/bundler": "^4.1.1", - "@biconomy/common": "^4.1.1", - "@biconomy/modules": "^4.1.1", - "@biconomy/paymaster": "^4.1.1", - "viem": "^2.7.12" - } -} diff --git a/packages/account/src/BiconomySmartAccountV2.ts b/packages/account/src/BiconomySmartAccountV2.ts deleted file mode 100644 index 3aa81a4e2..000000000 --- a/packages/account/src/BiconomySmartAccountV2.ts +++ /dev/null @@ -1,1356 +0,0 @@ -import { - Hex, - keccak256, - encodePacked, - getCreate2Address, - encodeAbiParameters, - parseAbiParameters, - toHex, - toBytes, - encodeFunctionData, - PublicClient, - createPublicClient, - http, - concatHex, - GetContractReturnType, - getContract, - decodeFunctionData, - parseAbi, - formatUnits, -} from "viem"; -import { - BaseSmartContractAccount, - getChain, - type BigNumberish, - type UserOperationStruct, - BatchUserOperationCallData, - SmartAccountSigner, -} from "@alchemy/aa-core"; -import { compareChainIds, isNullOrUndefined, packUserOp, isValidRpcUrl } from "./utils/Utils.js"; -import { BaseValidationModule, ModuleInfo, SendUserOpParams, createECDSAOwnershipValidationModule } from "@biconomy/modules"; -import { - IHybridPaymaster, - IPaymaster, - Paymaster, - PaymasterMode, - SponsorUserOperationDto, - Bundler, - IBundler, - UserOpResponse, - extractChainIdFromBundlerUrl, - convertSigner, - NATIVE_TOKEN_ALIAS, -} from "./index.js"; -import { - BiconomyTokenPaymasterRequest, - BiconomySmartAccountV2Config, - CounterFactualAddressParam, - BuildUserOpOptions, - NonceOptions, - Transaction, - QueryParamsForAddressResolver, - BiconomySmartAccountV2ConfigConstructorProps, - PaymasterUserOperationDto, - SimulationType, - BalancePayload, - SupportedToken, -} from "./utils/Types.js"; -import { - ADDRESS_RESOLVER_ADDRESS, - BICONOMY_IMPLEMENTATION_ADDRESSES_BY_VERSION, - DEFAULT_BICONOMY_FACTORY_ADDRESS, - DEFAULT_FALLBACK_HANDLER_ADDRESS, - PROXY_CREATION_CODE, - ADDRESS_ZERO, - DEFAULT_ENTRYPOINT_ADDRESS, - ERROR_MESSAGES, - ERC20_ABI, -} from "./utils/Constants.js"; -import { BiconomyFactoryAbi } from "./abi/Factory.js"; -import { BiconomyAccountAbi } from "./abi/SmartAccount.js"; -import { AccountResolverAbi } from "./abi/AccountResolver.js"; -import { Logger, StateOverrideSet } from "@biconomy/common"; -import { BiconomyPaymaster, FeeQuotesOrDataDto, FeeQuotesOrDataResponse } from "@biconomy/paymaster"; - -type UserOperationKey = keyof UserOperationStruct; - -export class BiconomySmartAccountV2 extends BaseSmartContractAccount { - private SENTINEL_MODULE = "0x0000000000000000000000000000000000000001"; - - private index: number; - - private chainId: number; - - private provider: PublicClient; - - paymaster?: IPaymaster; - - bundler?: IBundler; - - private accountContract?: GetContractReturnType<typeof BiconomyAccountAbi, PublicClient>; - - private defaultFallbackHandlerAddress: Hex; - - private implementationAddress: Hex; - - private scanForUpgradedAccountsFromV1!: boolean; - - private maxIndexForScan!: number; - - // Validation module responsible for account deployment initCode. This acts as a default authorization module. - defaultValidationModule!: BaseValidationModule; - - // Deployed Smart Account can have more than one module enabled. When sending a transaction activeValidationModule is used to prepare and validate userOp signature. - activeValidationModule!: BaseValidationModule; - - private constructor(readonly biconomySmartAccountConfig: BiconomySmartAccountV2ConfigConstructorProps) { - super({ - ...biconomySmartAccountConfig, - chain: biconomySmartAccountConfig.viemChain ?? getChain(biconomySmartAccountConfig.chainId), - rpcClient: biconomySmartAccountConfig.rpcUrl || getChain(biconomySmartAccountConfig.chainId).rpcUrls.default.http[0], - entryPointAddress: (biconomySmartAccountConfig.entryPointAddress as Hex) ?? DEFAULT_ENTRYPOINT_ADDRESS, - accountAddress: (biconomySmartAccountConfig.accountAddress as Hex) ?? undefined, - factoryAddress: biconomySmartAccountConfig.factoryAddress ?? DEFAULT_BICONOMY_FACTORY_ADDRESS, - }); - - this.defaultValidationModule = biconomySmartAccountConfig.defaultValidationModule; - this.activeValidationModule = biconomySmartAccountConfig.activeValidationModule; - - this.index = biconomySmartAccountConfig.index ?? 0; - this.chainId = biconomySmartAccountConfig.chainId; - this.bundler = biconomySmartAccountConfig.bundler; - this.implementationAddress = biconomySmartAccountConfig.implementationAddress ?? (BICONOMY_IMPLEMENTATION_ADDRESSES_BY_VERSION.V2_0_0 as Hex); - - if (biconomySmartAccountConfig.paymasterUrl) { - this.paymaster = new Paymaster({ - paymasterUrl: biconomySmartAccountConfig.paymasterUrl, - }); - } else if (biconomySmartAccountConfig.biconomyPaymasterApiKey) { - this.paymaster = new Paymaster({ - paymasterUrl: `https://paymaster.biconomy.io/api/v1/${biconomySmartAccountConfig.chainId}/${biconomySmartAccountConfig.biconomyPaymasterApiKey}`, - }); - } else { - this.paymaster = biconomySmartAccountConfig.paymaster; - } - - this.bundler = biconomySmartAccountConfig.bundler; - - const defaultFallbackHandlerAddress = - this.factoryAddress === DEFAULT_BICONOMY_FACTORY_ADDRESS ? DEFAULT_FALLBACK_HANDLER_ADDRESS : biconomySmartAccountConfig.defaultFallbackHandler; - if (!defaultFallbackHandlerAddress) { - throw new Error("Default Fallback Handler address is not provided"); - } - this.defaultFallbackHandlerAddress = defaultFallbackHandlerAddress; - - // Added bang operator to avoid null check as the constructor have these params as optional - this.defaultValidationModule = biconomySmartAccountConfig.defaultValidationModule!; - this.activeValidationModule = biconomySmartAccountConfig.activeValidationModule!; - - this.provider = createPublicClient({ - chain: biconomySmartAccountConfig.viemChain ?? getChain(biconomySmartAccountConfig.chainId), - transport: http(biconomySmartAccountConfig.rpcUrl || getChain(biconomySmartAccountConfig.chainId).rpcUrls.default.http[0]), - }); - - this.scanForUpgradedAccountsFromV1 = biconomySmartAccountConfig.scanForUpgradedAccountsFromV1 ?? false; - this.maxIndexForScan = biconomySmartAccountConfig.maxIndexForScan ?? 10; - } - - /** - * Creates a new instance of BiconomySmartAccountV2 - * - * This method will create a BiconomySmartAccountV2 instance but will not deploy the Smart Account - * Deployment of the Smart Account will be donewith the first user operation. - * - * - Docs: https://docs.biconomy.io/Account/integration#integration-1 - * - * @param biconomySmartAccountConfig - Configuration for initializing the BiconomySmartAccountV2 instance. - * @returns A promise that resolves to a new instance of BiconomySmartAccountV2. - * @throws An error if something is wrong with the smart account instance creation. - * - * @example - * import { createClient } from "viem" - * import { createSmartAccountClient, BiconomySmartAccountV2 } from "@biconomy/account" - * import { createWalletClient, http } from "viem"; - * import { polygonMumbai } from "viem/chains"; - * - * const signer = createWalletClient({ - * account, - * chain: polygonMumbai, - * transport: http(), - * }); - * - * const bundlerUrl = "" // Retrieve bundler url from dasboard - * - * const smartAccountFromStaticCreate = await BiconomySmartAccountV2.create({ signer, bundlerUrl }); - * - * // Is the same as... - * - * const smartAccount = await createSmartAccountClient({ signer, bundlerUrl }); - * - */ - public static async create(biconomySmartAccountConfig: BiconomySmartAccountV2Config): Promise<BiconomySmartAccountV2> { - let chainId = biconomySmartAccountConfig.chainId; - let rpcUrl = biconomySmartAccountConfig.rpcUrl; - let resolvedSmartAccountSigner!: SmartAccountSigner; - - // Signer needs to be initialised here before defaultValidationModule is set - if (biconomySmartAccountConfig.signer) { - const signerResult = await convertSigner(biconomySmartAccountConfig.signer, !!chainId); - if (!chainId && !!signerResult.chainId) { - chainId = signerResult.chainId; - } - if (!rpcUrl && !!signerResult.rpcUrl) { - if (isValidRpcUrl(signerResult.rpcUrl)) { - rpcUrl = signerResult.rpcUrl; - } - } - resolvedSmartAccountSigner = signerResult.signer; - } - if (!chainId) { - // Get it from bundler - if (biconomySmartAccountConfig.bundlerUrl) { - chainId = extractChainIdFromBundlerUrl(biconomySmartAccountConfig.bundlerUrl); - } else if (biconomySmartAccountConfig.bundler) { - const bundlerUrlFromBundler = biconomySmartAccountConfig.bundler.getBundlerUrl(); - chainId = extractChainIdFromBundlerUrl(bundlerUrlFromBundler); - } - } - if (!chainId) { - throw new Error("chainId required"); - } - const bundler: IBundler = biconomySmartAccountConfig.bundler ?? new Bundler({ bundlerUrl: biconomySmartAccountConfig.bundlerUrl!, chainId }); - let defaultValidationModule = biconomySmartAccountConfig.defaultValidationModule; - - // Note: If no module is provided, we will use ECDSA_OWNERSHIP as default - if (!defaultValidationModule) { - const newModule = await createECDSAOwnershipValidationModule({ signer: resolvedSmartAccountSigner! }); - defaultValidationModule = newModule; - } - const activeValidationModule = biconomySmartAccountConfig?.activeValidationModule ?? defaultValidationModule; - if (!resolvedSmartAccountSigner) { - resolvedSmartAccountSigner = await activeValidationModule.getSigner(); - } - if (!resolvedSmartAccountSigner) { - throw new Error("signer required"); - } - const config: BiconomySmartAccountV2ConfigConstructorProps = { - ...biconomySmartAccountConfig, - defaultValidationModule, - activeValidationModule, - chainId, - bundler, - signer: resolvedSmartAccountSigner, - rpcUrl, - }; - - // We check if chain ids match (skip this if chainId is passed by in the config) - // This check is at the end of the function for cases when the signer is not passed in the config but a validation modules is and we get the signer from the validation module in this case - if (!biconomySmartAccountConfig.chainId) { - await compareChainIds(biconomySmartAccountConfig.signer || resolvedSmartAccountSigner, config, false); - } - - return new BiconomySmartAccountV2(config); - } - - // Calls the getCounterFactualAddress - async getAddress(params?: CounterFactualAddressParam): Promise<Hex> { - if (this.accountAddress == null) { - // means it needs deployment - this.accountAddress = await this.getCounterFactualAddress(params); - } - return this.accountAddress; - } - - // Calls the getCounterFactualAddress - async getAccountAddress(params?: CounterFactualAddressParam): Promise<`0x${string}`> { - if (this.accountAddress == null || this.accountAddress == undefined) { - // means it needs deployment - this.accountAddress = await this.getCounterFactualAddress(params); - } - return this.accountAddress; - } - - /** - * Returns token balances (and native token balance) of the smartAccount instance. - * - * This method will fetch the token balances of the smartAccount instance. - * The balance of the native token will always be returned as the last element in the reponse array, with the address set to 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE. - * - * @param addresses - Optional. Array of asset addresses to fetch the balances of. If not provided, the method will return only the balance of the native token. - * @returns Promise<Array<BalancePayload>> - An array of token balances (plus the native token balance) of the smartAccount instance. - * - * @example - * import { createClient } from "viem" - * import { createSmartAccountClient } from "@biconomy/account" - * import { createWalletClient, http } from "viem"; - * import { polygonMumbai } from "viem/chains"; - * - * const signer = createWalletClient({ - * account, - * chain: polygonMumbai, - * transport: http(), - * }); - * - * const usdt = "0xda5289fcaaf71d52a80a254da614a192b693e977"; - * const smartAccount = await createSmartAccountClient({ signer, bundlerUrl }); - * const [usdtBalanceFromSmartAccount, nativeTokenBalanceFromSmartAccount] = await smartAccount.getBalances([usdt]); - * - * console.log(usdtBalanceFromSmartAccount); - * // { - * // amount: 1000000000000000n, - * // decimals: 6, - * // address: "0xda5289fcaaf71d52a80a254da614a192b693e977", - * // formattedAmount: "1000000", - * // chainId: 80001 - * // } - * - * // or to get the nativeToken balance - * - * const [nativeTokenBalanceFromSmartAccount] = await smartAccount.getBalances(); - * - * console.log(nativeTokenBalanceFromSmartAccount); - * // { - * // amount: 1000000000000000n, - * // decimals: 18, - * // address: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", - * // formattedAmount: "1", - * // chainId: 80001 - * // } - * - */ - public async getBalances(addresses?: Array<Hex>): Promise<Array<BalancePayload>> { - const accountAddress = await this.getAccountAddress(); - const result: BalancePayload[] = []; - - if (addresses) { - const tokenContracts = addresses.map((address) => - getContract({ - address, - abi: parseAbi(ERC20_ABI), - client: this.provider, - }), - ); - - const balancePromises = tokenContracts.map((tokenContract) => tokenContract.read.balanceOf([accountAddress])) as Promise<bigint>[]; - const decimalsPromises = tokenContracts.map((tokenContract) => tokenContract.read.decimals()) as Promise<number>[]; - const [balances, decimalsPerToken] = await Promise.all([Promise.all(balancePromises), Promise.all(decimalsPromises)]); - - balances.forEach((amount, index) => - result.push({ - amount, - decimals: decimalsPerToken[index], - address: addresses[index], - formattedAmount: formatUnits(amount, decimalsPerToken[index]), - chainId: this.chainId, - }), - ); - } - - const balance = await this.provider.getBalance({ address: accountAddress }); - - result.push({ - amount: balance, - decimals: 18, - address: NATIVE_TOKEN_ALIAS, - formattedAmount: formatUnits(balance, 18), - chainId: this.chainId, - }); - - return result; - } - - /** - * Return the account's address. This value is valid even before deploying the contract. - */ - async getCounterFactualAddress(params?: CounterFactualAddressParam): Promise<Hex> { - const validationModule = params?.validationModule ?? this.defaultValidationModule; - const index = params?.index ?? this.index; - - const maxIndexForScan = params?.maxIndexForScan ?? this.maxIndexForScan; - // Review: default behavior - const scanForUpgradedAccountsFromV1 = params?.scanForUpgradedAccountsFromV1 ?? this.scanForUpgradedAccountsFromV1; - - // if it's intended to detect V1 upgraded accounts - if (scanForUpgradedAccountsFromV1) { - const eoaSigner = await validationModule.getSigner(); - const eoaAddress = (await eoaSigner.getAddress()) as Hex; - const moduleAddress = validationModule.getAddress() as Hex; - const moduleSetupData = (await validationModule.getInitData()) as Hex; - const queryParams = { - eoaAddress, - index, - moduleAddress, - moduleSetupData, - maxIndexForScan, - }; - const accountAddress = await this.getV1AccountsUpgradedToV2(queryParams); - if (accountAddress !== ADDRESS_ZERO) { - return accountAddress; - } - } - - const counterFactualAddressV2 = await this.getCounterFactualAddressV2({ validationModule, index }); - return counterFactualAddressV2; - } - - private async getCounterFactualAddressV2(params?: CounterFactualAddressParam): Promise<Hex> { - const validationModule = params?.validationModule ?? this.defaultValidationModule; - const index = params?.index ?? this.index; - - try { - const initCalldata = encodeFunctionData({ - abi: BiconomyAccountAbi, - functionName: "init", - args: [this.defaultFallbackHandlerAddress, validationModule.getAddress() as Hex, (await validationModule.getInitData()) as Hex], - }); - - const proxyCreationCodeHash = keccak256(encodePacked(["bytes", "uint256"], [PROXY_CREATION_CODE, BigInt(this.implementationAddress)])); - - const salt = keccak256(encodePacked(["bytes32", "uint256"], [keccak256(initCalldata), BigInt(index)])); - - const counterFactualAddress = getCreate2Address({ - from: this.factoryAddress, - salt: salt, - bytecodeHash: proxyCreationCodeHash, - }); - - return counterFactualAddress; - } catch (e) { - throw new Error(`Failed to get counterfactual address, ${e}`); - } - } - - async _getAccountContract(): Promise<GetContractReturnType<typeof BiconomyAccountAbi, PublicClient>> { - if (this.accountContract == null) { - this.accountContract = getContract({ - address: await this.getAddress(), - abi: BiconomyAccountAbi, - client: this.provider as PublicClient, - }); - } - return this.accountContract; - } - - isActiveValidationModuleDefined(): boolean { - if (!this.activeValidationModule) throw new Error("Must provide an instance of active validation module."); - return true; - } - - isDefaultValidationModuleDefined(): boolean { - if (!this.defaultValidationModule) throw new Error("Must provide an instance of default validation module."); - return true; - } - - setActiveValidationModule(validationModule: BaseValidationModule): BiconomySmartAccountV2 { - if (validationModule instanceof BaseValidationModule) { - this.activeValidationModule = validationModule; - } - return this; - } - - setDefaultValidationModule(validationModule: BaseValidationModule): BiconomySmartAccountV2 { - if (validationModule instanceof BaseValidationModule) { - this.defaultValidationModule = validationModule; - } - return this; - } - - async getV1AccountsUpgradedToV2(params: QueryParamsForAddressResolver): Promise<Hex> { - const maxIndexForScan = params.maxIndexForScan ?? this.maxIndexForScan; - - const addressResolver = getContract({ - address: ADDRESS_RESOLVER_ADDRESS, - abi: AccountResolverAbi, - client: { - public: this.provider as PublicClient, - }, - }); - // Note: depending on moduleAddress and moduleSetupData passed call this. otherwise could call resolveAddresses() - - if (params.moduleAddress && params.moduleSetupData) { - const result = await addressResolver.read.resolveAddressesFlexibleForV2([ - params.eoaAddress, - maxIndexForScan, - params.moduleAddress, - params.moduleSetupData, - ]); - - const desiredV1Account = result.find( - (smartAccountInfo: { factoryVersion: string; currentVersion: string; deploymentIndex: { toString: () => any } }) => - smartAccountInfo.factoryVersion === "v1" && - smartAccountInfo.currentVersion === "2.0.0" && - Number(smartAccountInfo.deploymentIndex.toString()) === params.index, - ); - - if (desiredV1Account) { - const smartAccountAddress = desiredV1Account.accountAddress; - return smartAccountAddress; - } else { - return ADDRESS_ZERO; - } - } else { - return ADDRESS_ZERO; - } - } - - /** - * Return the value to put into the "initCode" field, if the account is not yet deployed. - * This value holds the "factory" address, followed by this account's information - */ - async getAccountInitCode(): Promise<Hex> { - this.isDefaultValidationModuleDefined(); - - return concatHex([ - this.factoryAddress as Hex, - encodeFunctionData({ - abi: BiconomyFactoryAbi, - functionName: "deployCounterFactualAccount", - args: [this.defaultValidationModule.getAddress() as Hex, (await this.defaultValidationModule.getInitData()) as Hex, BigInt(this.index)], - }), - ]); - } - - /** - * - * @param to { target } address of transaction - * @param value represents amount of native tokens - * @param data represent data associated with transaction - * @returns encoded data for execute function - */ - async encodeExecute(to: Hex, value: bigint, data: Hex): Promise<Hex> { - // return accountContract.interface.encodeFunctionData("execute_ncC", [to, value, data]) as Hex; - return encodeFunctionData({ - abi: BiconomyAccountAbi, - functionName: "execute_ncC", - args: [to, value, data], - }); - } - - /** - * - * @param to { target } array of addresses in transaction - * @param value represents array of amount of native tokens associated with each transaction - * @param data represent array of data associated with each transaction - * @returns encoded data for executeBatch function - */ - async encodeExecuteBatch(to: Array<Hex>, value: Array<bigint>, data: Array<Hex>): Promise<Hex> { - return encodeFunctionData({ - abi: BiconomyAccountAbi, - functionName: "executeBatch_y6U", - args: [to, value, data], - }); - } - - override async encodeBatchExecute(txs: BatchUserOperationCallData): Promise<Hex> { - const [targets, datas, value] = txs.reduce( - (accum, curr) => { - accum[0].push(curr.target); - accum[1].push(curr.data); - accum[2].push(curr.value || BigInt(0)); - - return accum; - }, - [[], [], []] as [Hex[], Hex[], bigint[]], - ); - - return this.encodeExecuteBatch(targets, value, datas); - } - - // dummy signature depends on the validation module supplied. - async getDummySignatures(params?: ModuleInfo): Promise<Hex> { - this.isActiveValidationModuleDefined(); - return (await this.activeValidationModule.getDummySignature(params)) as Hex; - } - - // TODO: review this - getDummySignature(): Hex { - throw new Error("Method not implemented! Call getDummySignatures instead."); - } - - // Might use provided paymaster instance to get dummy data (from pm service) - getDummyPaymasterData(): string { - return "0x"; - } - - validateUserOp(userOp: Partial<UserOperationStruct>, requiredFields: UserOperationKey[]): boolean { - for (const field of requiredFields) { - if (!userOp[field]) { - throw new Error(`${String(field)} is missing in the UserOp`); - } - } - return true; - } - - async signUserOp(userOp: Partial<UserOperationStruct>, params?: SendUserOpParams): Promise<UserOperationStruct> { - this.isActiveValidationModuleDefined(); - const requiredFields: UserOperationKey[] = [ - "sender", - "nonce", - "initCode", - "callData", - "callGasLimit", - "verificationGasLimit", - "preVerificationGas", - "maxFeePerGas", - "maxPriorityFeePerGas", - "paymasterAndData", - ]; - this.validateUserOp(userOp, requiredFields); - const userOpHash = await this.getUserOpHash(userOp); - - const moduleSig = (await this.activeValidationModule.signUserOpHash(userOpHash, params)) as Hex; - - const signatureWithModuleAddress = this.getSignatureWithModuleAddress(moduleSig, this.activeValidationModule.getAddress() as Hex); - - userOp.signature = signatureWithModuleAddress; - return userOp as UserOperationStruct; - } - - getSignatureWithModuleAddress(moduleSignature: Hex, moduleAddress?: Hex): Hex { - const moduleAddressToUse = moduleAddress ?? (this.activeValidationModule.getAddress() as Hex); - return encodeAbiParameters(parseAbiParameters("bytes, address"), [moduleSignature, moduleAddressToUse]); - } - - public async getPaymasterUserOp( - userOp: Partial<UserOperationStruct>, - paymasterServiceData: PaymasterUserOperationDto, - ): Promise<Partial<UserOperationStruct>> { - if (paymasterServiceData.mode === PaymasterMode.SPONSORED) { - return this.getPaymasterAndData(userOp, paymasterServiceData); - } else if (paymasterServiceData.mode === PaymasterMode.ERC20) { - if (paymasterServiceData?.feeQuote) { - const { feeQuote, spender, maxApproval = false } = paymasterServiceData; - Logger.log("there is a feeQuote: ", feeQuote); - if (!spender) throw new Error(ERROR_MESSAGES.SPENDER_REQUIRED); - if (!feeQuote) throw new Error(ERROR_MESSAGES.FAILED_FEE_QUOTE_FETCH); - if (paymasterServiceData.skipPatchCallData && paymasterServiceData.skipPatchCallData === true) { - return this.getPaymasterAndData(userOp, { - ...paymasterServiceData, - feeTokenAddress: feeQuote.tokenAddress, - }); - } - const partialUserOp = await this.buildTokenPaymasterUserOp(userOp, { - ...paymasterServiceData, - spender, - maxApproval, - feeQuote, - }); - return this.getPaymasterAndData(partialUserOp, { - ...paymasterServiceData, - feeTokenAddress: feeQuote.tokenAddress, - calculateGasLimits: true, // Always recommended and especially when using token paymaster - }); - } else if (paymasterServiceData?.preferredToken) { - const { preferredToken } = paymasterServiceData; - Logger.log("there is a preferred token: ", preferredToken); - const feeQuotesResponse = await this.getPaymasterFeeQuotesOrData(userOp, paymasterServiceData); - const spender = feeQuotesResponse.tokenPaymasterAddress; - const feeQuote = feeQuotesResponse.feeQuotes?.[0]; - if (!spender) throw new Error(ERROR_MESSAGES.SPENDER_REQUIRED); - if (!feeQuote) throw new Error(ERROR_MESSAGES.FAILED_FEE_QUOTE_FETCH); - return this.getPaymasterUserOp(userOp, { ...paymasterServiceData, feeQuote, spender }); // Recursively call getPaymasterUserOp with the feeQuote - } else { - Logger.log("ERC20 mode without feeQuote or preferredToken provided. Passing through unchanged."); - return userOp; - } - } - throw new Error("Invalid paymaster mode"); - } - - private async getPaymasterAndData( - userOp: Partial<UserOperationStruct>, - paymasterServiceData: PaymasterUserOperationDto, - ): Promise<Partial<UserOperationStruct>> { - const paymaster = this.paymaster as IHybridPaymaster<PaymasterUserOperationDto>; - const paymasterData = await paymaster.getPaymasterAndData(userOp, paymasterServiceData); - return { ...userOp, ...paymasterData }; - } - - private async getPaymasterFeeQuotesOrData( - userOp: Partial<UserOperationStruct>, - feeQuotesOrData: FeeQuotesOrDataDto, - ): Promise<FeeQuotesOrDataResponse> { - const paymaster = this.paymaster as IHybridPaymaster<PaymasterUserOperationDto>; - const tokenList = feeQuotesOrData?.preferredToken - ? [feeQuotesOrData?.preferredToken] - : feeQuotesOrData?.tokenList?.length - ? feeQuotesOrData?.tokenList - : []; - return paymaster.getPaymasterFeeQuotesOrData(userOp, { ...feeQuotesOrData, tokenList }); - } - - /** - * - * @description This function will retrieve fees from the paymaster in erc20 mode - * - * @param manyOrOneTransactions Array of {@link Transaction} to be batched and sent. Can also be a single {@link Transaction}. - * @param buildUseropDto {@link BuildUserOpOptions}. - * @returns Promise<FeeQuotesOrDataResponse> - * - * @example - * import { createClient } from "viem" - * import { createSmartAccountClient } from "@biconomy/account" - * import { createWalletClient, http } from "viem"; - * import { polygonMumbai } from "viem/chains"; - * - * const signer = createWalletClient({ - * account, - * chain: polygonMumbai, - * transport: http(), - * }); - * - * const smartAccount = await createSmartAccountClient({ signer, bundlerUrl }); // Retrieve bundler url from dasboard - * const encodedCall = encodeFunctionData({ - * abi: parseAbi(["function safeMint(address to) public"]), - * functionName: "safeMint", - * args: ["0x..."], - * }); - * - * const transaction = { - * to: nftAddress, - * data: encodedCall - * } - * - * const feeQuotesResponse: FeeQuotesOrDataResponse = await smartAccount.getTokenFees(transaction, { paymasterServiceData: { mode: PaymasterMode.ERC20 } }); - * - * const userSeletedFeeQuote = feeQuotesResponse.feeQuotes?.[0]; - * - * const { wait } = await smartAccount.sendTransaction(transaction, { - * paymasterServiceData: { - * mode: PaymasterMode.ERC20, - * feeQuote: userSeletedFeeQuote, - * spender: feeQuotesResponse.tokenPaymasterAddress, - * }, - * }); - * - * const { success, receipt } = await wait(); - * - */ - public async getTokenFees( - manyOrOneTransactions: Transaction | Transaction[], - buildUseropDto: BuildUserOpOptions, - ): Promise<FeeQuotesOrDataResponse> { - const txs = Array.isArray(manyOrOneTransactions) ? manyOrOneTransactions : [manyOrOneTransactions]; - const userOp = await this.buildUserOp(txs, buildUseropDto); - if (!buildUseropDto.paymasterServiceData) throw new Error("paymasterServiceData was not provided"); - return this.getPaymasterFeeQuotesOrData(userOp, buildUseropDto.paymasterServiceData); - } - - /** - * - * @description This function will return an array of supported tokens from the erc20 paymaster associated with the Smart Account - * @returns Promise<{@link SupportedToken}> - * - * @example - * import { createClient } from "viem" - * import { createSmartAccountClient } from "@biconomy/account" - * import { createWalletClient, http } from "viem"; - * import { polygonMumbai } from "viem/chains"; - * - * const signer = createWalletClient({ - * account, - * chain: polygonMumbai, - * transport: http(), - * }); - * - * const smartAccount = await createSmartAccountClient({ signer, bundlerUrl, biconomyPaymasterApiKey }); // Retrieve bundler url from dasboard - * const tokens = await smartAccount.getSupportedTokens(); - * - * // [ - * // { - * // symbol: "USDC", - * // tokenAddress: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", - * // decimal: 6, - * // logoUrl: "https://assets.coingecko.com/coins/images/279/large/usd-coin.png?1595353707", - * // premiumPercentage: 0.1, - * // } - * // ] - * - */ - public async getSupportedTokens(): Promise<SupportedToken[]> { - const feeQuotesResponse = await this.getTokenFees( - { - data: "0x", - value: BigInt(0), - to: await this.getAccountAddress(), - }, - { - paymasterServiceData: { mode: PaymasterMode.ERC20 }, - }, - ); - return (feeQuotesResponse?.feeQuotes ?? []).map(({ maxGasFee: _, maxGasFeeUSD: __, validUntil: ___, usdPayment: ____, ...rest }) => rest); - } - - /** - * - * @param userOp - * @param params - * @description This function will take a user op as an input, sign it with the owner key, and send it to the bundler. - * @returns Promise<UserOpResponse> - * Sends a user operation - * - * - Docs: https://docs.biconomy.io/Account/transactions/userpaid#send-useroperation - * - * @param userOp Partial<{@link UserOperationStruct}> the userOp params to be sent. - * @param params {@link SendUserOpParams}. - * @returns Promise<{@link UserOpResponse}> that you can use to track the user operation. - * - * @example - * import { createClient } from "viem" - * import { createSmartAccountClient } from "@biconomy/account" - * import { createWalletClient, http } from "viem"; - * import { polygonMumbai } from "viem/chains"; - * - * const signer = createWalletClient({ - * account, - * chain: polygonMumbai, - * transport: http(), - * }); - * - * const smartAccount = await createSmartAccountClient({ signer, bundlerUrl }); // Retrieve bundler url from dasboard - * const encodedCall = encodeFunctionData({ - * abi: parseAbi(["function safeMint(address to) public"]), - * functionName: "safeMint", - * args: ["0x..."], - * }); - * - * const transaction = { - * to: nftAddress, - * data: encodedCall - * } - * - * const userOp = await smartAccount.buildUserOp([transaction]); - * - * const { wait } = await smartAccount.sendUserOp(userOp); - * const { success, receipt } = await wait(); - * - */ - async sendUserOp(userOp: Partial<UserOperationStruct>, params?: SendUserOpParams): Promise<UserOpResponse> { - delete userOp.signature; - const userOperation = await this.signUserOp(userOp, params); - const bundlerResponse = await this.sendSignedUserOp(userOperation, params?.simulationType); - return bundlerResponse; - } - - /** - * - * @param userOp - The signed user operation to send - * @param simulationType - The type of simulation to perform ("validation" | "validation_and_execution") - * @description This function call will take 'signedUserOp' as input and send it to the bundler - * @returns - */ - async sendSignedUserOp(userOp: UserOperationStruct, simulationType?: SimulationType): Promise<UserOpResponse> { - const requiredFields: UserOperationKey[] = [ - "sender", - "nonce", - "initCode", - "callData", - "callGasLimit", - "verificationGasLimit", - "preVerificationGas", - "maxFeePerGas", - "maxPriorityFeePerGas", - "paymasterAndData", - "signature", - ]; - this.validateUserOp(userOp, requiredFields); - if (!this.bundler) throw new Error("Bundler is not provided"); - Logger.warn("userOp being sent to the bundler", userOp); - const bundlerResponse = await this.bundler.sendUserOp(userOp, simulationType); - return bundlerResponse; - } - - async getUserOpHash(userOp: Partial<UserOperationStruct>): Promise<Hex> { - const userOpHash = keccak256(packUserOp(userOp, true) as Hex); - const enc = encodeAbiParameters(parseAbiParameters("bytes32, address, uint256"), [userOpHash, this.entryPoint.address, BigInt(this.chainId)]); - return keccak256(enc); - } - - async estimateUserOpGas(userOp: Partial<UserOperationStruct>, stateOverrideSet?: StateOverrideSet): Promise<Partial<UserOperationStruct>> { - if (!this.bundler) throw new Error("Bundler is not provided"); - const requiredFields: UserOperationKey[] = ["sender", "nonce", "initCode", "callData"]; - this.validateUserOp(userOp, requiredFields); - - const finalUserOp = userOp; - - // Making call to bundler to get gas estimations for userOp - const { callGasLimit, verificationGasLimit, preVerificationGas, maxFeePerGas, maxPriorityFeePerGas } = await this.bundler.estimateUserOpGas( - userOp, - stateOverrideSet, - ); - // if neither user sent gas fee nor the bundler, estimate gas from provider - if (!userOp.maxFeePerGas && !userOp.maxPriorityFeePerGas && (!maxFeePerGas || !maxPriorityFeePerGas)) { - const feeData = await this.provider.estimateFeesPerGas(); - if (feeData.maxFeePerGas?.toString()) { - finalUserOp.maxFeePerGas = ("0x" + feeData.maxFeePerGas.toString(16)) as Hex; - } else if (feeData.gasPrice?.toString()) { - finalUserOp.maxFeePerGas = ("0x" + feeData.gasPrice.toString(16)) as Hex; - } else { - finalUserOp.maxFeePerGas = ("0x" + (await this.provider.getGasPrice()).toString(16)) as Hex; - } - - if (feeData.maxPriorityFeePerGas?.toString()) { - finalUserOp.maxPriorityFeePerGas = ("0x" + feeData.maxPriorityFeePerGas?.toString()) as Hex; - } else if (feeData.gasPrice?.toString()) { - finalUserOp.maxPriorityFeePerGas = toHex(Number(feeData.gasPrice?.toString())); - } else { - finalUserOp.maxPriorityFeePerGas = ("0x" + (await this.provider.getGasPrice()).toString(16)) as Hex; - } - } else { - finalUserOp.maxFeePerGas = toHex(Number(maxFeePerGas)) ?? userOp.maxFeePerGas; - finalUserOp.maxPriorityFeePerGas = toHex(Number(maxPriorityFeePerGas)) ?? userOp.maxPriorityFeePerGas; - } - finalUserOp.verificationGasLimit = toHex(Number(verificationGasLimit)) ?? userOp.verificationGasLimit; - finalUserOp.callGasLimit = toHex(Number(callGasLimit)) ?? userOp.callGasLimit; - finalUserOp.preVerificationGas = toHex(Number(preVerificationGas)) ?? userOp.preVerificationGas; - if (!finalUserOp.paymasterAndData) { - finalUserOp.paymasterAndData = "0x"; - } - - return finalUserOp; - } - - // Could call it nonce space - async getNonce(nonceKey?: number): Promise<bigint> { - const nonceSpace = nonceKey ?? 0; - try { - const address = await this.getAddress(); - return await this.entryPoint.read.getNonce([address, BigInt(nonceSpace)]); - } catch (e) { - return BigInt(0); - } - } - - private async getBuildUserOpNonce(nonceOptions: NonceOptions | undefined): Promise<BigNumberish> { - let nonce = BigInt(0); - try { - if (nonceOptions?.nonceOverride) { - nonce = BigInt(nonceOptions?.nonceOverride); - } else { - const _nonceSpace = nonceOptions?.nonceKey ?? 0; - nonce = await this.getNonce(_nonceSpace); - } - } catch (error) { - // Not throwing this error as nonce would be 0 if this.getNonce() throw exception, which is expected flow for undeployed account - Logger.warn("Error while getting nonce for the account. This is expected for undeployed accounts set nonce to 0"); - } - return nonce; - } - - /** - * Sends a transaction (builds and sends a user op in sequence) - * - * - Docs: https://docs.biconomy.io/Account/transactions/userpaid#send-transaction - * - * @param manyOrOneTransactions Array of {@link Transaction} to be batched and sent. Can also be a single {@link Transaction}. - * @param buildUseropDto {@link BuildUserOpOptions}. - * @returns Promise<{@link UserOpResponse}> that you can use to track the user operation. - * - * @example - * import { createClient } from "viem" - * import { createSmartAccountClient } from "@biconomy/account" - * import { createWalletClient, http } from "viem"; - * import { polygonMumbai } from "viem/chains"; - * - * const signer = createWalletClient({ - * account, - * chain: polygonMumbai, - * transport: http(), - * }); - * - * const smartAccount = await createSmartAccountClient({ signer, bundlerUrl }); // Retrieve bundler url from dasboard - * const encodedCall = encodeFunctionData({ - * abi: parseAbi(["function safeMint(address to) public"]), - * functionName: "safeMint", - * args: ["0x..."], - * }); - * - * const transaction = { - * to: nftAddress, - * data: encodedCall - * } - * - * const { waitForTxHash } = await smartAccount.sendTransaction(transaction); - * const { transactionHash, userOperationReceipt } = await wait(); - * - */ - async sendTransaction(manyOrOneTransactions: Transaction | Transaction[], buildUseropDto?: BuildUserOpOptions): Promise<UserOpResponse> { - const userOp = await this.buildUserOp(Array.isArray(manyOrOneTransactions) ? manyOrOneTransactions : [manyOrOneTransactions], buildUseropDto); - return this.sendUserOp(userOp, { simulationType: buildUseropDto?.simulationType, ...buildUseropDto?.params }); - } - - /** - * Builds a user operation - * - * - Docs: https://docs.biconomy.io/Account/transactions/userpaid#build-useroperation - * - * @param transactions Array of {@link Transaction} to be sent. - * @param buildUseropDto {@link BuildUserOpOptions}. - * @returns Promise<Partial{@link UserOperationStruct}>> the built user operation to be sent. - * - * @example - * import { createClient } from "viem" - * import { createSmartAccountClient } from "@biconomy/account" - * import { createWalletClient, http } from "viem"; - * import { polygonMumbai } from "viem/chains"; - * - * const signer = createWalletClient({ - * account, - * chain: polygonMumbai, - * transport: http(), - * }); - * - * const smartAccount = await createSmartAccountClient({ signer, bundlerUrl }); // Retrieve bundler url from dasboard - * const encodedCall = encodeFunctionData({ - * abi: parseAbi(["function safeMint(address to) public"]), - * functionName: "safeMint", - * args: ["0x..."], - * }); - * - * const transaction = { - * to: nftAddress, - * data: encodedCall - * } - * - * const userOp = await smartAccount.buildUserOp([{ to: "0x...", data: encodedCall }]); - * - */ - async buildUserOp(transactions: Transaction[], buildUseropDto?: BuildUserOpOptions): Promise<Partial<UserOperationStruct>> { - const to = transactions.map((element: Transaction) => element.to as Hex); - const data = transactions.map((element: Transaction) => (element.data as Hex) ?? "0x"); - const value = transactions.map((element: Transaction) => (element.value as bigint) ?? BigInt(0)); - - const initCodeFetchPromise = this.getInitCode(); - const dummySignatureFetchPromise = this.getDummySignatures(buildUseropDto?.params); - - const [nonceFromFetch, initCode, signature] = await Promise.all([ - this.getBuildUserOpNonce(buildUseropDto?.nonceOptions), - initCodeFetchPromise, - dummySignatureFetchPromise, - ]); - - if (transactions.length === 0) { - throw new Error("Transactions array cannot be empty"); - } - let callData: Hex = "0x"; - if (!buildUseropDto?.useEmptyDeployCallData) { - if (transactions.length > 1 || buildUseropDto?.forceEncodeForBatch) { - callData = await this.encodeExecuteBatch(to, value, data); - } else { - // transactions.length must be 1 - callData = await this.encodeExecute(to[0], value[0], data[0]); - } - } - - let userOp: Partial<UserOperationStruct> = { - sender: (await this.getAccountAddress()) as Hex, - nonce: toHex(nonceFromFetch), - initCode, - callData, - }; - - // for this Smart Account current validation module dummy signature will be used to estimate gas - userOp.signature = signature; - - if ( - buildUseropDto?.paymasterServiceData && - buildUseropDto?.paymasterServiceData.mode === PaymasterMode.SPONSORED && - this.paymaster instanceof BiconomyPaymaster - ) { - const gasFeeValues = await this.bundler?.getGasFeeValues(); - - // populate gasfee values and make a call to paymaster - userOp.maxFeePerGas = gasFeeValues?.maxFeePerGas as Hex; - userOp.maxPriorityFeePerGas = gasFeeValues?.maxPriorityFeePerGas as Hex; - - userOp = await this.getPaymasterUserOp(userOp, buildUseropDto.paymasterServiceData); - return userOp; - } else { - userOp = await this.estimateUserOpGas(userOp); - - if (buildUseropDto?.paymasterServiceData) { - userOp = await this.getPaymasterUserOp(userOp, buildUseropDto.paymasterServiceData); - } - return userOp; - } - } - - private validateUserOpAndPaymasterRequest(userOp: Partial<UserOperationStruct>, tokenPaymasterRequest: BiconomyTokenPaymasterRequest): void { - if (isNullOrUndefined(userOp.callData)) { - throw new Error("UserOp callData cannot be undefined"); - } - - const feeTokenAddress = tokenPaymasterRequest?.feeQuote?.tokenAddress; - Logger.warn("Requested fee token is ", feeTokenAddress); - - if (!feeTokenAddress || feeTokenAddress === ADDRESS_ZERO) { - throw new Error("Invalid or missing token address. Token address must be part of the feeQuote in tokenPaymasterRequest"); - } - - const spender = tokenPaymasterRequest?.spender; - Logger.warn("Spender address is ", spender); - - if (!spender || spender === ADDRESS_ZERO) { - throw new Error("Invalid or missing spender address. Sepnder address must be part of tokenPaymasterRequest"); - } - } - - /** - * - * @param userOp partial user operation without signature and paymasterAndData - * @param tokenPaymasterRequest This dto provides information about fee quote. Fee quote is received from earlier request getFeeQuotesOrData() to the Biconomy paymaster. - * maxFee and token decimals from the quote, along with the spender is required to append approval transaction. - * @notice This method should be called when gas is paid in ERC20 token using TokenPaymaster - * @description Optional method to update the userOp.calldata with batched transaction which approves the paymaster spender with necessary amount(if required) - * @returns updated userOp with new callData, callGasLimit - */ - async buildTokenPaymasterUserOp( - userOp: Partial<UserOperationStruct>, - tokenPaymasterRequest: BiconomyTokenPaymasterRequest, - ): Promise<Partial<UserOperationStruct>> { - this.validateUserOpAndPaymasterRequest(userOp, tokenPaymasterRequest); - try { - let batchTo: Array<Hex> = []; - let batchValue: Array<bigint> = []; - let batchData: Array<Hex> = []; - - let newCallData = userOp.callData; - Logger.warn("Received information about fee token address and quote ", tokenPaymasterRequest); - - if (this.paymaster && this.paymaster instanceof Paymaster) { - // Make a call to paymaster.buildTokenApprovalTransaction() with necessary details - - // Review: might request this form of an array of Transaction - const approvalRequest: Transaction = await (this.paymaster as IHybridPaymaster<SponsorUserOperationDto>).buildTokenApprovalTransaction( - tokenPaymasterRequest, - ); - Logger.warn("ApprovalRequest is for erc20 token ", approvalRequest.to); - - if (approvalRequest.data === "0x" || approvalRequest.to === ADDRESS_ZERO) { - return userOp; - } - - if (isNullOrUndefined(userOp.callData)) { - throw new Error("UserOp callData cannot be undefined"); - } - - const decodedSmartAccountData = decodeFunctionData({ - abi: BiconomyAccountAbi, - data: userOp.callData as Hex, - }); - - if (!decodedSmartAccountData) { - throw new Error("Could not parse userOp call data for this smart account"); - } - - const smartAccountExecFunctionName = decodedSmartAccountData.functionName; - - Logger.warn(`Originally an ${smartAccountExecFunctionName} method call for Biconomy Account V2`); - if (smartAccountExecFunctionName === "execute" || smartAccountExecFunctionName === "execute_ncC") { - const methodArgsSmartWalletExecuteCall = decodedSmartAccountData.args; - const toOriginal = methodArgsSmartWalletExecuteCall[0]; - const valueOriginal = methodArgsSmartWalletExecuteCall[1]; - const dataOriginal = methodArgsSmartWalletExecuteCall[2]; - - batchTo.push(toOriginal); - batchValue.push(valueOriginal); - batchData.push(dataOriginal); - } else if (smartAccountExecFunctionName === "executeBatch" || smartAccountExecFunctionName === "executeBatch_y6U") { - const methodArgsSmartWalletExecuteCall = decodedSmartAccountData.args; - batchTo = [...methodArgsSmartWalletExecuteCall[0]]; - batchValue = [...methodArgsSmartWalletExecuteCall[1]]; - batchData = [...methodArgsSmartWalletExecuteCall[2]]; - } - - if (approvalRequest.to && approvalRequest.data && approvalRequest.value) { - batchTo = [approvalRequest.to as Hex, ...batchTo]; - batchValue = [BigInt(Number(approvalRequest.value.toString())), ...batchValue]; - batchData = [approvalRequest.data as Hex, ...batchData]; - - newCallData = await this.encodeExecuteBatch(batchTo, batchValue, batchData); - } - const finalUserOp: Partial<UserOperationStruct> = { - ...userOp, - callData: newCallData, - }; - - // Optionally Requesting to update gas limits again (especially callGasLimit needs to be re-calculated) - - return finalUserOp; - } - } catch (error) { - Logger.log("Failed to update userOp. Sending back original op"); - Logger.error("Failed to update callData with error", error); - return userOp; - } - return userOp; - } - - async signUserOpHash(userOpHash: string, params?: ModuleInfo): Promise<Hex> { - this.isActiveValidationModuleDefined(); - const moduleSig = (await this.activeValidationModule.signUserOpHash(userOpHash, params)) as Hex; - - const signatureWithModuleAddress = encodeAbiParameters(parseAbiParameters("bytes, address"), [ - moduleSig, - this.activeValidationModule.getAddress() as Hex, - ]); - - return signatureWithModuleAddress; - } - - /** - * Deploys the smart contract - * - * This method will deploy a Smart Account contract. It is useful for deploying in a moment when you know that gas prices are low, - * and you want to deploy the account before sending the first user operation. This step can otherwise be skipped, - * as the deployment will alternatively be bundled with the first user operation. - * - * @param buildUseropDto {@link BuildUserOpOptions}. - * @returns Promise<{@link UserOpResponse}> that you can use to track the user operation. - * @error Throws an error if the account has already been deployed. - * @error Throws an error if the account has not enough native token balance to deploy, if not using a paymaster. - * - * @example - * import { createClient } from "viem" - * import { createSmartAccountClient } from "@biconomy/account" - * import { createWalletClient, http } from "viem"; - * import { polygonMumbai } from "viem/chains"; - * - * const signer = createWalletClient({ - * account, - * chain: polygonMumbai, - * transport: http(), - * }); - * - * const smartAccount = await createSmartAccountClient({ - * signer, - * biconomyPaymasterApiKey, - * bundlerUrl - * }); - * - * // If you want to use a paymaster... - * const { wait } = await smartAccount.deploy({ - * paymasterServiceData: { mode: PaymasterMode.SPONSORED }, - * }); - * - * // Or if you can't use a paymaster send native token to this address: - * const counterfactualAddress = await smartAccount.getAccountAddress(); - * - * // Then deploy the account - * const { wait } = await smartAccount.deploy(); - * - * const { success, receipt } = await wait(); - * - */ - public async deploy(buildUseropDto?: BuildUserOpOptions): Promise<UserOpResponse> { - const accountAddress = this.accountAddress ?? (await this.getAccountAddress()); - - // Check that the account has not already been deployed - const byteCode = await this.provider?.getBytecode({ address: accountAddress as Hex }); - if (byteCode !== undefined) { - throw new Error(ERROR_MESSAGES.ACCOUNT_ALREADY_DEPLOYED); - } - - // Check that the account has enough native token balance to deploy, if not using a paymaster - if (!buildUseropDto?.paymasterServiceData?.mode) { - const nativeTokenBalance = await this.provider?.getBalance({ address: accountAddress }); - if (nativeTokenBalance === BigInt(0)) { - throw new Error(ERROR_MESSAGES.NO_NATIVE_TOKEN_BALANCE_DURING_DEPLOY); - } - } - - const useEmptyDeployCallData = true; - - return this.sendTransaction( - { - to: accountAddress, - data: "0x", - }, - { ...buildUseropDto, useEmptyDeployCallData }, - ); - } - - async signMessage(message: string | Uint8Array): Promise<Hex> { - this.isActiveValidationModuleDefined(); - const dataHash = typeof message === "string" ? toBytes(message) : message; - let signature = await this.activeValidationModule.signMessage(dataHash); - - const potentiallyIncorrectV = parseInt(signature.slice(-2), 16); - if (![27, 28].includes(potentiallyIncorrectV)) { - const correctV = potentiallyIncorrectV + 27; - signature = signature.slice(0, -2) + correctV.toString(16); - } - if (signature.slice(0, 2) !== "0x") { - signature = "0x" + signature; - } - return signature as Hex; - } - - async enableModule(moduleAddress: Hex): Promise<UserOpResponse> { - const tx: Transaction = await this.getEnableModuleData(moduleAddress); - const partialUserOp = await this.buildUserOp([tx]); - return this.sendUserOp(partialUserOp); - } - - async getEnableModuleData(moduleAddress: Hex): Promise<Transaction> { - const callData = encodeFunctionData({ - abi: BiconomyAccountAbi, - functionName: "enableModule", - args: [moduleAddress], - }); - const tx: Transaction = { - to: await this.getAddress(), - value: "0x00", - data: callData, - }; - return tx; - } - - async getSetupAndEnableModuleData(moduleAddress: Hex, moduleSetupData: Hex): Promise<Transaction> { - const callData = encodeFunctionData({ - abi: BiconomyAccountAbi, - functionName: "setupAndEnableModule", - args: [moduleAddress, moduleSetupData], - }); - const tx: Transaction = { - to: await this.getAddress(), - value: "0x00", - data: callData, - }; - return tx; - } - - async disableModule(prevModule: Hex, moduleAddress: Hex): Promise<UserOpResponse> { - const tx: Transaction = await this.getDisableModuleData(prevModule, moduleAddress); - const partialUserOp = await this.buildUserOp([tx]); - return this.sendUserOp(partialUserOp); - } - - async getDisableModuleData(prevModule: Hex, moduleAddress: Hex): Promise<Transaction> { - const callData = encodeFunctionData({ - abi: BiconomyAccountAbi, - functionName: "disableModule", - args: [prevModule, moduleAddress], - }); - const tx: Transaction = { - to: await this.getAddress(), - value: "0x00", - data: callData, - }; - return tx; - } - - async isModuleEnabled(moduleAddress: Hex): Promise<boolean> { - const accountContract = await this._getAccountContract(); - return accountContract.read.isModuleEnabled([moduleAddress]); - } - - // Review - async getAllModules(pageSize?: number): Promise<Array<string>> { - pageSize = pageSize ?? 100; - const accountContract = await this._getAccountContract(); - const result = await accountContract.read.getModulesPaginated([this.SENTINEL_MODULE as Hex, BigInt(pageSize)]); - const modules: Array<string> = result[0] as Array<string>; - return modules; - } -} diff --git a/packages/account/src/abi/SmartAccount.ts b/packages/account/src/abi/SmartAccount.ts deleted file mode 100644 index 3542c17d1..000000000 --- a/packages/account/src/abi/SmartAccount.ts +++ /dev/null @@ -1,944 +0,0 @@ -export const BiconomyAccountAbi = [ - { - inputs: [], - name: "AlreadyInitialized", - type: "error", - }, - { - inputs: [], - name: "BaseImplementationCannotBeZero", - type: "error", - }, - { - inputs: [ - { - internalType: "address", - name: "caller", - type: "address", - }, - ], - name: "CallerIsNotAnEntryPoint", - type: "error", - }, - { - inputs: [ - { - internalType: "address", - name: "caller", - type: "address", - }, - ], - name: "CallerIsNotEntryPoint", - type: "error", - }, - { - inputs: [ - { - internalType: "address", - name: "caller", - type: "address", - }, - ], - name: "CallerIsNotEntryPointOrOwner", - type: "error", - }, - { - inputs: [ - { - internalType: "address", - name: "caller", - type: "address", - }, - ], - name: "CallerIsNotEntryPointOrSelf", - type: "error", - }, - { - inputs: [ - { - internalType: "address", - name: "caller", - type: "address", - }, - ], - name: "CallerIsNotOwner", - type: "error", - }, - { - inputs: [], - name: "DelegateCallsOnly", - type: "error", - }, - { - inputs: [], - name: "EntryPointCannotBeZero", - type: "error", - }, - { - inputs: [ - { - internalType: "address", - name: "implementationAddress", - type: "address", - }, - ], - name: "InvalidImplementation", - type: "error", - }, - { - inputs: [ - { - internalType: "address", - name: "caller", - type: "address", - }, - ], - name: "MixedAuthFail", - type: "error", - }, - { - inputs: [ - { - internalType: "address", - name: "module", - type: "address", - }, - ], - name: "ModuleAlreadyEnabled", - type: "error", - }, - { - inputs: [ - { - internalType: "address", - name: "expectedModule", - type: "address", - }, - { - internalType: "address", - name: "returnedModule", - type: "address", - }, - { - internalType: "address", - name: "prevModule", - type: "address", - }, - ], - name: "ModuleAndPrevModuleMismatch", - type: "error", - }, - { - inputs: [ - { - internalType: "address", - name: "module", - type: "address", - }, - ], - name: "ModuleCannotBeZeroOrSentinel", - type: "error", - }, - { - inputs: [ - { - internalType: "address", - name: "module", - type: "address", - }, - ], - name: "ModuleNotEnabled", - type: "error", - }, - { - inputs: [], - name: "ModulesAlreadyInitialized", - type: "error", - }, - { - inputs: [], - name: "ModulesSetupExecutionFailed", - type: "error", - }, - { - inputs: [], - name: "OwnerCanNotBeSelf", - type: "error", - }, - { - inputs: [], - name: "OwnerCannotBeZero", - type: "error", - }, - { - inputs: [], - name: "OwnerProvidedIsSame", - type: "error", - }, - { - inputs: [], - name: "TransferToZeroAddressAttempt", - type: "error", - }, - { - inputs: [ - { - internalType: "uint256", - name: "destLength", - type: "uint256", - }, - { - internalType: "uint256", - name: "valueLength", - type: "uint256", - }, - { - internalType: "uint256", - name: "funcLength", - type: "uint256", - }, - { - internalType: "uint256", - name: "operationLength", - type: "uint256", - }, - ], - name: "WrongBatchProvided", - type: "error", - }, - { - inputs: [ - { - internalType: "bytes", - name: "contractSignature", - type: "bytes", - }, - ], - name: "WrongContractSignature", - type: "error", - }, - { - inputs: [ - { - internalType: "uint256", - name: "uintS", - type: "uint256", - }, - { - internalType: "uint256", - name: "contractSignatureLength", - type: "uint256", - }, - { - internalType: "uint256", - name: "signatureLength", - type: "uint256", - }, - ], - name: "WrongContractSignatureFormat", - type: "error", - }, - { - inputs: [ - { - internalType: "address", - name: "moduleAddressProvided", - type: "address", - }, - ], - name: "WrongValidationModule", - type: "error", - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "address", - name: "module", - type: "address", - }, - ], - name: "DisabledModule", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "address", - name: "module", - type: "address", - }, - ], - name: "EnabledModule", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "module", - type: "address", - }, - ], - name: "ExecutionFromModuleFailure", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "module", - type: "address", - }, - ], - name: "ExecutionFromModuleSuccess", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "oldImplementation", - type: "address", - }, - { - indexed: true, - internalType: "address", - name: "newImplementation", - type: "address", - }, - ], - name: "ImplementationUpdated", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "address", - name: "module", - type: "address", - }, - { - indexed: false, - internalType: "address", - name: "to", - type: "address", - }, - { - indexed: false, - internalType: "uint256", - name: "value", - type: "uint256", - }, - { - indexed: false, - internalType: "bytes", - name: "data", - type: "bytes", - }, - { - indexed: false, - internalType: "enum Enum.Operation", - name: "operation", - type: "uint8", - }, - ], - name: "ModuleTransaction", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "sender", - type: "address", - }, - { - indexed: true, - internalType: "uint256", - name: "value", - type: "uint256", - }, - ], - name: "SmartAccountReceivedNativeToken", - type: "event", - }, - { - inputs: [], - name: "VERSION", - outputs: [ - { - internalType: "string", - name: "", - type: "string", - }, - ], - stateMutability: "pure", - type: "function", - }, - { - inputs: [], - name: "addDeposit", - outputs: [], - stateMutability: "payable", - type: "function", - }, - { - inputs: [ - { - internalType: "address", - name: "prevModule", - type: "address", - }, - { - internalType: "address", - name: "module", - type: "address", - }, - ], - name: "disableModule", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "address", - name: "module", - type: "address", - }, - ], - name: "enableModule", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [], - name: "entryPoint", - outputs: [ - { - internalType: "contract IEntryPoint", - name: "", - type: "address", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "address[]", - name: "to", - type: "address[]", - }, - { - internalType: "uint256[]", - name: "value", - type: "uint256[]", - }, - { - internalType: "bytes[]", - name: "data", - type: "bytes[]", - }, - { - internalType: "enum Enum.Operation[]", - name: "operations", - type: "uint8[]", - }, - ], - name: "execBatchTransactionFromModule", - outputs: [ - { - internalType: "bool", - name: "success", - type: "bool", - }, - ], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "address", - name: "to", - type: "address", - }, - { - internalType: "uint256", - name: "value", - type: "uint256", - }, - { - internalType: "bytes", - name: "data", - type: "bytes", - }, - { - internalType: "enum Enum.Operation", - name: "operation", - type: "uint8", - }, - { - internalType: "uint256", - name: "txGas", - type: "uint256", - }, - ], - name: "execTransactionFromModule", - outputs: [ - { - internalType: "bool", - name: "success", - type: "bool", - }, - ], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "address", - name: "to", - type: "address", - }, - { - internalType: "uint256", - name: "value", - type: "uint256", - }, - { - internalType: "bytes", - name: "data", - type: "bytes", - }, - { - internalType: "enum Enum.Operation", - name: "operation", - type: "uint8", - }, - ], - name: "execTransactionFromModule", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool", - }, - ], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "address", - name: "to", - type: "address", - }, - { - internalType: "uint256", - name: "value", - type: "uint256", - }, - { - internalType: "bytes", - name: "data", - type: "bytes", - }, - { - internalType: "enum Enum.Operation", - name: "operation", - type: "uint8", - }, - ], - name: "execTransactionFromModuleReturnData", - outputs: [ - { - internalType: "bool", - name: "success", - type: "bool", - }, - { - internalType: "bytes", - name: "returnData", - type: "bytes", - }, - ], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "address", - name: "dest", - type: "address", - }, - { - internalType: "uint256", - name: "value", - type: "uint256", - }, - { - internalType: "bytes", - name: "func", - type: "bytes", - }, - ], - name: "execute", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "address[]", - name: "dest", - type: "address[]", - }, - { - internalType: "uint256[]", - name: "value", - type: "uint256[]", - }, - { - internalType: "bytes[]", - name: "func", - type: "bytes[]", - }, - ], - name: "executeBatch", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "address[]", - name: "dest", - type: "address[]", - }, - { - internalType: "uint256[]", - name: "value", - type: "uint256[]", - }, - { - internalType: "bytes[]", - name: "func", - type: "bytes[]", - }, - ], - name: "executeBatch_y6U", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "address", - name: "dest", - type: "address", - }, - { - internalType: "uint256", - name: "value", - type: "uint256", - }, - { - internalType: "bytes", - name: "func", - type: "bytes", - }, - ], - name: "execute_ncC", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [], - name: "getDeposit", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [], - name: "getImplementation", - outputs: [ - { - internalType: "address", - name: "_implementation", - type: "address", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "address", - name: "start", - type: "address", - }, - { - internalType: "uint256", - name: "pageSize", - type: "uint256", - }, - ], - name: "getModulesPaginated", - outputs: [ - { - internalType: "address[]", - name: "array", - type: "address[]", - }, - { - internalType: "address", - name: "next", - type: "address", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "address", - name: "handler", - type: "address", - }, - { - internalType: "address", - name: "moduleSetupContract", - type: "address", - }, - { - internalType: "bytes", - name: "moduleSetupData", - type: "bytes", - }, - ], - name: "init", - outputs: [ - { - internalType: "address", - name: "", - type: "address", - }, - ], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "address", - name: "module", - type: "address", - }, - ], - name: "isModuleEnabled", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "uint192", - name: "_key", - type: "uint192", - }, - ], - name: "nonce", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "address", - name: "setupContract", - type: "address", - }, - { - internalType: "bytes", - name: "setupData", - type: "bytes", - }, - ], - name: "setupAndEnableModule", - outputs: [ - { - internalType: "address", - name: "", - type: "address", - }, - ], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "address", - name: "_implementation", - type: "address", - }, - ], - name: "updateImplementation", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - components: [ - { - internalType: "address", - name: "sender", - type: "address", - }, - { - internalType: "uint256", - name: "nonce", - type: "uint256", - }, - { - internalType: "bytes", - name: "initCode", - type: "bytes", - }, - { - internalType: "bytes", - name: "callData", - type: "bytes", - }, - { - internalType: "uint256", - name: "callGasLimit", - type: "uint256", - }, - { - internalType: "uint256", - name: "verificationGasLimit", - type: "uint256", - }, - { - internalType: "uint256", - name: "preVerificationGas", - type: "uint256", - }, - { - internalType: "uint256", - name: "maxFeePerGas", - type: "uint256", - }, - { - internalType: "uint256", - name: "maxPriorityFeePerGas", - type: "uint256", - }, - { - internalType: "bytes", - name: "paymasterAndData", - type: "bytes", - }, - { - internalType: "bytes", - name: "signature", - type: "bytes", - }, - ], - internalType: "struct UserOperation", - name: "userOp", - type: "tuple", - }, - { - internalType: "bytes32", - name: "userOpHash", - type: "bytes32", - }, - { - internalType: "uint256", - name: "missingAccountFunds", - type: "uint256", - }, - ], - name: "validateUserOp", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "address payable", - name: "withdrawAddress", - type: "address", - }, - { - internalType: "uint256", - name: "amount", - type: "uint256", - }, - ], - name: "withdrawDepositTo", - outputs: [], - stateMutability: "payable", - type: "function", - }, -] as const; diff --git a/packages/account/src/index.ts b/packages/account/src/index.ts deleted file mode 100644 index f46953a67..000000000 --- a/packages/account/src/index.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { BiconomySmartAccountV2 } from "./BiconomySmartAccountV2.js"; -import { type BiconomySmartAccountV2Config } from "./utils/Types.js"; - -export * from "./utils/Types.js"; -export * from "./utils/Constants.js"; -export * from "./utils/Utils.js"; -export * from "./BiconomySmartAccountV2.js"; - -export { WalletClientSigner, LocalAccountSigner, type SmartAccountSigner } from "@alchemy/aa-core"; -export { - BiconomyPaymaster as Paymaster, - type IPaymaster, - PaymasterMode, - type IHybridPaymaster, - type PaymasterFeeQuote, - type SponsorUserOperationDto, - type FeeQuotesOrDataResponse, - createPaymaster, -} from "@biconomy/paymaster"; -export { EthersSigner, convertSigner, type LightSigner, type SupportedSigner } from "@biconomy/common"; -export { - Bundler, - type IBundler, - extractChainIdFromBundlerUrl, - type UserOpResponse, - type UserOpStatus, - type UserOpReceipt, - createBundler, -} from "@biconomy/bundler"; -export { - createECDSAOwnershipValidationModule, - createERC20SessionValidationModule, - createBatchedSessionRouterModule, - createSessionKeyManagerModule, - createMultiChainValidationModule, - DEFAULT_ECDSA_OWNERSHIP_MODULE, - DEFAULT_SESSION_KEY_MANAGER_MODULE, - DEFAULT_MULTICHAIN_MODULE, - DEFAULT_BATCHED_SESSION_ROUTER_MODULE, - type ECDSAOwnershipValidationModuleConfig, - type BatchedSessionRouterModuleConfig, - type SessionKeyManagerModuleConfig, - type MultiChainValidationModuleConfig, - type SessionValidationModuleConfig, -} from "@biconomy/modules"; - -export const createSmartAccountClient = BiconomySmartAccountV2.create; - -export type SmartWalletConfig = BiconomySmartAccountV2Config; diff --git a/packages/account/src/utils/Types.ts b/packages/account/src/utils/Types.ts deleted file mode 100644 index f653796c1..000000000 --- a/packages/account/src/utils/Types.ts +++ /dev/null @@ -1,304 +0,0 @@ -import { BigNumberish, SmartAccountSigner, UserOperationStruct } from "@alchemy/aa-core"; -import { IBundler } from "@biconomy/bundler"; -import { - type FeeQuotesOrDataDto, - type IPaymaster, - type PaymasterFeeQuote, - PaymasterMode, - type SmartAccountData, - type SponsorUserOperationDto, -} from "@biconomy/paymaster"; -import { BaseValidationModule, ModuleInfo } from "@biconomy/modules"; -import { Chain, Hex, WalletClient } from "viem"; -import { SupportedSigner, StateOverrideSet } from "@biconomy/common"; - -export type EntryPointAddresses = Record<string, string>; -export type BiconomyFactories = Record<string, string>; -export type BiconomyImplementations = Record<string, string>; -export type EntryPointAddressesByVersion = Record<string, string>; -export type BiconomyFactoriesByVersion = Record<string, string>; -export type BiconomyImplementationsByVersion = Record<string, string>; - -export type SmartAccountConfig = { - /** entryPointAddress: address of the entry point */ - entryPointAddress: string; - /** factoryAddress: address of the smart account factory */ - bundler?: IBundler; -}; - -export interface BalancePayload { - /** address: The address of the account */ - address: string; - /** chainId: The chainId of the network */ - chainId: number; - /** amount: The amount of the balance */ - amount: bigint; - /** decimals: The number of decimals */ - decimals: number; - /** formattedAmount: The amount of the balance formatted */ - formattedAmount: string; -} - -export interface GasOverheads { - /** fixed: fixed gas overhead */ - fixed: number; - /** perUserOp: per user operation gas overhead */ - perUserOp: number; - /** perUserOpWord: per user operation word gas overhead */ - perUserOpWord: number; - /** zeroByte: per byte gas overhead */ - zeroByte: number; - /** nonZeroByte: per non zero byte gas overhead */ - nonZeroByte: number; - /** bundleSize: per signature bundleSize */ - bundleSize: number; - /** sigSize: sigSize gas overhead */ - sigSize: number; -} - -export type BaseSmartAccountConfig = { - /** index: helps to not conflict with other smart account instances */ - index?: number; - /** provider: WalletClientSigner from viem */ - provider?: WalletClient; - /** entryPointAddress: address of the smart account entry point */ - entryPointAddress?: string; - /** accountAddress: address of the smart account, potentially counterfactual */ - accountAddress?: string; - /** overheads: {@link GasOverheads} */ - overheads?: Partial<GasOverheads>; - /** paymaster: {@link IPaymaster} interface */ - paymaster?: IPaymaster; - /** chainId: chainId of the network */ - chainId?: number; -}; - -export type BiconomyTokenPaymasterRequest = { - /** feeQuote: {@link PaymasterFeeQuote} */ - feeQuote: PaymasterFeeQuote; - /** spender: The address of the spender who is paying for the transaction, this can usually be set to feeQuotesResponse.tokenPaymasterAddress */ - spender: Hex; - /** maxApproval: If set to true, the paymaster will approve the maximum amount of tokens required for the transaction. Not recommended */ - maxApproval?: boolean; - /* skip option to patch callData if approval is already given to the paymaster */ - skipPatchCallData?: boolean; -}; - -export type RequireAtLeastOne<T, Keys extends keyof T = keyof T> = Pick<T, Exclude<keyof T, Keys>> & - { - [K in Keys]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<Keys, K>>>; - }[Keys]; - -export type ConditionalBundlerProps = RequireAtLeastOne< - { - bundler: IBundler; - bundlerUrl: string; - }, - "bundler" | "bundlerUrl" ->; -export type ResolvedBundlerProps = { - bundler: IBundler; -}; -export type ConditionalValidationProps = RequireAtLeastOne< - { - defaultValidationModule: BaseValidationModule; - signer: SupportedSigner; - }, - "defaultValidationModule" | "signer" ->; - -export type ResolvedValidationProps = { - /** defaultValidationModule: {@link BaseValidationModule} */ - defaultValidationModule: BaseValidationModule; - /** activeValidationModule: {@link BaseValidationModule}. The active validation module. Will default to the defaultValidationModule */ - activeValidationModule: BaseValidationModule; - /** signer: ethers Wallet, viemWallet or alchemys SmartAccountSigner */ - signer: SmartAccountSigner; - /** chainId: chainId of the network */ - chainId: number; -}; - -export type BiconomySmartAccountV2ConfigBaseProps = { - /** Factory address of biconomy factory contract or some other contract you have deployed on chain */ - factoryAddress?: Hex; - /** Sender address: If you want to override the Signer address with some other address and get counterfactual address can use this to pass the EOA and get SA address */ - senderAddress?: Hex; - /** implementation of smart contract address or some other contract you have deployed and want to override */ - implementationAddress?: Hex; - /** defaultFallbackHandler: override the default fallback contract address */ - defaultFallbackHandler?: Hex; - /** rpcUrl: Rpc url, optional, we set default rpc url if not passed. */ - rpcUrl?: string; // as good as Provider - /** paymasterUrl: The Paymaster URL retrieved from the Biconomy dashboard */ - paymasterUrl?: string; - /** biconomyPaymasterApiKey: The API key retrieved from the Biconomy dashboard */ - biconomyPaymasterApiKey?: string; - /** activeValidationModule: The active validation module. Will default to the defaultValidationModule */ - activeValidationModule?: BaseValidationModule; - /** scanForUpgradedAccountsFromV1: set to true if you you want the userwho was using biconomy SA v1 to upgrade to biconomy SA v2 */ - scanForUpgradedAccountsFromV1?: boolean; - /** the index of SA the EOA have generated and till which indexes the upgraded SA should scan */ - maxIndexForScan?: number; - /** Can be used to optionally override the chain with a custom chain if it doesn't already exist in viems list of supported chains */ - viemChain?: Chain; -}; -export type BiconomySmartAccountV2Config = BiconomySmartAccountV2ConfigBaseProps & - BaseSmartAccountConfig & - ConditionalBundlerProps & - ConditionalValidationProps; - -export type BiconomySmartAccountV2ConfigConstructorProps = BiconomySmartAccountV2ConfigBaseProps & - BaseSmartAccountConfig & - ResolvedBundlerProps & - ResolvedValidationProps; - -export type BuildUserOpOptions = { - /** overrides: Explicitly set gas values */ - // overrides?: Overrides; - /** Not currently in use */ - // skipBundlerGasEstimation?: boolean; - /** params relevant to the module, mostly relevant to sessions */ - params?: ModuleInfo; - /** nonceOptions: For overriding the nonce */ - nonceOptions?: NonceOptions; - /** forceEncodeForBatch: For encoding the user operation for batch */ - forceEncodeForBatch?: boolean; - /** paymasterServiceData: Options specific to transactions that involve a paymaster */ - paymasterServiceData?: PaymasterUserOperationDto; - /** simulationType: Determine which parts of the tx a bundler will simulate: "validation" | "validation_and_execution". */ - simulationType?: SimulationType; - /** stateOverrideSet: For overriding the state */ - stateOverrideSet?: StateOverrideSet; - /** set to true if the tx is being used *only* to deploy the smartContract, so "0x" is set as the userOp.callData */ - useEmptyDeployCallData?: boolean; -}; - -export type NonceOptions = { - /** nonceKey: The key to use for nonce */ - nonceKey?: number; - /** nonceOverride: The nonce to use for the transaction */ - nonceOverride?: number; -}; - -export type SimulationType = "validation" | "validation_and_execution"; - -export type Overrides = { - /* Value used by inner account execution */ - callGasLimit?: Hex; - /* Actual gas used by the validation of this UserOperation */ - verificationGasLimit?: Hex; - /* Gas overhead of this UserOperation */ - preVerificationGas?: Hex; - /* Maximum fee per gas (similar to EIP-1559 max_fee_per_gas) */ - maxFeePerGas?: Hex; - /* Maximum priority fee per gas (similar to EIP-1559 max_priority_fee_per_gas) */ - maxPriorityFeePerGas?: Hex; - /* Address of paymaster sponsoring the transaction, followed by extra data to send to the paymaster ("0x" for self-sponsored transaction) */ - paymasterData?: Hex; - /* Data passed into the account along with the nonce during the verification step */ - signature?: Hex; -}; - -export type InitilizationData = { - accountIndex?: number; - signerAddress?: string; -}; - -export type PaymasterUserOperationDto = SponsorUserOperationDto & - FeeQuotesOrDataDto & { - /** mode: sponsored or erc20 */ - mode: PaymasterMode; - /** Always recommended, especially when using token paymaster */ - calculateGasLimits?: boolean; - /** Expiry duration in seconds */ - expiryDuration?: number; - /** Webhooks to be fired after user op is sent */ - webhookData?: Record<string, any>; - /** Smart account meta data */ - smartAccountInfo?: SmartAccountData; - /** the fee-paying token address */ - feeTokenAddress?: string; - /** The fee quote */ - feeQuote?: PaymasterFeeQuote; - /** The address of the spender. This is usually set to FeeQuotesOrDataResponse.tokenPaymasterAddress */ - spender?: Hex; - /** Not recommended */ - maxApproval?: boolean; - /* skip option to patch callData if approval is already given to the paymaster */ - skipPatchCallData?: boolean; - }; - -export type InitializeV2Data = { - accountIndex?: number; -}; - -export type EstimateUserOpGasParams = { - userOp: Partial<UserOperationStruct>; - // overrides?: Overrides; - /** Currrently has no effect */ - // skipBundlerGasEstimation?: boolean; - /** paymasterServiceData: Options specific to transactions that involve a paymaster */ - paymasterServiceData?: SponsorUserOperationDto; -}; - -export interface TransactionDetailsForUserOp { - /** target: The address of the contract to call */ - target: string; - /** data: The data to send to the contract */ - data: string; - /** value: The value to send to the contract */ - value?: BigNumberish; - /** gasLimit: The gas limit to use for the transaction */ - gasLimit?: BigNumberish; - /** maxFeePerGas: The maximum fee per gas to use for the transaction */ - maxFeePerGas?: BigNumberish; - /** maxPriorityFeePerGas: The maximum priority fee per gas to use for the transaction */ - maxPriorityFeePerGas?: BigNumberish; - /** nonce: The nonce to use for the transaction */ - nonce?: BigNumberish; -} - -export type CounterFactualAddressParam = { - index?: number; - validationModule?: BaseValidationModule; - /** scanForUpgradedAccountsFromV1: set to true if you you want the userwho was using biconomy SA v1 to upgrade to biconomy SA v2 */ - scanForUpgradedAccountsFromV1?: boolean; - /** the index of SA the EOA have generated and till which indexes the upgraded SA should scan */ - maxIndexForScan?: number; -}; - -export type QueryParamsForAddressResolver = { - eoaAddress: Hex; - index: number; - moduleAddress: Hex; - moduleSetupData: Hex; - maxIndexForScan?: number; -}; - -export type SmartAccountInfo = { - /** accountAddress: The address of the smart account */ - accountAddress: Hex; - /** factoryAddress: The address of the smart account factory */ - factoryAddress: Hex; - /** currentImplementation: The address of the current implementation */ - currentImplementation: string; - /** currentVersion: The version of the smart account */ - currentVersion: string; - /** factoryVersion: The version of the factory */ - factoryVersion: string; - /** deploymentIndex: The index of the deployment */ - deploymentIndex: BigNumberish; -}; - -export type ValueOrData = RequireAtLeastOne< - { - value: BigNumberish | string; - data: string; - }, - "value" | "data" ->; -export type Transaction = { - to: string; -} & ValueOrData; - -export type SupportedToken = Omit<PaymasterFeeQuote, "maxGasFeeUSD" | "usdPayment" | "maxGasFee" | "validUntil">; diff --git a/packages/account/src/utils/Utils.ts b/packages/account/src/utils/Utils.ts deleted file mode 100644 index 7d18918b1..000000000 --- a/packages/account/src/utils/Utils.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { encodeAbiParameters, parseAbiParameters, keccak256, Hex, Chain } from "viem"; -import type { UserOperationStruct } from "@alchemy/aa-core"; -import { SupportedSigner, convertSigner } from "@biconomy/common"; -import { extractChainIdFromBundlerUrl } from "@biconomy/bundler"; -import { BiconomySmartAccountV2Config } from "./Types.js"; -import { extractChainIdFromPaymasterUrl } from "@biconomy/bundler"; -import * as chains from "viem/chains"; -import { ERROR_MESSAGES } from "./Constants.js"; - -/** - * pack the userOperation - * @param op - * @param forSignature "true" if the hash is needed to calculate the getUserOpHash() - * "false" to pack entire UserOp, for calculating the calldata cost of putting it on-chain. - */ -export function packUserOp(op: Partial<UserOperationStruct>, forSignature = true): string { - if (!op.initCode || !op.callData || !op.paymasterAndData) throw new Error("Missing userOp properties"); - if (forSignature) { - return encodeAbiParameters(parseAbiParameters("address, uint256, bytes32, bytes32, uint256, uint256, uint256, uint256, uint256, bytes32"), [ - op.sender as Hex, - BigInt(op.nonce as Hex), - keccak256(op.initCode as Hex), - keccak256(op.callData as Hex), - BigInt(op.callGasLimit as Hex), - BigInt(op.verificationGasLimit as Hex), - BigInt(op.preVerificationGas as Hex), - BigInt(op.maxFeePerGas as Hex), - BigInt(op.maxPriorityFeePerGas as Hex), - keccak256(op.paymasterAndData as Hex), - ]); - } else { - // for the purpose of calculating gas cost encode also signature (and no keccak of bytes) - return encodeAbiParameters(parseAbiParameters("address, uint256, bytes, bytes, uint256, uint256, uint256, uint256, uint256, bytes, bytes"), [ - op.sender as Hex, - BigInt(op.nonce as Hex), - op.initCode as Hex, - op.callData as Hex, - BigInt(op.callGasLimit as Hex), - BigInt(op.verificationGasLimit as Hex), - BigInt(op.preVerificationGas as Hex), - BigInt(op.maxFeePerGas as Hex), - BigInt(op.maxPriorityFeePerGas as Hex), - op.paymasterAndData as Hex, - op.signature as Hex, - ]); - } -} - -export const isNullOrUndefined = (value: any): value is undefined => { - return value === null || value === undefined; -}; - -export const compareChainIds = async ( - signer: SupportedSigner, - biconomySmartAccountConfig: BiconomySmartAccountV2Config, - skipChainIdCalls: boolean, -): Promise<Error | void> => { - const signerResult = await convertSigner(signer, skipChainIdCalls); - - const chainIdFromBundler = biconomySmartAccountConfig.bundlerUrl - ? extractChainIdFromBundlerUrl(biconomySmartAccountConfig.bundlerUrl) - : biconomySmartAccountConfig.bundler - ? extractChainIdFromBundlerUrl(biconomySmartAccountConfig.bundler.getBundlerUrl()) - : undefined; - - const chainIdFromPaymasterUrl = biconomySmartAccountConfig.paymasterUrl - ? extractChainIdFromPaymasterUrl(biconomySmartAccountConfig.paymasterUrl) - : undefined; - - if (!isNullOrUndefined(signerResult.chainId)) { - if (chainIdFromBundler !== undefined && signerResult.chainId !== chainIdFromBundler) { - throw new Error(`Chain IDs from signer (${signerResult.chainId}) and bundler (${chainIdFromBundler}) do not match.`); - } - if (chainIdFromPaymasterUrl !== undefined && signerResult.chainId !== chainIdFromPaymasterUrl) { - throw new Error(`Chain IDs from signer (${signerResult.chainId}) and paymaster (${chainIdFromPaymasterUrl}) do not match.`); - } - } else { - if (chainIdFromBundler !== undefined && chainIdFromPaymasterUrl !== undefined && chainIdFromBundler !== chainIdFromPaymasterUrl) { - throw new Error(`Chain IDs from bundler (${chainIdFromBundler}) and paymaster (${chainIdFromPaymasterUrl}) do not match.`); - } - } -}; - -export const isValidRpcUrl = (url: string): boolean => { - const regex = /^(https:\/\/|wss:\/\/).*/; - return regex.test(url); -}; - -export const addressEquals = (a?: string, b?: string): boolean => !!a && !!b && a?.toLowerCase() === b.toLowerCase(); - -/** - * Utility method for converting a chainId to a {@link Chain} object - * - * @param chainId - * @returns a {@link Chain} object for the given chainId - * @throws if the chainId is not found - */ -export const getChain = (chainId: number): Chain => { - for (const chain of Object.values(chains)) { - if (chain.id === chainId) { - return chain; - } - } - throw new Error(ERROR_MESSAGES.CHAIN_NOT_FOUND); -}; diff --git a/packages/account/src/utils/index.ts b/packages/account/src/utils/index.ts deleted file mode 100644 index bc65ec9be..000000000 --- a/packages/account/src/utils/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from "./Types.js"; -export * from "./Utils.js"; -export * from "./Constants.js"; diff --git a/packages/account/tests/account.e2e.spec.ts b/packages/account/tests/account.e2e.spec.ts deleted file mode 100644 index 82f9649f1..000000000 --- a/packages/account/tests/account.e2e.spec.ts +++ /dev/null @@ -1,671 +0,0 @@ -import { TestData } from "../../../tests"; -import { createSmartAccountClient, ERROR_MESSAGES, FeeQuotesOrDataResponse, NATIVE_TOKEN_ALIAS, PaymasterMode } from "../src/index"; -import { Hex, createWalletClient, encodeFunctionData, getContract, http, parseAbi } from "viem"; -import { UserOperationStruct } from "@alchemy/aa-core"; -import { checkBalance, entryPointABI } from "../../../tests/utils"; -import { ERC20_ABI } from "@biconomy/modules"; -import { privateKeyToAccount, generatePrivateKey } from "viem/accounts"; - -describe("Account Tests", () => { - let mumbai: TestData; - let baseSepolia: TestData; - let optimism: TestData; - - beforeEach(() => { - // @ts-ignore: Comes from setup-e2e-tests - [mumbai, baseSepolia, optimism] = testDataPerChain; - }); - - it("should have addresses", async () => { - const { - whale: { viemWallet: signer, publicAddress: sender }, - minnow: { viemWallet: recipientSigner, publicAddress: recipient }, - bundlerUrl, - } = mumbai; - - const { - whale: { viemWallet: signerBase, publicAddress: senderBase }, - minnow: { viemWallet: recipientSignerBase, publicAddress: recipientBase }, - bundlerUrl: bundlerUrlBase, - } = baseSepolia; - - const { - whale: { viemWallet: signerOp, publicAddress: senderOp }, - minnow: { viemWallet: recipientSignerOp, publicAddress: recipientOp }, - bundlerUrl: bundlerUrlOp, - } = optimism; - - const smartAccount = await createSmartAccountClient({ - signer, - bundlerUrl, - }); - - const reciepientSmartAccount = await createSmartAccountClient({ - signer: recipientSigner, - bundlerUrl, - }); - - const smartAccountBase = await createSmartAccountClient({ - signer: signerBase, - bundlerUrl: bundlerUrlBase, - }); - - const reciepientSmartAccountBase = await createSmartAccountClient({ - signer: recipientSignerBase, - bundlerUrl: bundlerUrlBase, - }); - - const smartAccountOp = await createSmartAccountClient({ - signer: signerOp, - bundlerUrl: bundlerUrlOp, - }); - - const reciepientSmartAccountOp = await createSmartAccountClient({ - signer: recipientSignerOp, - bundlerUrl: bundlerUrlOp, - }); - - const addresses = await Promise.all([ - sender, - smartAccount.getAddress(), - recipient, - reciepientSmartAccount.getAddress(), - senderBase, - smartAccountBase.getAddress(), - recipientBase, - reciepientSmartAccountBase.getAddress(), - senderOp, - smartAccountOp.getAddress(), - recipientOp, - reciepientSmartAccountOp.getAddress(), - ]); - expect(addresses.every(Boolean)).toBeTruthy(); - }); - - it("should send some native token to a recipient", async () => { - const { - whale: { viemWallet: signer }, - minnow: { publicAddress: recipient }, - bundlerUrl, - publicClient, - } = mumbai; - - const smartAccount = await createSmartAccountClient({ - signer, - bundlerUrl, - }); - - const balance = (await checkBalance(publicClient, recipient)) as bigint; - const { wait } = await smartAccount.sendTransaction( - { - to: recipient, - value: 1, - }, - { - simulationType: "validation_and_execution", - }, - ); - - const result = await wait(); - const newBalance = (await checkBalance(publicClient, recipient)) as bigint; - - expect(result?.receipt?.transactionHash).toBeTruthy(); - expect(newBalance - balance).toBe(1n); - }, 50000); - - it("Create a smart account with paymaster with an api key", async () => { - const { - whale: { viemWallet: signer }, - bundlerUrl, - paymasterUrl, - } = mumbai; - - const smartAccount = await createSmartAccountClient({ - signer, - paymasterUrl, - bundlerUrl, - }); - - const paymaster = smartAccount.paymaster; - expect(paymaster).not.toBeNull(); - expect(paymaster).not.toBeUndefined(); - }); - - it("Should gaslessly mint an NFT on Mumbai", async () => { - const { - whale: { viemWallet: signer, publicAddress: recipient }, - bundlerUrl, - paymasterUrl, - publicClient, - nftAddress, - } = mumbai; - - const smartAccount = await createSmartAccountClient({ - signer, - bundlerUrl, - paymasterUrl, - }); - - const encodedCall = encodeFunctionData({ - abi: parseAbi(["function safeMint(address to) public"]), - functionName: "safeMint", - args: [recipient], - }); - - const transaction = { - to: nftAddress, // NFT address - data: encodedCall, - }; - - const balance = (await checkBalance(publicClient, recipient, nftAddress)) as bigint; - - const maticBalanceBefore = await checkBalance(publicClient, await smartAccount.getAddress()); - - const response = await smartAccount.sendTransaction(transaction, { - paymasterServiceData: { mode: PaymasterMode.SPONSORED }, - simulationType: "validation", - }); - - const userOpReceipt = await response.wait(3); - expect(userOpReceipt.userOpHash).toBeTruthy(); - expect(userOpReceipt.success).toBe("true"); - - const maticBalanceAfter = await checkBalance(publicClient, await smartAccount.getAddress()); - - expect(maticBalanceAfter).toEqual(maticBalanceBefore); - - const newBalance = (await checkBalance(publicClient, recipient, nftAddress)) as bigint; - - expect(newBalance - balance).toBe(1n); - }, 60000); - - // TODO(Remove when Yash fixes approvals issue) - it.skip("Should mint an NFT on Mumbai and pay with ERC20 - with preferredToken", async () => { - const { - whale: { viemWallet: signer, publicAddress: recipient }, - bundlerUrl, - nftAddress, - publicClient - } = mumbai; - - const smartAccount = await createSmartAccountClient({ - signer, - bundlerUrl, - biconomyPaymasterApiKey: "7K_k68BFN.ed274da8-69a1-496d-a897-508fc2653666", - }); - - const accountAddress = await smartAccount.getAddress(); - - const encodedCall = encodeFunctionData({ - abi: parseAbi(["function safeMint(address _to)"]), - functionName: "safeMint", - args: [recipient], - }); - - const transaction = { - to: nftAddress, // NFT address - data: encodedCall, - }; - - const balance = (await checkBalance(publicClient, recipient, nftAddress)) as bigint; - const maticBalanceBefore = await checkBalance(publicClient, accountAddress); - const usdcBalanceBefore = await checkBalance(publicClient, accountAddress, "0xda5289fcaaf71d52a80a254da614a192b693e977"); - - const { wait } = await smartAccount.sendTransaction([transaction], { - paymasterServiceData: { - mode: PaymasterMode.ERC20, - preferredToken: "0xda5289fcaaf71d52a80a254da614a192b693e977", - }, - }); - - const { - receipt: { transactionHash }, - userOpHash, - success, - } = await wait(); - - expect(transactionHash).toBeTruthy(); - expect(userOpHash).toBeTruthy(); - expect(success).toBe("true"); - - const maticBalanceAfter = await checkBalance(publicClient, await smartAccount.getAddress()); - expect(maticBalanceAfter).toEqual(maticBalanceBefore); - - const usdcBalanceAfter = await checkBalance(publicClient, await smartAccount.getAddress(), "0xda5289fcaaf71d52a80a254da614a192b693e977"); - expect(usdcBalanceAfter).toBeLessThan(usdcBalanceBefore); - - const newBalance = (await checkBalance(publicClient, recipient, nftAddress)) as bigint; - expect(newBalance - balance).toBe(1n); - }, 60000); - - it("Should expect several feeQuotes in resonse to empty tokenInfo fields", async () => { - const { - whale: { viemWallet: signer, publicAddress: recipient }, - bundlerUrl, - biconomyPaymasterApiKey, - nftAddress, - } = mumbai; - - const smartAccount = await createSmartAccountClient({ - signer, - bundlerUrl, - biconomyPaymasterApiKey, - }); - - const encodedCall = encodeFunctionData({ - abi: parseAbi(["function safeMint(address _to)"]), - functionName: "safeMint", - args: [recipient], - }); - - const transaction = { - to: nftAddress, // NFT address - data: encodedCall, - }; - - const feeQuotesResponse = await smartAccount.getTokenFees(transaction, { paymasterServiceData: { mode: PaymasterMode.ERC20 } }); - expect(feeQuotesResponse.feeQuotes?.length).toBeGreaterThan(1); - }); - - // TODO(Remove when Yash fixes approvals issue) - it.skip("Should mint an NFT on Mumbai and pay with ERC20 - with token selection and no maxApproval", async () => { - const preferredToken: Hex = "0xda5289fcaaf71d52a80a254da614a192b693e977"; - const { - whale: { viemWallet: signer, publicAddress: recipient }, - bundlerUrl, - paymasterUrl, - publicClient, - nftAddress, - } = mumbai; - - const smartAccount = await createSmartAccountClient({ - signer, - bundlerUrl, - paymasterUrl, - }); - - const smartAccountAddress = await smartAccount.getAddress(); - - const encodedCall = encodeFunctionData({ - abi: parseAbi(["function safeMint(address _to)"]), - functionName: "safeMint", - args: [recipient], - }); - - const transaction = { - to: nftAddress, // NFT address - data: encodedCall, - }; - - const feeQuotesResponse = await smartAccount.getTokenFees(transaction, { - paymasterServiceData: { - mode: PaymasterMode.ERC20, - preferredToken, - }, - }); - - const selectedFeeQuote = feeQuotesResponse.feeQuotes?.[0]; - const spender = feeQuotesResponse.tokenPaymasterAddress!; - - const contract = getContract({ - address: preferredToken, - abi: parseAbi(ERC20_ABI), - client: publicClient, - }); - - const allowanceBefore = (await contract.read.allowance([smartAccountAddress, spender])) as bigint; - - if (allowanceBefore > 0) { - const decreaseAllowanceData = encodeFunctionData({ - abi: parseAbi(["function decreaseAllowance(address spender, uint256 subtractedValue)"]), - functionName: "decreaseAllowance", - args: [spender, allowanceBefore], - }); - - const decreaseAllowanceTx = { - to: "0xda5289fcaaf71d52a80a254da614a192b693e977", - data: decreaseAllowanceData, - }; - - const { wait } = await smartAccount.sendTransaction(decreaseAllowanceTx, { paymasterServiceData: { mode: PaymasterMode.SPONSORED } }); - const { success } = await wait(); - - expect(success).toBe("true"); - const allowanceAfter = (await contract.read.allowance([smartAccountAddress, spender])) as bigint; - expect(allowanceAfter).toBe(0n); - } - - const balance = (await checkBalance(publicClient, recipient, nftAddress)) as bigint; - const maticBalanceBefore = await checkBalance(publicClient, smartAccountAddress); - const usdcBalanceBefore = await checkBalance(publicClient, smartAccountAddress, preferredToken); - - const { wait } = await smartAccount.sendTransaction(transaction, { - paymasterServiceData: { - mode: PaymasterMode.ERC20, - feeQuote: selectedFeeQuote, - spender: feeQuotesResponse.tokenPaymasterAddress, - }, - }); - - const { - receipt: { transactionHash }, - userOpHash, - success, - } = await wait(); - - expect(userOpHash).toBeTruthy(); - expect(success).toBe("true"); - expect(transactionHash).toBeTruthy(); - - const maticBalanceAfter = await checkBalance(publicClient, smartAccountAddress); - expect(maticBalanceAfter).toEqual(maticBalanceBefore); - - const usdcBalanceAfter = await checkBalance(publicClient, smartAccountAddress, preferredToken); - expect(usdcBalanceAfter).toBeLessThan(usdcBalanceBefore); - - const newBalance = (await checkBalance(publicClient, recipient, nftAddress)) as bigint; - expect(newBalance - balance).toBe(1n); - }, 60000); - - it("Should throw and error if missing field for ERC20 Paymaster user op", async () => { - const { - whale: { viemWallet: signer, publicAddress: recipient }, - bundlerUrl, - biconomyPaymasterApiKey, - nftAddress, - } = mumbai; - - const smartAccount = await createSmartAccountClient({ - signer, - bundlerUrl, - biconomyPaymasterApiKey, - }); - - const encodedCall = encodeFunctionData({ - abi: parseAbi(["function safeMint(address _to)"]), - functionName: "safeMint", - args: [recipient], - }); - - const transaction = { - to: nftAddress, // NFT address - data: encodedCall, - }; - - const feeQuotesResponse: FeeQuotesOrDataResponse = await smartAccount.getTokenFees(transaction, { - paymasterServiceData: { - mode: PaymasterMode.ERC20, - preferredToken: "0xda5289fcaaf71d52a80a254da614a192b693e977", - }, - }); - - expect(async () => - smartAccount.sendTransaction(transaction, { - paymasterServiceData: { - mode: PaymasterMode.ERC20, - feeQuote: feeQuotesResponse.feeQuotes?.[0], - }, - simulationType: "validation", - }), - ).rejects.toThrow(ERROR_MESSAGES.SPENDER_REQUIRED); - }, 60000); - - it("#getUserOpHash should match entryPoint.getUserOpHash", async () => { - const { - whale: { viemWallet: signer }, - bundlerUrl, - entryPointAddress, - publicClient, - paymasterUrl, - } = mumbai; - - const smartAccount = await createSmartAccountClient({ - signer, - paymasterUrl, - bundlerUrl, - }); - - const userOp: UserOperationStruct = { - sender: "0x".padEnd(42, "1") as string, - nonce: 2, - initCode: "0x3333", - callData: "0x4444", - callGasLimit: 5, - verificationGasLimit: 6, - preVerificationGas: 7, - maxFeePerGas: 8, - maxPriorityFeePerGas: 9, - paymasterAndData: "0xaaaaaa", - signature: "0xbbbb", - }; - - const epHash = await publicClient.readContract({ - address: entryPointAddress as Hex, - abi: entryPointABI, - functionName: "getUserOpHash", - // @ts-ignore - args: [userOp], - }); - - const hash = await smartAccount.getUserOpHash(userOp); - expect(hash).toBe(epHash); - }, 30000); - - it("should be deployed to counterfactual address", async () => { - const { - whale: { viemWallet: signer }, - bundlerUrl, - publicClient, - paymasterUrl, - } = mumbai; - - const smartAccount = await createSmartAccountClient({ - signer, - paymasterUrl, - bundlerUrl, - }); - - const accountAddress = await smartAccount.getAccountAddress(); - const byteCode = await publicClient.getBytecode({ address: accountAddress as Hex }); - - expect(byteCode?.length).toBeGreaterThan(2); - }, 10000); // on github runner it takes more time than 5000ms - - it("should check if ecdsaOwnershipModule is enabled", async () => { - const ecdsaOwnershipModule = "0x0000001c5b32F37F5beA87BDD5374eB2aC54eA8e"; - - const { - whale: { viemWallet: signer }, - bundlerUrl, - viemChain, - } = mumbai; - - const smartAccount = await createSmartAccountClient({ - signer, - bundlerUrl, - rpcUrl: viemChain.rpcUrls.default.http[0], - }); - - expect(ecdsaOwnershipModule).toBe(smartAccount.activeValidationModule.getAddress()); - }); - - it("Should throw, chain id from signer and bundlerUrl do not match", async () => { - const { - whale: { viemWallet: signer }, - } = mumbai; - - const createAccount = createSmartAccountClient({ - signer, - bundlerUrl: "https://bundler.biconomy.io/api/v2/1/nJPK7B3ru.dd7f7861-190d-41bd-af80-6877f74b8f44", // mock - }); - - await expect(createAccount).rejects.toThrow(); - }); - - it("Should throw, chain id from paymasterUrl and bundlerUrl do not match", async () => { - const { - whale: { viemWallet: signer }, - } = mumbai; - - const createAccount = createSmartAccountClient({ - signer, - paymasterUrl: "https://paymaster.biconomy.io/api/v1/1/-RObQRX9ei.fc6918eb-c582-4417-9d5a-0507b17cfe71", - bundlerUrl: "https://bundler.biconomy.io/api/v2/80001/nJPK7B3ru.dd7f7861-190d-41bd-af80-6877f74b8f44", // mock - }); - - await expect(createAccount).rejects.toThrow(); - }); - it("should deploy a smart account with native token balance", async () => { - const { - bundlerUrl, - biconomyPaymasterApiKey, - viemChain, - publicClient, - whale: { viemWallet: signer, publicAddress, account }, - deploymentCost, - } = mumbai; - - const newPrivateKey = generatePrivateKey(); - const newAccount = privateKeyToAccount(newPrivateKey); - - const newViemWallet = createWalletClient({ - account: newAccount, - chain: viemChain, - transport: http(viemChain.rpcUrls.default.http[0]), - }); - - const smartAccount = await createSmartAccountClient({ - signer: newViemWallet, - biconomyPaymasterApiKey, - bundlerUrl, - }); - - const smartAccountAddress = await smartAccount.getAccountAddress(); - - // Setup: - const hash = await signer.sendTransaction({ to: smartAccountAddress, value: BigInt(deploymentCost), account, chain: viemChain }); // Send enough native token to counterfactual address to deploy the smart account - const transaction = await publicClient.waitForTransactionReceipt({ hash }); - expect(transaction).toBeTruthy(); - - // Test: - const { wait } = await smartAccount.deploy(); - const { success } = await wait(); - - const byteCode = await publicClient.getBytecode({ address: smartAccountAddress }); - expect(success).toBe("true"); - expect(byteCode).toBeTruthy(); - }, 60000); - - it("should deploy a smart account with sponsorship", async () => { - const { bundlerUrl, biconomyPaymasterApiKey, viemChain, publicClient } = mumbai; - - const newPrivateKey = generatePrivateKey(); - const newAccount = privateKeyToAccount(newPrivateKey); - - const newViemWallet = createWalletClient({ - account: newAccount, - chain: viemChain, - transport: http(viemChain.rpcUrls.default.http[0]), - }); - - const smartAccount = await createSmartAccountClient({ - signer: newViemWallet, - biconomyPaymasterApiKey, - bundlerUrl, - }); - - const smartAccountAddress = await smartAccount.getAccountAddress(); - const balance = await publicClient.getBalance({ address: smartAccountAddress }); - expect(balance).toBe(0n); - - const { wait } = await smartAccount.deploy({ - paymasterServiceData: { mode: PaymasterMode.SPONSORED }, - }); - const { success } = await wait(); - - const byteCode = await publicClient.getBytecode({ address: smartAccountAddress }); - expect(success).toBe("true"); - expect(byteCode).toBeTruthy(); - }, 60000); - - it("should fail to deploy a smart account if no native token balance or paymaster", async () => { - const { bundlerUrl, biconomyPaymasterApiKey, viemChain } = mumbai; - - const newPrivateKey = generatePrivateKey(); - const newAccount = privateKeyToAccount(newPrivateKey); - - const newViemWallet = createWalletClient({ - account: newAccount, - chain: viemChain, - transport: http(viemChain.rpcUrls.default.http[0]), - }); - - const smartAccount = await createSmartAccountClient({ - signer: newViemWallet, - biconomyPaymasterApiKey, - bundlerUrl, - }); - - expect(async () => smartAccount.deploy()).rejects.toThrow(ERROR_MESSAGES.NO_NATIVE_TOKEN_BALANCE_DURING_DEPLOY); - }); - - it("should get supported tokens from the paymaster", async () => { - const { - whale: { viemWallet: signer }, - bundlerUrl, - biconomyPaymasterApiKey, - } = mumbai; - - const smartAccount = await createSmartAccountClient({ - signer, - biconomyPaymasterApiKey, - bundlerUrl, - }); - - const tokens = await smartAccount.getSupportedTokens(); - - expect(tokens.length).toBeGreaterThan(0); - expect(tokens[0]).toHaveProperty("tokenAddress"); - expect(tokens[0]).toHaveProperty("symbol"); - expect(tokens[0]).toHaveProperty("decimal"); - expect(tokens[0]).toHaveProperty("premiumPercentage"); - expect(tokens[0]).toHaveProperty("logoUrl"); - }, 60000); - - it("should fail to deploy a smart account if already deployed", async () => { - const { - whale: { viemWallet: signer }, - bundlerUrl, - biconomyPaymasterApiKey, - } = mumbai; - - const smartAccount = await createSmartAccountClient({ - signer, - biconomyPaymasterApiKey, - bundlerUrl, - }); - - expect(async () => smartAccount.deploy()).rejects.toThrow(ERROR_MESSAGES.ACCOUNT_ALREADY_DEPLOYED); - }, 60000); - - it("should fetch balances for smartAccount", async () => { - const usdt = "0xda5289fcaaf71d52a80a254da614a192b693e977"; - const { - whale: { viemWallet: signer }, - bundlerUrl, - publicClient, - biconomyPaymasterApiKey, - } = mumbai; - - const smartAccount = await createSmartAccountClient({ - signer, - biconomyPaymasterApiKey, - bundlerUrl, - }); - - const usdcBalanceBefore = await checkBalance(publicClient, await smartAccount.getAddress(), usdt); - const [usdtBalanceFromSmartAccount] = await smartAccount.getBalances([usdt]); - - expect(usdcBalanceBefore).toBe(usdtBalanceFromSmartAccount.amount); - }); -}); diff --git a/packages/account/tests/account.optimism.e2e.spec.ts b/packages/account/tests/account.optimism.e2e.spec.ts deleted file mode 100644 index d558ba4ed..000000000 --- a/packages/account/tests/account.optimism.e2e.spec.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { TestData } from "../../../tests"; -import { createSmartAccountClient, PaymasterMode } from "../src/index"; -import { encodeFunctionData, parseAbi } from "viem"; -import { checkBalance } from "../../../tests/utils"; - -const maybe = process.env.WITH_MAINNET_TESTS === "true" ? describe : describe.skip; - -maybe("Account Tests", () => { - let optimism: TestData; - let _: TestData; - let __: TestData; - - beforeEach(() => { - // @ts-ignore: Comes from setup-e2e-tests - [_, __, optimism] = testDataPerChain; - }); - - it("should send some native token to a recipient on optimism", async () => { - const { - whale: { viemWallet: signer, publicAddress: sender }, - minnow: { publicAddress: recipient }, - bundlerUrl, - publicClient, - } = optimism; - - const smartAccount = await createSmartAccountClient({ - signer, - bundlerUrl, - }); - - const accountAddress = await smartAccount.getAddress(); - - const balanceOfRecipient = (await checkBalance(publicClient, recipient)) as bigint; - const smartAccountBalance = (await checkBalance(publicClient, accountAddress)) as bigint; - const { wait } = await smartAccount.sendTransaction( - { - to: recipient, - value: BigInt(1), - }, - { - simulationType: "validation_and_execution", - }, - ); - - const result = await wait(); - const newBalanceOfRecipient = (await checkBalance(publicClient, recipient)) as bigint; - - expect(result?.receipt?.transactionHash).toBeTruthy(); - expect(result.success).toBe("true"); - expect(newBalanceOfRecipient).toBeGreaterThan(balanceOfRecipient); - }, 50000); - - it("Create a smart account with paymaster with an api key on optimism", async () => { - const { - whale: { viemWallet: signer }, - bundlerUrl, - biconomyPaymasterApiKey, - } = optimism; - - const smartAccount = await createSmartAccountClient({ - signer, - biconomyPaymasterApiKey, - bundlerUrl, - }); - - const paymaster = smartAccount.paymaster; - expect(paymaster).not.toBeNull(); - expect(paymaster).not.toBeUndefined(); - }); - - it("Should gaslessly mint an NFT on optimism", async () => { - const { - whale: { viemWallet: signer, publicAddress: recipient }, - bundlerUrl, - biconomyPaymasterApiKey, - publicClient, - nftAddress, - } = optimism; - - const smartAccount = await createSmartAccountClient({ - signer, - bundlerUrl, - biconomyPaymasterApiKey, - }); - - const encodedCall = encodeFunctionData({ - abi: parseAbi(["function safeMint(address to) public"]), - functionName: "safeMint", - args: [recipient], - }); - - const transaction = { - to: nftAddress, // NFT address - data: encodedCall, - }; - - const balance = (await checkBalance(publicClient, recipient, nftAddress)) as bigint; - - const maticBalanceBefore = await checkBalance(publicClient, await smartAccount.getAddress()); - - const response = await smartAccount.sendTransaction(transaction, { - paymasterServiceData: { mode: PaymasterMode.SPONSORED }, - simulationType: "validation_and_execution", - }); - - const userOpReceipt = await response.wait(3); - expect(userOpReceipt.userOpHash).toBeTruthy(); - expect(userOpReceipt.success).toBe("true"); - - const maticBalanceAfter = await checkBalance(publicClient, await smartAccount.getAddress()); - - expect(maticBalanceAfter).toEqual(maticBalanceBefore); - - const newBalance = (await checkBalance(publicClient, recipient, nftAddress)) as bigint; - - expect(newBalance - balance).toBe(1n); - }, 50000); -}); diff --git a/packages/account/tests/account.read.e2e.spec.ts b/packages/account/tests/account.read.e2e.spec.ts deleted file mode 100644 index 80abf9d21..000000000 --- a/packages/account/tests/account.read.e2e.spec.ts +++ /dev/null @@ -1,108 +0,0 @@ -import { TestData } from "../../../tests"; -import { createSmartAccountClient } from "../src/index"; -import { DEFAULT_ECDSA_OWNERSHIP_MODULE, DEFAULT_SESSION_KEY_MANAGER_MODULE, createECDSAOwnershipValidationModule } from "@biconomy/modules"; - -describe("Account Tests", () => { - let mumbai: TestData; - - beforeEach(() => { - // @ts-ignore: Comes from setup-e2e-tests - [mumbai] = testDataPerChain; - }); - - it("should check if module is enabled on the smart account", async () => { - const { - whale: { viemWallet: signer }, - bundlerUrl, - } = mumbai; - - const smartWallet = await createSmartAccountClient({ - signer, - bundlerUrl, - }); - - const isEnabled = await smartWallet.isModuleEnabled(DEFAULT_ECDSA_OWNERSHIP_MODULE); - expect(isEnabled).toBeTruthy(); - }, 30000); - - it("should get all modules", async () => { - const { - whale: { - viemWallet: signer, - account: { address: accountAddress }, - }, - bundlerUrl, - biconomyPaymasterApiKey, - } = mumbai; - - const smartAccount = await createSmartAccountClient({ - signer, - bundlerUrl, - biconomyPaymasterApiKey, - }); - - const modules = await smartAccount.getAllModules(); - - expect(modules).toContain(DEFAULT_SESSION_KEY_MANAGER_MODULE); // session manager module - expect(modules).toContain(DEFAULT_ECDSA_OWNERSHIP_MODULE); // ecdsa ownership module - }, 30000); - - it("should get disabled module data", async () => { - const { - whale: { viemWallet: signer }, - bundlerUrl, - } = mumbai; - - const smartWallet = await createSmartAccountClient({ - signer, - bundlerUrl, - }); - - const disableModuleData = await smartWallet.getDisableModuleData(DEFAULT_ECDSA_OWNERSHIP_MODULE, DEFAULT_ECDSA_OWNERSHIP_MODULE); - expect(disableModuleData).toBeTruthy(); - }, 30000); - - it("should get setup and enable module data", async () => { - const { - whale: { viemWallet: signer }, - bundlerUrl, - } = mumbai; - - const smartWallet = await createSmartAccountClient({ - signer, - bundlerUrl, - }); - - const module = await createECDSAOwnershipValidationModule({ signer }); - const initData = await module.getInitData(); - const setupAndEnableModuleData = await smartWallet.getSetupAndEnableModuleData(DEFAULT_ECDSA_OWNERSHIP_MODULE, initData); - expect(setupAndEnableModuleData).toBeTruthy(); - }, 30000); - - it("should read estimated user op gas values", async () => { - const { - whale: { viemWallet: signer }, - bundlerUrl, - } = mumbai; - - const smartWallet = await createSmartAccountClient({ - signer, - bundlerUrl, - }); - - const tx = { - to: "0x000000D50C68705bd6897B2d17c7de32FB519fDA", - data: "0x", - }; - - const userOp = await smartWallet.buildUserOp([tx]); - - const estimatedGas = await smartWallet.estimateUserOpGas(userOp); - expect(estimatedGas.maxFeePerGas).toBeTruthy(); - expect(estimatedGas.maxPriorityFeePerGas).toBeTruthy(); - expect(estimatedGas.verificationGasLimit).toBeTruthy(); - expect(estimatedGas.callGasLimit).toBeTruthy(); - expect(estimatedGas.preVerificationGas).toBeTruthy(); - expect(estimatedGas).toHaveProperty("paymasterAndData", "0x"); - }, 35000); -}); diff --git a/packages/account/tests/account.spec.ts b/packages/account/tests/account.spec.ts deleted file mode 100644 index 42cc90355..000000000 --- a/packages/account/tests/account.spec.ts +++ /dev/null @@ -1,284 +0,0 @@ -import { Bundler, Paymaster, createBundler, createSmartAccountClient } from "../src"; -import { Chain, createWalletClient, http } from "viem"; -import { localhost } from "viem/chains"; -import { privateKeyToAccount, generatePrivateKey } from "viem/accounts"; -import { TestData } from "../../../tests"; -import { JsonRpcProvider } from "@ethersproject/providers"; -import { Wallet } from "@ethersproject/wallet"; -import { getMockBundlerUrl } from "../../../tests/utils"; - -describe("Account Tests", () => { - let ganache: TestData; - const mockBundlerUrl = "https://bundler.biconomy.io/api/v2/1337/nJPK7B3ru.dd7f7861-190d-41bd-af80-6877f74b8f14"; - - beforeEach(() => { - // @ts-ignore: Comes from setup-unit-tests - [ganache] = testDataPerChain; - }); - - it("should create a smartAccountClient from an ethers signer", async () => { - const { - minnow: { ethersSigner: signer }, - } = ganache; - - const smartAccount = await createSmartAccountClient({ - signer, - bundlerUrl: mockBundlerUrl, - rpcUrl: localhost.rpcUrls.default.http[0], - }); - const address = await smartAccount.getAccountAddress(); - expect(address).toBeTruthy(); - }); - - it("should create a whale smartAccountClient from an ethers signer", async () => { - const { - bundlerUrl, - whale: { ethersSigner: signer }, - } = ganache; - - const smartAccount = await createSmartAccountClient({ - signer, - bundlerUrl: mockBundlerUrl, - rpcUrl: localhost.rpcUrls.default.http[0], - }); - const address = await smartAccount.getAccountAddress(); - expect(address).toBeTruthy(); - }); - - it("should create a smartAccountClient from a walletClient", async () => { - const { - whale: { viemWallet: signer }, - } = ganache; - - const smartAccount = await createSmartAccountClient({ - signer, - bundlerUrl: mockBundlerUrl, - rpcUrl: localhost.rpcUrls.default.http[0], - }); - const address = await smartAccount.getAccountAddress(); - expect(address).toBeTruthy(); - }); - - it("should pickup the rpcUrl when a custom chain is used", async () => { - const customBlastChain = { - id: 81_457, - name: "Blast", - // network: "blast", - nativeCurrency: { - decimals: 18, - name: "Ethereum", - symbol: "ETH", - }, - rpcUrls: { - public: { http: ["https://rpc.blast.io"] }, - default: { http: ["https://rpc.blast.io"] }, - }, - blockExplorers: { - etherscan: { name: "Blastscan", url: "https://blastscan.io/" }, - default: { name: "Blastscan", url: "https://blastscan.io/" }, - }, - contracts: { - multicall3: { - address: "0xca11bde05977b3631167028862be2a173976ca11", - blockCreated: 88_189, - }, - }, - } as const satisfies Chain; - - const { - whale: { privateKey }, - } = ganache; - - const accountOne = privateKeyToAccount(privateKey); - - const walletClientWithCustomChain = createWalletClient({ - account: accountOne, - chain: customBlastChain, - transport: http(customBlastChain.rpcUrls.default.http[0]), - }); - - const blastBundler = await createBundler({ - bundlerUrl: getMockBundlerUrl(customBlastChain.id), - viemChain: customBlastChain, - }); - const smartAccountFromViemWithCustomChain = await createSmartAccountClient({ - viemChain: customBlastChain, - signer: walletClientWithCustomChain, - bundler: blastBundler, - rpcUrl: customBlastChain.rpcUrls.default.http[0], - }); - - expect(smartAccountFromViemWithCustomChain.rpcProvider.transport.url).toBe("https://rpc.blast.io"); - expect(blastBundler.getBundlerUrl()).toBe(getMockBundlerUrl(customBlastChain.id)); - }); - - it("should pickup the rpcUrl from viem wallet and ethers", async () => { - const { - chainId, - viemChain, - whale: { privateKey, viemWallet: originalViemSigner, ethersSigner: originalEthersSigner }, - } = ganache; - - const newRpcUrl = "http://localhost:8545"; - const defaultRpcUrl = viemChain.rpcUrls.default.http[0]; //http://127.0.0.1:8545" - - const ethersProvider = new JsonRpcProvider(newRpcUrl); - const ethersSignerWithNewRpcUrl = new Wallet(privateKey, ethersProvider); - - const accountOne = privateKeyToAccount(privateKey); - const walletClientWithNewRpcUrl = createWalletClient({ - account: accountOne, - chain: viemChain, - transport: http(newRpcUrl), - }); - - const [smartAccountFromEthersWithNewRpc, smartAccountFromViemWithNewRpc, smartAccountFromEthersWithOldRpc, smartAccountFromViemWithOldRpc] = - await Promise.all([ - createSmartAccountClient({ - chainId, - signer: ethersSignerWithNewRpcUrl, - bundlerUrl: mockBundlerUrl, - rpcUrl: newRpcUrl, - }), - createSmartAccountClient({ - chainId, - signer: walletClientWithNewRpcUrl, - bundlerUrl: mockBundlerUrl, - rpcUrl: newRpcUrl, - }), - createSmartAccountClient({ - chainId, - signer: originalEthersSigner, - bundlerUrl: mockBundlerUrl, - rpcUrl: viemChain.rpcUrls.default.http[0], - }), - createSmartAccountClient({ - chainId, - signer: originalViemSigner, - bundlerUrl: mockBundlerUrl, - rpcUrl: viemChain.rpcUrls.default.http[0], - }), - ]); - - const [ - smartAccountFromEthersWithNewRpcAddress, - smartAccountFromViemWithNewRpcAddress, - smartAccountFromEthersWithOldRpcAddress, - smartAccountFromViemWithOldRpcAddress, - ] = await Promise.all([ - smartAccountFromEthersWithNewRpc.getAccountAddress(), - smartAccountFromViemWithNewRpc.getAccountAddress(), - smartAccountFromEthersWithOldRpc.getAccountAddress(), - smartAccountFromViemWithOldRpc.getAccountAddress(), - ]); - - expect( - [ - smartAccountFromEthersWithNewRpcAddress, - smartAccountFromViemWithNewRpcAddress, - smartAccountFromEthersWithOldRpcAddress, - smartAccountFromViemWithOldRpcAddress, - ].every(Boolean), - ).toBeTruthy(); - - expect(smartAccountFromEthersWithNewRpc.rpcProvider.transport.url).toBe(newRpcUrl); - expect(smartAccountFromViemWithNewRpc.rpcProvider.transport.url).toBe(newRpcUrl); - expect(smartAccountFromEthersWithOldRpc.rpcProvider.transport.url).toBe(defaultRpcUrl); - expect(smartAccountFromViemWithOldRpc.rpcProvider.transport.url).toBe(defaultRpcUrl); - }); - - it("should create a smartAccountClient from a signer and chainId", async () => { - const { - chainId, - whale: { alchemyWalletClientSigner: signer }, - } = ganache; - - const smartAccount = await createSmartAccountClient({ - chainId, - signer, - bundlerUrl: mockBundlerUrl, - rpcUrl: localhost.rpcUrls.default.http[0], - }); - const address = await smartAccount.getAccountAddress(); - expect(address).toBeTruthy(); - }); - - it("should provide an account address", async () => { - const { - whale: { viemWallet: signer }, - } = ganache; - - const smartAccount = await createSmartAccountClient({ - signer, - bundlerUrl: mockBundlerUrl, - rpcUrl: localhost.rpcUrls.default.http[0], - }); - const address = await smartAccount.getAccountAddress(); - expect(address).toBeTruthy(); - }); - - it("should have an active validation module", async () => { - const { - whale: { viemWallet: signer }, - } = ganache; - - const smartAccount = await createSmartAccountClient({ - signer, - bundlerUrl: mockBundlerUrl, - rpcUrl: localhost.rpcUrls.default.http[0], - }); - - const module = smartAccount.activeValidationModule; - expect(module).toBeTruthy(); - }); - - it("Create a smart account with paymaster by creating instance", async () => { - const { - whale: { viemWallet: signer }, - paymasterUrl, - } = ganache; - - const paymaster = new Paymaster({ paymasterUrl }); - - const smartAccount = await createSmartAccountClient({ - signer, - bundlerUrl: mockBundlerUrl, - paymaster, - rpcUrl: localhost.rpcUrls.default.http[0], - }); - expect(smartAccount.paymaster).not.toBeNull(); - expect(smartAccount.paymaster).not.toBeUndefined(); - }, 10000); - - it("should fail to create a smartAccountClient from a walletClient without a chainId", async () => { - const account = privateKeyToAccount(generatePrivateKey()); - const viemWalletClientNoChainId = createWalletClient({ - account, - transport: http(localhost.rpcUrls.default.http[0]), - }); - - expect( - await expect( - createSmartAccountClient({ - signer: viemWalletClientNoChainId, - bundlerUrl: mockBundlerUrl, - rpcUrl: localhost.rpcUrls.default.http[0], - }), - ).rejects.toThrow("Cannot consume a viem wallet without a chainId"), - ); - }); - - it("should fail to create a smartAccountClient from a walletClient without an account", async () => { - const viemWalletNoAccount = createWalletClient({ - transport: http(localhost.rpcUrls.default.http[0]), - }); - - expect(async () => - createSmartAccountClient({ - signer: viemWalletNoAccount, - bundlerUrl: mockBundlerUrl, - rpcUrl: localhost.rpcUrls.default.http[0], - }), - ).rejects.toThrow("Cannot consume a viem wallet without an account"); - }); -}); diff --git a/packages/account/tests/utils.spec.ts b/packages/account/tests/utils.spec.ts deleted file mode 100644 index d8dfc2a79..000000000 --- a/packages/account/tests/utils.spec.ts +++ /dev/null @@ -1,130 +0,0 @@ -import { BiconomySmartAccountV2Config, ERROR_MESSAGES, createECDSAOwnershipValidationModule } from "../src"; -import { TestData } from "../../../tests"; -import { compareChainIds, getChain } from "../src/utils"; -import { createWalletClient, http } from "viem"; -import { bsc } from "viem/chains"; - -describe("Utils tests", () => { - let ganache: TestData; - - beforeEach(() => { - // @ts-ignore: Comes from setup-unit-tests - [ganache] = testDataPerChain; - }); - - it("Should not throw and error, chain ids match", async () => { - const { - minnow: { viemWallet: walletClient }, - } = ganache; - - const mockBundlerUrl = "https://bundler.biconomy.io/api/v2/1337/nJPK7B3ru.dd7f7861-190d-41bd-af80-6877f74b8f44"; - const mockPaymasterUrl = "https://paymaster.biconomy.io/api/v1/1337/-RObQRX9ei.fc6918eb-c582-4417-9d5a-0507b17cfe71"; - - const config: BiconomySmartAccountV2Config = { - signer: walletClient, - bundlerUrl: mockBundlerUrl, - paymasterUrl: mockPaymasterUrl, - }; - - await expect(compareChainIds(walletClient, config, false)).resolves.not.toThrow(); - }); - - it("Should throw and error, bundlerUrl chain id and signer chain id does not match", async () => { - const { - minnow: { viemWallet: walletClient }, - paymasterUrl, - } = ganache; - - const mockBundlerUrl = "https://bundler.biconomy.io/api/v2/1/nJPK7B3ru.dd7f7861-190d-41bd-af80-6877f74b8f44"; - - const config: BiconomySmartAccountV2Config = { - signer: walletClient, - bundlerUrl: mockBundlerUrl, - paymasterUrl, - }; - - await expect(compareChainIds(walletClient, config, false)).rejects.toThrow(); - }); - - it("Should throw and error, bundlerUrl chain id and paymaster url chain id does not match", async () => { - const { - bundlerUrl, - minnow: { viemWallet: walletClient }, - } = ganache; - - const mockPaymasterUrl = "https://paymaster.biconomy.io/api/v1/80001/-RObQRX9ei.fc6918eb-c582-4417-9d5a-0507b17cfe71"; - - const config: BiconomySmartAccountV2Config = { - signer: walletClient, - bundlerUrl, - paymasterUrl: mockPaymasterUrl, - }; - - await expect(compareChainIds(walletClient, config, false)).rejects.toThrow(); - }); - - it("Should throw and error, bundlerUrl chain id and paymaster url chain id does not match", async () => { - const { - bundlerUrl, - minnow: { viemWallet: walletClient }, - } = ganache; - - const mockPaymasterUrl = "https://paymaster.biconomy.io/api/v1/80001/-RObQRX9ei.fc6918eb-c582-4417-9d5a-0507b17cfe71"; - - const ecdsaModule = await createECDSAOwnershipValidationModule({ - signer: walletClient, - }); - - const config: BiconomySmartAccountV2Config = { - defaultValidationModule: ecdsaModule, - activeValidationModule: ecdsaModule, - bundlerUrl, - paymasterUrl: mockPaymasterUrl, - }; - - await expect(compareChainIds(walletClient, config, false)).rejects.toThrow(); - }); - - it("Should throw and error, signer has chain id (56) and paymasterUrl has chain id (80001)", async () => { - const { bundlerUrl, whale } = ganache; - - const mockPaymasterUrl = "https://paymaster.biconomy.io/api/v1/80001/-RObQRX9ei.fc6918eb-c582-4417-9d5a-0507b17cfe71"; - - const walletClient = createWalletClient({ - account: whale.viemWallet.account, - chain: bsc, - transport: http(bsc.rpcUrls.default.http[0]), - }); - - const config: BiconomySmartAccountV2Config = { - signer: walletClient, - bundlerUrl, - paymasterUrl: mockPaymasterUrl, - }; - - await expect(compareChainIds(walletClient, config, false)).rejects.toThrow(); - }); - - // test chains - it("Should return chain object for chain id 1", () => { - const chainId = 1; - const chain = getChain(chainId); - expect(chain.id).toBe(chainId); - }); - - // should have correct fields - it("Should have correct fields", () => { - const chainId = 1; - const chain = getChain(chainId); - - ["blockExplorers", "contracts", "fees", "formatters", "id", "name", "nativeCurrency", "rpcUrls", "serializers"].every((field) => { - expect(chain).toHaveProperty(field); - }); - }); - - // Should throw an error, chain id not found - it("Should throw an error, chain id not found", () => { - const chainId = 0; - expect(() => getChain(chainId)).toThrow(ERROR_MESSAGES.CHAIN_NOT_FOUND); - }); -}); diff --git a/packages/account/tsconfig.build.json b/packages/account/tsconfig.build.json deleted file mode 100644 index 42d88a236..000000000 --- a/packages/account/tsconfig.build.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "display": "Build", - "compilerOptions": { - "lib": ["es2022", "dom"], - "target": "es2021", - "types": ["node"], - "allowJs": false, - "skipLibCheck": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "module": "esnext", - "moduleResolution": "node", - "resolveJsonModule": true, - "isolatedModules": true, - "verbatimModuleSyntax": false, - "useDefineForClassFields": true, - "noFallthroughCasesInSwitch": true, - "noImplicitReturns": true, - "useUnknownInCatchVariables": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "declaration": true, - "inlineSources": true, - "noEmit": false, - "sourceMap": true - }, - "exclude": ["**/*/node_modules", "**/*/tests", "tests", "tests/**/*"], - "include": ["src"] -} \ No newline at end of file diff --git a/packages/account/tsconfig.json b/packages/account/tsconfig.json deleted file mode 100644 index 53677da37..000000000 --- a/packages/account/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../../tsconfig.settings.json", - "compilerOptions": { - "composite": true, - "outDir": "dist", - "baseUrl": "src", - "resolveJsonModule": true, - "esModuleInterop": true, - "lib": ["es2020"], - "types": ["node"] - }, - "include": ["src", "src/**/*.json"], -} diff --git a/packages/bundler/.esbuild.js b/packages/bundler/.esbuild.js deleted file mode 100644 index ca355e346..000000000 --- a/packages/bundler/.esbuild.js +++ /dev/null @@ -1,58 +0,0 @@ -const esbuildPluginTsc = require("esbuild-plugin-tsc"); -const esbuild = require("esbuild"); -const { dependencies, peerDependencies = {} } = require("./package.json"); -const { Generator } = require("npm-dts"); - -const COMMON_SETTINGS = { - entryPoints: ["src/index.ts"], - minify: true, - bundle: true, - plugins: [esbuildPluginTsc({ force: true })], -}; - -const ESM_SETTINGS = { - ...COMMON_SETTINGS, - sourcemap: true, - outfile: "dist/esm/index.js", - platform: "browser", - target: "esnext", - format: "esm", - mainFields: ["browser", "module", "main"], -}; -const buildForESM = async () => await esbuild.build(ESM_SETTINGS); - -const CJS_SETTINGS = { - ...COMMON_SETTINGS, - format: "cjs", - sourcemap: false, - outfile: "dist/cjs/index.js", - platform: "node", -}; - -const watchForCJS = async () => { - let ctx = await esbuild.context(CJS_SETTINGS); - await ctx.watch(); - await ctx.serve({ servedir: "dist/src" }); - console.log("watching..."); -}; - -const buildForCJS = async () => await esbuild.build(CJS_SETTINGS); -const buildForTYP = async () => await new Generator({ entry: "src/index.ts", output: "dist/types/index.d.ts" }).generate(); - -(async () => { - const buildType = process.argv.slice(2)[0]; - const shouldWatch = process.argv.slice(3)[0] === "--watch"; - if (!buildType) { - console.log("No build type provided"); - process.exit(1); - } - console.log(`Building for ${buildType}`); - if (buildType === "ESM") { - await buildForESM(); - } else if (buildType === "CJS") { - console.log("watching? " + shouldWatch); - await (shouldWatch ? watchForCJS : buildForCJS)(); - } else if (buildType === "TYP") { - await buildForTYP(); - } -})(); diff --git a/packages/bundler/CHANGELOG.md b/packages/bundler/CHANGELOG.md deleted file mode 100644 index 7730bad6b..000000000 --- a/packages/bundler/CHANGELOG.md +++ /dev/null @@ -1,94 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## 4.1.1 (2023-07-03) - -VERSION Bump Only. - -## 4.1.0 (2023-04-03) - -VERSION Bump Only. - -## 4.0.3 (2023-28-02) - -VERSION Bump Only. - -## 4.0.2 (2023-26-02) - -VERSION Bump Only. - -## 4.0.1 (2023-02-22) - -VERSION Bump Only. - -## 4.0.0 (2023-07-02) - -Export createBundler alias for static Bundler.create call - -## 3.1.3 (2023-12-28) - -VERSION Bump Only. - -## 3.1.2 (2023-12-28) - -### Features - -- Make entrypoint address optional in bundler config ([547724a](https://github.com/bcnmy/biconomy-client-sdk/pull/337/commits/547724a15366ee1e63aee80fdee0edc128a84c41)) - -### Bug Fixes - -- use undefined in place of ! + check on limits returned by paymaster and throw ([0376901](https://github.com/bcnmy/biconomy-client-sdk/commit/0376901b7aec8c268a6a3c654d147335974d78f3)) - -## 3.1.1 (2023-11-09) - -### Bug Fixes - -- resolve comments ([34fd6a3](https://github.com/bcnmy/biconomy-client-sdk/commit/34fd6a308805061d9faf408f1ce6da9cac0ee819)) - -### Features - -- add linea mainnet ([c3d1283](https://github.com/bcnmy/biconomy-client-sdk/commit/c3d12832002c18e187f910b5f7dac5ef5b797abf)) -- chain integration ([ddc5d91](https://github.com/bcnmy/biconomy-client-sdk/commit/ddc5d91d5df10a10266f4500644d24e0bc1ea684)) -- chain integration ([738556e](https://github.com/bcnmy/biconomy-client-sdk/commit/738556efcfda70fedc652befc0b35f8835c5e360)) - -## 3.1.0 (2023-09-20) - -Modular Account Abstraction is here. - -### Bug Fixes - -- lint warning and errors ([2135498](https://github.com/bcnmy/biconomy-client-sdk/commit/2135498896beb54d25add820c1521ffa22d5db7c)) -- linting ([563befe](https://github.com/bcnmy/biconomy-client-sdk/commit/563befedcc37aee4c531e01809b47e559a33f526)) -- more lint issues ([10df908](https://github.com/bcnmy/biconomy-client-sdk/commit/10df90821b473fd668907cf3e447dfe3825317fc)) - -### Features - -- base mainnet integration ([c17f5d6](https://github.com/bcnmy/biconomy-client-sdk/commit/c17f5d6c2fe34b106e6d9755f54fab2493db6fbe)) -- chain integration ([ddc5d91](https://github.com/bcnmy/biconomy-client-sdk/commit/ddc5d91d5df10a10266f4500644d24e0bc1ea684)) -- chain integration ([738556e](https://github.com/bcnmy/biconomy-client-sdk/commit/738556efcfda70fedc652befc0b35f8835c5e360)) - -## 3.0.0 (2023-08-28) - -Modular SDK - consists stable version of below updates done in Alphas. - -### Features - -- base mainnet integration ([c17f5d6](https://github.com/bcnmy/biconomy-client-sdk/commit/c17f5d6c2fe34b106e6d9755f54fab2493db6fbe)) - -## 3.0.0-alpha.0 (2023-08-02) - -VERSION Bump Only. - -# 3.1.0-alpha.0 (2023-07-24) - -### Features - -- chain integration ([738556e](https://github.com/bcnmy/biconomy-client-sdk/commit/738556efcfda70fedc652befc0b35f8835c5e360)) - -## 3.0.0-alpha.0 (2023-07-12) - -### Bug Fixes - -- linting ([563befe](https://github.com/bcnmy/biconomy-client-sdk/commit/563befedcc37aee4c531e01809b47e559a33f526)) diff --git a/packages/bundler/Readme.md b/packages/bundler/Readme.md deleted file mode 100644 index 06e0c4af6..000000000 --- a/packages/bundler/Readme.md +++ /dev/null @@ -1,99 +0,0 @@ -### Bundler - -In the context of (ERC4337), A bundler plays a main role in the infrastructure. This concept is integral to the operation of account abstraction across any network that utilizes the Ethereum Virtual Machine (EVM). - -## Installation - -Using `npm` package manager - -```bash -npm i @biconomy/bundler -``` - -OR - -Using `yarn` package manager - -```bash -yarn add @biconomy/bundler -``` - -## configuration - -| Key | Description | -| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -| bundlerUrl | Represent ERC4337 spec implemented bundler url. you can get one from biconomy dashboard. Alternatively you can supply any of your preferred | -| chainId | This represents the network your smart wallet transactions will be conducted on. Take a look following Link for supported chain id's | -| entryPointAddress | Since entrypoint can have different addresses you can call getSupportedEntryPoints() on bundler instance for supported addresses list | - -```typescript -// This is how you create bundler instance in your dapp's -import { IBundler, createBundler } from "@biconomy/bundler"; - -// Make use of core-types package -import { ChainId } from "@biconomy/core-types"; - -const bundler: IBundler = await createBundler({ bundlerUrl: "" }); // you can get this value from biconomy dashboard. https://dashboard.biconomy.io -``` - -Following are the methods that can be call on bundler instance - -```typescript -export interface IBundler { - estimateUserOpGas(userOp: Partial<UserOperation>): Promise<UserOpGasResponse>; - sendUserOp(userOp: UserOperation): Promise<UserOpResponse>; - getUserOpReceipt(userOpHash: string): Promise<UserOpReceipt>; - getUserOpByHash(userOpHash: string): Promise<UserOpByHashResponse>; -} -``` - -**[estimateUserOpGas](https://bcnmy.github.io/biconomy-client-sdk/classes/Bundler.html#estimateUserOpGas)** -Estimate the gas values for a UserOperation. Given UserOperation optionally without gas limits and gas prices, return the needed gas limits. The signature field is ignored by the wallet, so that the operation will not require user's approval. Still, it might require putting a "semi-valid" signature (e.g. a signature in the right length) - -**Return Values** - -**preVerificationGas** gas overhead of this UserOperation -**verificationGasLimit** actual gas used by the validation of this UserOperation -**callGasLimit** limit used to execute userop.callData called from EntryPoint to the Smart Account - - -------------------------------- - -**[sendUserOp](https://bcnmy.github.io/biconomy-client-sdk/classes/Bundler.html#sendUserOp)** -it submits a User Operation object to the User Operation pool of the client. The client MUST validate the UserOperation, and return a result accordingly. - -The result SHOULD be set to the userOpHash if and only if the request passed simulation and was accepted in the client's User Operation pool. If the validation, simulation, or User Operation pool inclusion fails, result SHOULD NOT be returned. Rather, the client SHOULD return the failure reason. - -**Return Values** -If the UserOperation is valid, the client MUST return the calculated userOpHash for it - - -------------------------------- - -**[getUserOpByHash](https://bcnmy.github.io/biconomy-client-sdk/classes/Bundler.html#getUserOpByHash)** -Return a UserOperation based on a hash (userOpHash) returned by sendUserOp (eth_sendUserOperation) - -**Return Values** - -null in case the UserOperation is not yet included in a block, or a full UserOperation, with the addition of entryPoint, blockNumber, blockHash and transactionHash - - -------------------------------- - -**[getUserOpReceipt](https://bcnmy.github.io/biconomy-client-sdk/classes/Bundler.html#getUserOpReceipt)** - -Return a UserOperation receipt based on a hash (userOpHash) returned by eth_sendUserOperation - -**Return Values** -null in case the UserOperation is not yet included in a block, or: - -**userOpHash** the request hash -**entryPoint** -**sender** -**nonce** -**paymaster** the paymaster used for this userOp (or empty) -**actualGasCost** - actual amount paid (by account or paymaster) for this UserOperation -**actualGasUsed** - total gas used by this UserOperation (including preVerification, creation, validation and execution) -**success** boolean - did this execution completed without revert -**reason** in case of revert, this is the revert reason -**logs** the logs generated by this UserOperation (not including logs of other UserOperations in the same bundle) -**receipt** the TransactionReceipt object. Note that the returned TransactionReceipt is for the entire bundle, not only for this UserOperation. - - -------------------------------- diff --git a/packages/bundler/package.json b/packages/bundler/package.json deleted file mode 100644 index a41dde75f..000000000 --- a/packages/bundler/package.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "@biconomy/bundler", - "version": "4.1.1", - "description": "Biconomy Bundler package to interact with any bundler node as per ERC4337 standard", - "main": "./dist/cjs/index.js", - "module": "./dist/esm/index.js", - "types": "./dist/types/index.d.ts", - "typings": "./dist/types/index.d.ts", - "exports": { - ".": { - "import": "./dist/esm/index.js", - "types": "./dist/types/index.d.ts", - "default": "./dist/cjs/index.js" - }, - "./package.json": "./package.json" - }, - "keywords": [ - "Ethereum", - "Bundler", - "Relayer", - "ERC4337", - "Gasless Transaction", - "Biconomy", - "SDK" - ], - "scripts": { - "unbuild": "rimraf dist *.tsbuildinfo", - "build:watch": "yarn build:tsc --watch", - "dist:minify": "esbuild ./dist/esm/**/*.js ./dist/esm/*.js --minify --outdir=./dist/esm --bundle=false --allow-overwrite", - "build": "yarn unbuild && yarn build:tsc", - "build:esbuild": "yarn build:esbuild:cjs && yarn build:esbuild:esm && yarn build:typ", - "build:tsc:cjs": "tsc --project tsconfig.build.json --module commonjs --outDir ./dist/cjs --removeComments --verbatimModuleSyntax false && echo > ./dist/cjs/package.json '{\"type\":\"commonjs\"}'", - "build:tsc:esm": "tsc --project tsconfig.build.json --module esnext --outDir ./dist/esm --removeComments && echo > ./dist/esm/package.json '{\"type\":\"module\"}'", - "build:esbuild:cjs": "node .esbuild.js CJS && echo > ./dist/cjs/package.json '{\"type\":\"commonjs\"}'", - "build:esbuild:esm": "node .esbuild.js ESM && echo > ./dist/esm/package.json '{\"type\":\"module\"}'", - "build:typ": "tsc --project tsconfig.build.json --module esnext --declarationDir ./dist/types --emitDeclarationOnly --declaration --declarationMap", - "build:tsc": "yarn build:tsc:cjs && yarn build:tsc:esm && yarn build:typ && yarn dist:minify", - "test:file": "jest --config=../../jest.config.js --runInBand", - "test:concurrently": "concurrently -k --success first 'yarn start:ganache > /dev/null'", - "test:run": "jest tests/**/*.spec.ts --runInBand", - "start:ganache": "ganache -m 'direct buyer cliff train rice spirit census refuse glare expire innocent quote'", - "format": "prettier --write \"{src,tests}/**/*.ts\"", - "lint": "tslint -p tsconfig.json" - }, - "author": "Biconomy", - "repository": { - "type": "git", - "url": "git+https://github.com/bcnmy/biconomy-client-sdk.git" - }, - "license": "MIT", - "files": [ - "dist/*", - "README.md" - ], - "publishConfig": { - "access": "public" - }, - "dependencies": { - "@alchemy/aa-core": "^3.1.1", - "@biconomy/common": "^4.1.1", - "viem": "^2.7.12" - }, - "devDependencies": { - "@types/node": "^20.11.10", - "esbuild": "^0.19.11", - "esbuild-plugin-tsc": "^0.4.0", - "npm-dts": "^1.3.12" - } -} diff --git a/packages/bundler/src/index.ts b/packages/bundler/src/index.ts deleted file mode 100644 index 7a779f5d5..000000000 --- a/packages/bundler/src/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Bundler } from "./Bundler.js"; - -export * from "./interfaces/IBundler.js"; -export * from "./Bundler.js"; -export * from "./utils/Types.js"; -export * from "./utils/Utils.js"; - -export const createBundler = Bundler.create; diff --git a/packages/bundler/src/interfaces/IBundler.ts b/packages/bundler/src/interfaces/IBundler.ts deleted file mode 100644 index 75077e141..000000000 --- a/packages/bundler/src/interfaces/IBundler.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { StateOverrideSet } from "@biconomy/common"; -import { - UserOpResponse, - UserOpGasResponse, - UserOpReceipt, - UserOpByHashResponse, - UserOpStatus, - SimulationType, - GasFeeValues, -} from "../utils/Types.js"; -import { UserOperationStruct } from "@alchemy/aa-core"; - -export interface IBundler { - estimateUserOpGas(_userOp: Partial<UserOperationStruct>, stateOverrideSet?: StateOverrideSet): Promise<UserOpGasResponse>; - sendUserOp(_userOp: UserOperationStruct, _simulationType?: SimulationType): Promise<UserOpResponse>; - getUserOpReceipt(_userOpHash: string): Promise<UserOpReceipt>; - getUserOpByHash(_userOpHash: string): Promise<UserOpByHashResponse>; - getGasFeeValues(): Promise<GasFeeValues>; - getUserOpStatus(_userOpHash: string): Promise<UserOpStatus>; - getBundlerUrl(): string; -} diff --git a/packages/bundler/src/utils/Utils.ts b/packages/bundler/src/utils/Utils.ts deleted file mode 100644 index 692cf1bdd..000000000 --- a/packages/bundler/src/utils/Utils.ts +++ /dev/null @@ -1,22 +0,0 @@ -export const extractChainIdFromBundlerUrl = (url: string): number => { - try { - const regex = /\/api\/v2\/(\d+)\/[a-zA-Z0-9.-]+$/; - const match = regex.exec(url)!; - return parseInt(match[1]); - } catch (error) { - throw new Error("Invalid chain id"); - } -}; - -export const extractChainIdFromPaymasterUrl = (url: string): number => { - try { - const regex = /\/api\/v\d+\/(\d+)\//; - const match = regex.exec(url); - if (!match) { - throw new Error("Invalid URL format"); - } - return parseInt(match[1]); - } catch (error) { - throw new Error("Invalid chain id"); - } -}; diff --git a/packages/bundler/tests/bundler.e2e.spec.ts b/packages/bundler/tests/bundler.e2e.spec.ts deleted file mode 100644 index 7b9211dd0..000000000 --- a/packages/bundler/tests/bundler.e2e.spec.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { TestData } from "../../../tests"; - -describe("Bundler Unit Tests", () => { - let mumbai: TestData; - let baseSepolia: TestData; - - beforeEach(() => { - // @ts-ignore: Comes from setup-e2e-tests - [mumbai, baseSepolia] = testDataPerChain; - }); - - it("should have chain data for mumbai", () => { - expect(mumbai).toHaveProperty("chainId"); - }); - - it("should also have chain data for base", () => { - expect(baseSepolia).toHaveProperty("chainId"); - }); -}); diff --git a/packages/bundler/tests/bundler.spec.ts b/packages/bundler/tests/bundler.spec.ts deleted file mode 100644 index e663dafb4..000000000 --- a/packages/bundler/tests/bundler.spec.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { TestData } from "../../../tests"; - -describe("Bundler Unit Tests", () => { - let ganache: TestData; - - beforeEach(() => { - // @ts-ignore: Comes from setup-unit-tests - [ganache] = testDataPerChain; - }); - - it("should have chain data for ganache", () => { - expect(ganache).toHaveProperty("chainId"); - }); -}); diff --git a/packages/bundler/tsconfig.build.json b/packages/bundler/tsconfig.build.json deleted file mode 100644 index 4ac8b8026..000000000 --- a/packages/bundler/tsconfig.build.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "display": "Build", - "compilerOptions": { - "lib": ["es2022", "dom"], - "target": "es2021", - "types": ["node"], - "allowJs": false, - "skipLibCheck": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "module": "esnext", - "moduleResolution": "node", - "resolveJsonModule": true, - "isolatedModules": true, - "verbatimModuleSyntax": false, - "useDefineForClassFields": true, - "noFallthroughCasesInSwitch": true, - "noImplicitReturns": true, - "useUnknownInCatchVariables": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "declaration": true, - "inlineSources": true, - "noEmit": false, - "sourceMap": true - }, - "exclude": ["**/*/node_modules", "**/*/tests", "tests"], - "include": ["src"] -} \ No newline at end of file diff --git a/packages/bundler/tsconfig.json b/packages/bundler/tsconfig.json deleted file mode 100644 index d9b305a9a..000000000 --- a/packages/bundler/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../../tsconfig.settings.json", - "compilerOptions": { - "composite": true, - "outDir": "dist", - "baseUrl": "src", - "resolveJsonModule": true, - "esModuleInterop": true, - "lib": ["es2020"], - "types": ["node"] - }, - "include": ["src", "src/**/*.json"] -} diff --git a/packages/common/.esbuild.js b/packages/common/.esbuild.js deleted file mode 100644 index ca355e346..000000000 --- a/packages/common/.esbuild.js +++ /dev/null @@ -1,58 +0,0 @@ -const esbuildPluginTsc = require("esbuild-plugin-tsc"); -const esbuild = require("esbuild"); -const { dependencies, peerDependencies = {} } = require("./package.json"); -const { Generator } = require("npm-dts"); - -const COMMON_SETTINGS = { - entryPoints: ["src/index.ts"], - minify: true, - bundle: true, - plugins: [esbuildPluginTsc({ force: true })], -}; - -const ESM_SETTINGS = { - ...COMMON_SETTINGS, - sourcemap: true, - outfile: "dist/esm/index.js", - platform: "browser", - target: "esnext", - format: "esm", - mainFields: ["browser", "module", "main"], -}; -const buildForESM = async () => await esbuild.build(ESM_SETTINGS); - -const CJS_SETTINGS = { - ...COMMON_SETTINGS, - format: "cjs", - sourcemap: false, - outfile: "dist/cjs/index.js", - platform: "node", -}; - -const watchForCJS = async () => { - let ctx = await esbuild.context(CJS_SETTINGS); - await ctx.watch(); - await ctx.serve({ servedir: "dist/src" }); - console.log("watching..."); -}; - -const buildForCJS = async () => await esbuild.build(CJS_SETTINGS); -const buildForTYP = async () => await new Generator({ entry: "src/index.ts", output: "dist/types/index.d.ts" }).generate(); - -(async () => { - const buildType = process.argv.slice(2)[0]; - const shouldWatch = process.argv.slice(3)[0] === "--watch"; - if (!buildType) { - console.log("No build type provided"); - process.exit(1); - } - console.log(`Building for ${buildType}`); - if (buildType === "ESM") { - await buildForESM(); - } else if (buildType === "CJS") { - console.log("watching? " + shouldWatch); - await (shouldWatch ? watchForCJS : buildForCJS)(); - } else if (buildType === "TYP") { - await buildForTYP(); - } -})(); diff --git a/packages/common/README.md b/packages/common/README.md deleted file mode 100644 index db4c4a8c7..000000000 --- a/packages/common/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# `@biconomy/common` - -common utils - -common methods for other biconomy packages - -## Usage - -``` -no direct usage of this package -``` diff --git a/packages/common/package.json b/packages/common/package.json deleted file mode 100644 index 22010587c..000000000 --- a/packages/common/package.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "name": "@biconomy/common", - "version": "4.1.1", - "description": "common utils to be used for aa transactions", - "keywords": [ - "utils" - ], - "author": "livingrockrises <chirag@biconomy.io>", - "homepage": "https://github.com/bcnmy/biconomy-client-sdk#readme", - "license": "MIT", - "main": "./dist/cjs/index.js", - "module": "./dist/esm/index.js", - "types": "./dist/types/index.d.ts", - "typings": "./dist/types/index.d.ts", - "exports": { - ".": { - "import": "./dist/esm/index.js", - "types": "./dist/types/index.d.ts", - "default": "./dist/cjs/index.js" - }, - "./package.json": "./package.json" - }, - "files": [ - "dist/*", - "README.md" - ], - "publishConfig": { - "access": "public" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/bcnmy/biconomy-client-sdk.git" - }, - "scripts": { - "unbuild": "rimraf dist *.tsbuildinfo", - "build:watch": "yarn build:tsc --watch", - "dist:minify": "esbuild ./dist/esm/**/*.js ./dist/esm/*.js --minify --outdir=./dist/esm --bundle=false --allow-overwrite", - "build": "yarn unbuild && yarn build:tsc", - "build:esbuild": "yarn build:esbuild:cjs && yarn build:esbuild:esm && yarn build:typ", - "build:tsc:cjs": "tsc --project tsconfig.build.json --module commonjs --outDir ./dist/cjs --removeComments --verbatimModuleSyntax false && echo > ./dist/cjs/package.json '{\"type\":\"commonjs\"}'", - "build:tsc:esm": "tsc --project tsconfig.build.json --module esnext --outDir ./dist/esm --removeComments && echo > ./dist/esm/package.json '{\"type\":\"module\"}'", - "build:esbuild:cjs": "node .esbuild.js CJS && echo > ./dist/cjs/package.json '{\"type\":\"commonjs\"}'", - "build:esbuild:esm": "node .esbuild.js ESM && echo > ./dist/esm/package.json '{\"type\":\"module\"}'", - "build:typ": "tsc --project tsconfig.build.json --module esnext --declarationDir ./dist/types --emitDeclarationOnly --declaration --declarationMap", - "build:tsc": "yarn build:tsc:cjs && yarn build:tsc:esm && yarn build:typ && yarn dist:minify", - "test:file": "jest --config=../../jest.config.js --runInBand", - "test:concurrently": "concurrently -k --success first 'yarn start:ganache > /dev/null'", - "test:run": "jest tests/**/*.spec.ts --runInBand", - "start:ganache": "ganache -m 'direct buyer cliff train rice spirit census refuse glare expire innocent quote'", - "format": "prettier --write \"{src,tests}/**/*.ts\"", - "lint": "tslint -p tsconfig.json" - }, - "bugs": { - "url": "https://github.com/bcnmy/biconomy-client-sdk/issues" - }, - "dependencies": { - "@alchemy/aa-core": "^3.1.1", - "@ethersproject/abstract-signer": "^5.7.0", - "viem": "^2.7.12" - }, - "devDependencies": { - "@types/node": "^20.11.10", - "esbuild": "^0.19.11", - "esbuild-plugin-tsc": "^0.4.0", - "npm-dts": "^1.3.12" - } -} diff --git a/packages/common/src/index.ts b/packages/common/src/index.ts deleted file mode 100644 index cca231168..000000000 --- a/packages/common/src/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from "./utils/Helpers/convertSigner.js"; -export * from "./utils/Types.js"; -export * from "./utils/Constants.js"; -export * from "./utils/Logger.js"; -export * from "./utils/HttpRequests.js"; -export { EthersSigner } from "./utils/EthersSigner.js"; diff --git a/packages/common/src/utils/Constants.ts b/packages/common/src/utils/Constants.ts deleted file mode 100644 index 4e3292cb5..000000000 --- a/packages/common/src/utils/Constants.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { SupportedSignerName } from "./Types.js"; - -export const UNIQUE_PROPERTIES_PER_SIGNER: Record<SupportedSignerName, string> = { - alchemy: "signerType", - ethers: "provider", - viem: "transport", -}; diff --git a/packages/common/src/utils/EthersSigner.ts b/packages/common/src/utils/EthersSigner.ts deleted file mode 100644 index d77e0eab1..000000000 --- a/packages/common/src/utils/EthersSigner.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { SmartAccountSigner } from "@alchemy/aa-core"; -import { Hex, SignableMessage } from "viem"; -import { Signer } from "@ethersproject/abstract-signer"; - -export class EthersSigner<T extends Signer> implements SmartAccountSigner<T> { - signerType: string = "ethers"; - - inner: T; - - constructor(inner: T, signerType: string) { - this.inner = inner; - this.signerType = signerType; - } - - async getAddress() { - return (await this.inner.getAddress()) as Hex; - } - - async signMessage(_message: SignableMessage): Promise<Hex> { - const message = typeof _message === "string" ? _message : _message.raw; - const signature = await this.inner?.signMessage(message); - return this.#correctSignature(signature as Hex); - } - - async signTypedData(_notUsed: any): Promise<Hex> { - throw new Error("signTypedData is not supported for Ethers Signer"); - } - - #correctSignature = (signature: Hex): Hex => { - const potentiallyIncorrectV = parseInt(signature.slice(-2), 16); - if (![27, 28].includes(potentiallyIncorrectV)) { - const correctV = potentiallyIncorrectV + 27; - signature = signature.slice(0, -2) + correctV.toString(16); - } - return signature; - }; -} - -export default EthersSigner; diff --git a/packages/common/src/utils/Helpers/convertSigner.ts b/packages/common/src/utils/Helpers/convertSigner.ts deleted file mode 100644 index 5aadb0803..000000000 --- a/packages/common/src/utils/Helpers/convertSigner.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { EthersSigner } from "../EthersSigner.js"; -import { SupportedSigner } from "../Types.js"; -import { WalletClient } from "viem"; -import { WalletClientSigner, SmartAccountSigner } from "@alchemy/aa-core"; -import { UNIQUE_PROPERTIES_PER_SIGNER } from "../Constants.js"; -import { Signer } from "@ethersproject/abstract-signer"; - -interface SmartAccountResult { - signer: SmartAccountSigner; - chainId: number | null; - rpcUrl: string | null; -} - -export const convertSigner = async (signer: SupportedSigner, skipChainIdCalls: boolean = false): Promise<SmartAccountResult> => { - let resolvedSmartAccountSigner: SmartAccountSigner; - let rpcUrl: string | null = null; - let chainId: number | null = null; - const isAnAlchemySigner = UNIQUE_PROPERTIES_PER_SIGNER.alchemy in signer; - const isAnEthersSigner = UNIQUE_PROPERTIES_PER_SIGNER.ethers in signer; - const isAViemSigner = UNIQUE_PROPERTIES_PER_SIGNER.viem in signer; - - if (!isAnAlchemySigner) { - if (isAnEthersSigner) { - const ethersSigner = signer as Signer; - if (!skipChainIdCalls) { - // If chainId not provided, get it from walletClient - if (!ethersSigner.provider) { - throw new Error("Cannot consume an ethers Wallet without a provider"); - } - const chainIdFromProvider = await ethersSigner.provider.getNetwork(); - if (!chainIdFromProvider?.chainId) { - throw new Error("Cannot consume an ethers Wallet without a chainId"); - } - chainId = Number(chainIdFromProvider.chainId); - } - // convert ethers Wallet to alchemy's SmartAccountSigner under the hood - resolvedSmartAccountSigner = new EthersSigner(ethersSigner, "ethers"); - // @ts-ignore - rpcUrl = ethersSigner.provider?.connection?.url ?? null; - } else if (isAViemSigner) { - const walletClient = signer as WalletClient; - if (!walletClient.account) { - throw new Error("Cannot consume a viem wallet without an account"); - } - if (!skipChainIdCalls) { - // If chainId not provided, get it from walletClient - if (!walletClient.chain) { - throw new Error("Cannot consume a viem wallet without a chainId"); - } - chainId = walletClient.chain.id; - } - // convert viems walletClient to alchemy's SmartAccountSigner under the hood - resolvedSmartAccountSigner = new WalletClientSigner(walletClient, "viem"); - rpcUrl = walletClient?.transport?.url ?? null; - } else { - throw new Error("Unsupported signer"); - } - } else { - resolvedSmartAccountSigner = signer as SmartAccountSigner; - } - return { signer: resolvedSmartAccountSigner, rpcUrl, chainId }; -}; diff --git a/packages/common/src/utils/Helpers/index.ts b/packages/common/src/utils/Helpers/index.ts deleted file mode 100644 index 235336dc3..000000000 --- a/packages/common/src/utils/Helpers/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./convertSigner.js"; diff --git a/packages/common/src/utils/HttpRequests.ts b/packages/common/src/utils/HttpRequests.ts deleted file mode 100644 index 192a33e4e..000000000 --- a/packages/common/src/utils/HttpRequests.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Logger } from "./Logger.js"; -import { Service } from "./Types.js"; - -export enum HttpMethod { - Get = "get", - Post = "post", - Delete = "delete", -} - -/* eslint-disable @typescript-eslint/no-explicit-any */ -export interface HttpRequest { - url: string; - method: HttpMethod; - body?: Record<string, any>; -} - -export async function sendRequest<T>({ url, method, body }: HttpRequest, service: Service): Promise<T> { - const response = await fetch(url, { - method, - headers: { - Accept: "application/json", - "Content-Type": "application/json", - }, - body: JSON.stringify(body), - }); - - let jsonResponse; - try { - jsonResponse = await response.json(); - Logger.log(`${service} RPC Response`, jsonResponse); - } catch (error) { - if (!response.ok) { - throw new Error(response.statusText); - } - } - - if (response.ok) { - return jsonResponse as T; - } - if (jsonResponse.error) { - throw new Error(`Error coming from ${service}: ${jsonResponse.error.message}`); - } - if (jsonResponse.message) { - throw new Error(jsonResponse.message); - } - if (jsonResponse.msg) { - throw new Error(jsonResponse.msg); - } - if (jsonResponse.data) { - throw new Error(jsonResponse.data); - } - if (jsonResponse.detail) { - throw new Error(jsonResponse.detail); - } - if (jsonResponse.message) { - throw new Error(jsonResponse.message); - } - if (jsonResponse.nonFieldErrors) { - throw new Error(jsonResponse.nonFieldErrors); - } - if (jsonResponse.delegate) { - throw new Error(jsonResponse.delegate); - } - throw new Error(response.statusText); -} diff --git a/packages/common/src/utils/Types.ts b/packages/common/src/utils/Types.ts deleted file mode 100644 index 52eac0216..000000000 --- a/packages/common/src/utils/Types.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { WalletClient } from "viem"; -import { Signer } from "@ethersproject/abstract-signer"; -import { SmartAccountSigner } from "@alchemy/aa-core"; - -export type SupportedSignerName = "alchemy" | "ethers" | "viem"; -export type SupportedSigner = SmartAccountSigner | WalletClient | Signer | LightSigner; - -export type Service = "Bundler" | "Paymaster"; - -export interface LightSigner { - getAddress(): Promise<string>; - signMessage(message: string | Uint8Array): Promise<string>; -} - -export type StateOverrideSet = { - [key: string]: { - balance?: string; - nonce?: string; - code?: string; - state?: object; - stateDiff?: object; - }; -}; diff --git a/packages/common/tsconfig.build.json b/packages/common/tsconfig.build.json deleted file mode 100644 index 4ac8b8026..000000000 --- a/packages/common/tsconfig.build.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "display": "Build", - "compilerOptions": { - "lib": ["es2022", "dom"], - "target": "es2021", - "types": ["node"], - "allowJs": false, - "skipLibCheck": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "module": "esnext", - "moduleResolution": "node", - "resolveJsonModule": true, - "isolatedModules": true, - "verbatimModuleSyntax": false, - "useDefineForClassFields": true, - "noFallthroughCasesInSwitch": true, - "noImplicitReturns": true, - "useUnknownInCatchVariables": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "declaration": true, - "inlineSources": true, - "noEmit": false, - "sourceMap": true - }, - "exclude": ["**/*/node_modules", "**/*/tests", "tests"], - "include": ["src"] -} \ No newline at end of file diff --git a/packages/common/tsconfig.json b/packages/common/tsconfig.json deleted file mode 100644 index d9b305a9a..000000000 --- a/packages/common/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../../tsconfig.settings.json", - "compilerOptions": { - "composite": true, - "outDir": "dist", - "baseUrl": "src", - "resolveJsonModule": true, - "esModuleInterop": true, - "lib": ["es2020"], - "types": ["node"] - }, - "include": ["src", "src/**/*.json"] -} diff --git a/packages/modules/.esbuild.js b/packages/modules/.esbuild.js deleted file mode 100644 index ca355e346..000000000 --- a/packages/modules/.esbuild.js +++ /dev/null @@ -1,58 +0,0 @@ -const esbuildPluginTsc = require("esbuild-plugin-tsc"); -const esbuild = require("esbuild"); -const { dependencies, peerDependencies = {} } = require("./package.json"); -const { Generator } = require("npm-dts"); - -const COMMON_SETTINGS = { - entryPoints: ["src/index.ts"], - minify: true, - bundle: true, - plugins: [esbuildPluginTsc({ force: true })], -}; - -const ESM_SETTINGS = { - ...COMMON_SETTINGS, - sourcemap: true, - outfile: "dist/esm/index.js", - platform: "browser", - target: "esnext", - format: "esm", - mainFields: ["browser", "module", "main"], -}; -const buildForESM = async () => await esbuild.build(ESM_SETTINGS); - -const CJS_SETTINGS = { - ...COMMON_SETTINGS, - format: "cjs", - sourcemap: false, - outfile: "dist/cjs/index.js", - platform: "node", -}; - -const watchForCJS = async () => { - let ctx = await esbuild.context(CJS_SETTINGS); - await ctx.watch(); - await ctx.serve({ servedir: "dist/src" }); - console.log("watching..."); -}; - -const buildForCJS = async () => await esbuild.build(CJS_SETTINGS); -const buildForTYP = async () => await new Generator({ entry: "src/index.ts", output: "dist/types/index.d.ts" }).generate(); - -(async () => { - const buildType = process.argv.slice(2)[0]; - const shouldWatch = process.argv.slice(3)[0] === "--watch"; - if (!buildType) { - console.log("No build type provided"); - process.exit(1); - } - console.log(`Building for ${buildType}`); - if (buildType === "ESM") { - await buildForESM(); - } else if (buildType === "CJS") { - console.log("watching? " + shouldWatch); - await (shouldWatch ? watchForCJS : buildForCJS)(); - } else if (buildType === "TYP") { - await buildForTYP(); - } -})(); diff --git a/packages/modules/CHANGELOG.md b/packages/modules/CHANGELOG.md deleted file mode 100644 index 7c3d40af8..000000000 --- a/packages/modules/CHANGELOG.md +++ /dev/null @@ -1,64 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## 4.1.1 (2023-07-03) - -VERSION Bump Only. - -## 4.1.0 (2023-04-03) - -VERSION Bump Only. - -## 4.0.3 (2023-28-02) - -VERSION Bump Only. - -## 4.0.2 (2023-26-02) - -VERSION Bump Only. - -## 4.0.1 (2023-02-22) - -VERSION Bump Only. - -## 4.0.0 (2024-02-12) - -### Features - -- Export module create aliases from modules package ([d6205c](https://github.com/bcnmy/biconomy-client-sdk/pull/401/commits/d6205c4d76ab846ecdc10843c65e0277f3ceab00)) - -## 3.1.3 (2023-12-28) - -VERSION Bump Only. - -## 3.1.2 (2023-12-28) - -### Bug Fixes - -- Update import paths for consistency and fixing build issues ([ec5c3a3](https://github.com/bcnmy/biconomy-client-sdk/pull/332/commits/ec5c3a352e8caab6e94234264f4cd5cb32e5af3f)) - -## 3.1.1 (2023-11-09) - -### Bug Fixes - -- Fix update batched session router address and signing logic ([107b881](https://github.com/bcnmy/biconomy-client-sdk/commit/107b881da4b1a6da1f9db22ac54eda62f8c05b59)) - -## 3.1.0 (2023-09-20) - -Modular Account Abstraction is here. - -### Bug Fixes - -- incorrect data merkleRoot length ([2e9d2dd](https://github.com/bcnmy/biconomy-client-sdk/commit/2e9d2dd5876a4de61af390d6595e1ab2cf8c137c)) -- lint warning and errors ([2135498](https://github.com/bcnmy/biconomy-client-sdk/commit/2135498896beb54d25add820c1521ffa22d5db7c)) -- more lint issues ([10df908](https://github.com/bcnmy/biconomy-client-sdk/commit/10df90821b473fd668907cf3e447dfe3825317fc)) -- signing issue ([f67e339](https://github.com/bcnmy/biconomy-client-sdk/commit/f67e339bcff8d9712df8406b4d123affcd4d4aa4)) -- sorting leaves always ([1fb908c](https://github.com/bcnmy/biconomy-client-sdk/commit/1fb908cb3b90abe4588c3a162ecf45c8afc80d81)) -- use hexZeroPad in leaf ([b3da05f](https://github.com/bcnmy/biconomy-client-sdk/commit/b3da05f2e9c56973e96d0a7a3bc065aef23f9c18)) -- use proof instead of root ([3a40a9d](https://github.com/bcnmy/biconomy-client-sdk/commit/3a40a9d8b9fb1fba8f660e5eab1fae1369f9f289)) - -### Features - -- add session key manager ([af41480](https://github.com/bcnmy/biconomy-client-sdk/commit/af41480ff1c88e2a4d0ee8605f2f01b3a958a1d9)) diff --git a/packages/modules/README.md b/packages/modules/README.md deleted file mode 100644 index e69de29bb..000000000 diff --git a/packages/modules/package.json b/packages/modules/package.json deleted file mode 100644 index 7d73de383..000000000 --- a/packages/modules/package.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "name": "@biconomy/modules", - "version": "4.1.1", - "description": "This package provides different validation modules/plugins for ERC4337 compatible modular account", - "main": "./dist/cjs/index.js", - "module": "./dist/esm/index.js", - "types": "./dist/types/index.d.ts", - "typings": "./dist/types/index.d.ts", - "exports": { - ".": { - "import": "./dist/esm/index.js", - "types": "./dist/types/index.d.ts", - "default": "./dist/cjs/index.js" - }, - "./package.json": "./package.json" - }, - "keywords": [ - "Smart Account", - "ERC-4337", - "Account Abstraction", - "Smart Contract Wallets", - "Biconomy", - "Modules", - "Plugins" - ], - "scripts": { - "unbuild": "rimraf dist *.tsbuildinfo", - "build:watch": "yarn build:tsc --watch", - "dist:minify": "esbuild ./dist/esm/**/*.js ./dist/esm/*.js --minify --outdir=./dist/esm --bundle=false --allow-overwrite", - "build": "yarn unbuild && yarn build:tsc", - "build:esbuild": "yarn build:esbuild:cjs && yarn build:esbuild:esm && yarn build:typ", - "build:tsc:cjs": "tsc --project tsconfig.build.json --module commonjs --outDir ./dist/cjs --removeComments --verbatimModuleSyntax false && echo > ./dist/cjs/package.json '{\"type\":\"commonjs\"}'", - "build:tsc:esm": "tsc --project tsconfig.build.json --module esnext --outDir ./dist/esm --removeComments && echo > ./dist/esm/package.json '{\"type\":\"module\"}'", - "build:esbuild:cjs": "node .esbuild.js CJS && echo > ./dist/cjs/package.json '{\"type\":\"commonjs\"}'", - "build:esbuild:esm": "node .esbuild.js ESM && echo > ./dist/esm/package.json '{\"type\":\"module\"}'", - "build:typ": "tsc --project tsconfig.build.json --module esnext --declarationDir ./dist/types --emitDeclarationOnly --declaration --declarationMap", - "build:tsc": "yarn build:tsc:cjs && yarn build:tsc:esm && yarn build:typ && yarn dist:minify", - "test:file": "TS_NODE_PROJECT=../../tsconfig.json mocha -r ts-node/register --timeout 30000", - "test:concurrently": "concurrently -k --success first 'yarn start:ganache > /dev/null'", - "test:cov": "jest --coverage", - "test:run": "yarn test:file tests/**/*.spec.ts", - "start:ganache": "ganache -m 'direct buyer cliff train rice spirit census refuse glare expire innocent quote'", - "format": "prettier --write \"{src,tests}/**/*.ts\"", - "lint": "tslint -p tsconfig.json" - }, - "author": "Biconomy", - "license": "MIT", - "files": [ - "dist/*", - "README.md" - ], - "publishConfig": { - "access": "public" - }, - "dependencies": { - "@alchemy/aa-core": "^3.1.1", - "@biconomy/common": "^4.1.1", - "@ethersproject/abi": "^5.7.0", - "merkletreejs": "^0.3.11", - "viem": "^2.7.12" - }, - "devDependencies": { - "@types/node": "^20.11.10", - "esbuild": "^0.19.11", - "esbuild-plugin-tsc": "^0.4.0", - "npm-dts": "^1.3.12", - "@biconomy/paymaster": "^4.1.1", - "@biconomy/modules": "^4.1.1" - } -} diff --git a/packages/modules/src/BaseValidationModule.ts b/packages/modules/src/BaseValidationModule.ts deleted file mode 100644 index 4f739f782..000000000 --- a/packages/modules/src/BaseValidationModule.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { Hex } from "viem"; -import { SmartAccountSigner } from "@alchemy/aa-core"; -import { BaseValidationModuleConfig, ModuleInfo } from "./utils/Types.js"; -import { DEFAULT_ENTRYPOINT_ADDRESS } from "./utils/Constants.js"; -import { IValidationModule } from "./interfaces/IValidationModule.js"; - -export abstract class BaseValidationModule implements IValidationModule { - entryPointAddress: Hex; - - constructor(moduleConfig: BaseValidationModuleConfig) { - const { entryPointAddress } = moduleConfig; - - this.entryPointAddress = entryPointAddress || DEFAULT_ENTRYPOINT_ADDRESS; - } - - abstract getAddress(): Hex; - - setEntryPointAddress(entryPointAddress: Hex): void { - this.entryPointAddress = entryPointAddress; - } - - abstract getInitData(): Promise<Hex>; - - // Anything required to get dummy signature can be passed as params - abstract getDummySignature(_params?: ModuleInfo): Promise<Hex>; - - abstract getSigner(): Promise<SmartAccountSigner>; - - // Signer specific or any other additional information can be passed as params - abstract signUserOpHash(_userOpHash: string, _params?: ModuleInfo): Promise<Hex>; - - abstract signMessage(_message: Uint8Array | string): Promise<string>; - - async signMessageSmartAccountSigner(_message: string | Uint8Array, signer: SmartAccountSigner): Promise<string> { - const message = typeof _message === "string" ? _message : { raw: _message }; - let signature: `0x${string}` = await signer.signMessage(message); - - const potentiallyIncorrectV = parseInt(signature.slice(-2), 16); - if (![27, 28].includes(potentiallyIncorrectV)) { - const correctV = potentiallyIncorrectV + 27; - signature = `0x${signature.slice(0, -2) + correctV.toString(16)}`; - } - - return signature; - } -} diff --git a/packages/modules/src/BatchedSessionRouterModule.ts b/packages/modules/src/BatchedSessionRouterModule.ts deleted file mode 100644 index cec1cddd4..000000000 --- a/packages/modules/src/BatchedSessionRouterModule.ts +++ /dev/null @@ -1,278 +0,0 @@ -import { ModuleVersion, CreateSessionDataParams, BatchedSessionRouterModuleConfig, ModuleInfo, CreateSessionDataResponse } from "./utils/Types.js"; -import { - BATCHED_SESSION_ROUTER_MODULE_ADDRESSES_BY_VERSION, - DEFAULT_SESSION_KEY_MANAGER_MODULE, - DEFAULT_BATCHED_SESSION_ROUTER_MODULE, -} from "./utils/Constants.js"; -import { BaseValidationModule } from "./BaseValidationModule.js"; -import { SessionKeyManagerModule } from "./SessionKeyManagerModule.js"; -import { SessionSearchParam, SessionStatus } from "./interfaces/ISessionStorage.js"; -import { Hex, concat, encodeAbiParameters, keccak256, pad, parseAbiParameters, toBytes, toHex } from "viem"; -import { SmartAccountSigner } from "@alchemy/aa-core"; -import { convertSigner } from "@biconomy/common"; -import { defaultAbiCoder } from "@ethersproject/abi"; - -export class BatchedSessionRouterModule extends BaseValidationModule { - version: ModuleVersion = "V1_0_0"; - - moduleAddress!: Hex; - - sessionManagerModuleAddress!: Hex; - - sessionKeyManagerModule!: SessionKeyManagerModule; - - readonly mockEcdsaSessionKeySig: Hex = - "0x73c3ac716c487ca34bb858247b5ccf1dc354fbaabdd089af3b2ac8e78ba85a4959a2d76250325bd67c11771c31fccda87c33ceec17cc0de912690521bb95ffcb1b"; - - /** - * This constructor is private. Use the static create method to instantiate SessionKeyManagerModule - * @param moduleConfig The configuration for the module - * @returns An instance of SessionKeyManagerModule - */ - private constructor(moduleConfig: BatchedSessionRouterModuleConfig) { - super(moduleConfig); - } - - /** - * Asynchronously creates and initializes an instance of SessionKeyManagerModule - * @param moduleConfig The configuration for the module - * @returns A Promise that resolves to an instance of SessionKeyManagerModule - */ - public static async create(moduleConfig: BatchedSessionRouterModuleConfig): Promise<BatchedSessionRouterModule> { - const instance = new BatchedSessionRouterModule(moduleConfig); - - if (moduleConfig.moduleAddress) { - instance.moduleAddress = moduleConfig.moduleAddress; - } else if (moduleConfig.version) { - const moduleAddr = BATCHED_SESSION_ROUTER_MODULE_ADDRESSES_BY_VERSION[moduleConfig.version] as Hex; - if (!moduleAddr) { - throw new Error(`Invalid version ${moduleConfig.version}`); - } - instance.moduleAddress = moduleAddr; - instance.version = moduleConfig.version as ModuleVersion; - } else { - instance.moduleAddress = DEFAULT_BATCHED_SESSION_ROUTER_MODULE; - // Note: in this case Version remains the default one - } - - instance.sessionManagerModuleAddress = moduleConfig.sessionManagerModuleAddress ?? DEFAULT_SESSION_KEY_MANAGER_MODULE; - - if (!moduleConfig.sessionKeyManagerModule) { - // generate sessionModule - const sessionModule = await SessionKeyManagerModule.create({ - moduleAddress: instance.sessionManagerModuleAddress, - smartAccountAddress: moduleConfig.smartAccountAddress, - storageType: moduleConfig.storageType, - }); - - instance.sessionKeyManagerModule = sessionModule; - } else { - instance.sessionKeyManagerModule = moduleConfig.sessionKeyManagerModule; - instance.sessionManagerModuleAddress = moduleConfig.sessionKeyManagerModule.getAddress(); - } - - return instance; - } - - /** - * Method to create session data for any module. The session data is used to create a leaf in the merkle tree - * @param leavesData The data of one or more leaves to be used to create session data - * @returns The session data - */ - createSessionData = async (leavesData: CreateSessionDataParams[]): Promise<CreateSessionDataResponse> => { - return this.sessionKeyManagerModule.createSessionData(leavesData); - }; - - /** - * This method is used to sign the user operation using the session signer - * @param userOp The user operation to be signed - * @param sessionParams Information about all the sessions to be used to sign the user operation which has a batch execution - * @returns The signature of the user operation - */ - async signUserOpHash(userOpHash: string, params?: ModuleInfo): Promise<Hex> { - const sessionParams = params?.batchSessionParams; - if (!sessionParams || sessionParams.length === 0) { - throw new Error("Session parameters are not provided"); - } - - const sessionDataTupleArray = []; - - // signer must be the same for all the sessions - const { signer: sessionSigner } = await convertSigner(sessionParams[0].sessionSigner, false); - - const signature = await sessionSigner.signMessage({ raw: toBytes(userOpHash) }); - - for (const sessionParam of sessionParams) { - if (!sessionParam.sessionSigner) { - throw new Error("Session signer is not provided."); - } - - const sessionDataTuple = []; - - let sessionSignerData; - - if (sessionParam.sessionID) { - sessionSignerData = await this.sessionKeyManagerModule.sessionStorageClient.getSessionData({ - sessionID: sessionParam.sessionID, - }); - } else if (sessionParam.sessionValidationModule) { - sessionSignerData = await this.sessionKeyManagerModule.sessionStorageClient.getSessionData({ - sessionValidationModule: sessionParam.sessionValidationModule, - sessionPublicKey: await sessionSigner.getAddress(), - }); - } else { - throw new Error("sessionID or sessionValidationModule should be provided."); - } - - sessionDataTuple.push(sessionSignerData.validUntil); - sessionDataTuple.push(sessionSignerData.validAfter); - sessionDataTuple.push(sessionSignerData.sessionValidationModule); - sessionDataTuple.push(sessionSignerData.sessionKeyData); - - const leafDataHex = concat([ - pad(toHex(sessionSignerData.validUntil), { size: 6 }), - pad(toHex(sessionSignerData.validAfter), { size: 6 }), - pad(sessionSignerData.sessionValidationModule, { size: 20 }), - sessionSignerData.sessionKeyData, - ]); - - const proof = this.sessionKeyManagerModule.merkleTree.getHexProof(keccak256(leafDataHex)); - - sessionDataTuple.push(proof); - sessionDataTuple.push(sessionParam.additionalSessionData ?? "0x"); - - sessionDataTupleArray.push(sessionDataTuple); - } - - // Generate the padded signature - - const paddedSignature = defaultAbiCoder.encode( - ["address", "tuple(uint48,uint48,address,bytes,bytes32[],bytes)[]", "bytes"], - [this.getSessionKeyManagerAddress(), sessionDataTupleArray, signature], - ); - - return paddedSignature as Hex; - } - - /** - * Update the session data pending state to active - * @param param The search param to find the session data - * @param status The status to be updated - * @returns - */ - async updateSessionStatus(param: SessionSearchParam, status: SessionStatus): Promise<void> { - this.sessionKeyManagerModule.sessionStorageClient.updateSessionStatus(param, status); - } - - /** - * @remarks This method is used to clear all the pending sessions - * @returns - */ - async clearPendingSessions(): Promise<void> { - this.sessionKeyManagerModule.sessionStorageClient.clearPendingSessions(); - } - - /** - * @returns SessionKeyManagerModule address - */ - getAddress(): Hex { - return this.moduleAddress; - } - - /** - * @returns SessionKeyManagerModule address - */ - getSessionKeyManagerAddress(): Hex { - return this.sessionManagerModuleAddress; - } - - /** - * @remarks This is the version of the module contract - */ - async getSigner(): Promise<SmartAccountSigner> { - throw new Error("Method not implemented."); - } - - /** - * @remarks This is the dummy signature for the module, used in buildUserOp for bundler estimation - * @returns Dummy signature - */ - async getDummySignature(params?: ModuleInfo): Promise<Hex> { - const sessionParams = params?.batchSessionParams; - if (!sessionParams || sessionParams.length === 0) { - throw new Error("Session parameters are not provided"); - } - - const sessionDataTupleArray = []; - - // if needed we could do mock signature over userOpHashAndModuleAddress - - // signer must be the same for all the sessions - const { signer: sessionSigner } = await convertSigner(sessionParams[0].sessionSigner, false); - - for (const sessionParam of sessionParams) { - if (!sessionParam.sessionSigner) { - throw new Error("Session signer is not provided."); - } - - const sessionDataTuple = []; - - let sessionSignerData; - - if (sessionParam.sessionID) { - sessionSignerData = await this.sessionKeyManagerModule.sessionStorageClient.getSessionData({ - sessionID: sessionParam.sessionID, - }); - } else if (sessionParam.sessionValidationModule) { - sessionSignerData = await this.sessionKeyManagerModule.sessionStorageClient.getSessionData({ - sessionValidationModule: sessionParam.sessionValidationModule, - sessionPublicKey: await sessionSigner.getAddress(), - }); - } else { - throw new Error("sessionID or sessionValidationModule should be provided."); - } - - sessionDataTuple.push(BigInt(sessionSignerData.validUntil)); - sessionDataTuple.push(BigInt(sessionSignerData.validAfter)); - sessionDataTuple.push(sessionSignerData.sessionValidationModule); - sessionDataTuple.push(sessionSignerData.sessionKeyData); - - const leafDataHex = concat([ - pad(toHex(sessionSignerData.validUntil), { size: 6 }), - pad(toHex(sessionSignerData.validAfter), { size: 6 }), - pad(sessionSignerData.sessionValidationModule, { size: 20 }), - sessionSignerData.sessionKeyData, - ]); - - const proof = this.sessionKeyManagerModule.merkleTree.getHexProof(keccak256(leafDataHex)); - - sessionDataTuple.push(proof); - sessionDataTuple.push(sessionParam.additionalSessionData ?? "0x"); - - sessionDataTupleArray.push(sessionDataTuple); - } - - // Generate the padded signature - const paddedSignature = defaultAbiCoder.encode( - ["address", "tuple(uint48,uint48,address,bytes,bytes32[],bytes)[]", "bytes"], - [this.getSessionKeyManagerAddress(), sessionDataTupleArray, this.mockEcdsaSessionKeySig], - ); - - const dummySig = encodeAbiParameters(parseAbiParameters("bytes, address"), [paddedSignature as Hex, this.getAddress()]); - return dummySig; - } - - /** - * @remarks Other modules may need additional attributes to build init data - */ - async getInitData(): Promise<Hex> { - throw new Error("Method not implemented."); - } - - /** - * @remarks This Module dont have knowledge of signer. So, this method is not implemented - */ - async signMessage(_message: Uint8Array | string): Promise<string> { - throw new Error("Method not implemented."); - } -} diff --git a/packages/modules/src/MultichainValidationModule.ts b/packages/modules/src/MultichainValidationModule.ts deleted file mode 100644 index 0846b0f83..000000000 --- a/packages/modules/src/MultichainValidationModule.ts +++ /dev/null @@ -1,163 +0,0 @@ -import { Hex, concat, encodeAbiParameters, encodeFunctionData, getAddress, keccak256, pad, parseAbi, parseAbiParameters, toBytes, toHex } from "viem"; -import { UserOperationStruct, SmartAccountSigner } from "@alchemy/aa-core"; -import { MerkleTree } from "merkletreejs"; -import { DEFAULT_MULTICHAIN_MODULE, MULTICHAIN_VALIDATION_MODULE_ADDRESSES_BY_VERSION } from "./utils/Constants.js"; -import { - ModuleVersion, - MultiChainUserOpDto, - MultiChainValidationModuleConfig, - MultiChainValidationModuleConfigConstructorProps, -} from "./utils/Types.js"; -import { BaseValidationModule } from "./BaseValidationModule.js"; -import { getUserOpHash } from "./utils/Helper.js"; -import { convertSigner, Logger } from "@biconomy/common"; - -export class MultiChainValidationModule extends BaseValidationModule { - signer: SmartAccountSigner; - - moduleAddress!: Hex; - - version: ModuleVersion = "V1_0_0"; - - private constructor(moduleConfig: MultiChainValidationModuleConfigConstructorProps) { - super(moduleConfig); - this.signer = moduleConfig.signer; - } - - public static async create(moduleConfig: MultiChainValidationModuleConfig): Promise<MultiChainValidationModule> { - // Signer needs to be initialised here before defaultValidationModule is set - const { signer } = await convertSigner(moduleConfig.signer, false); - const configForConstructor: MultiChainValidationModuleConfigConstructorProps = { ...moduleConfig, signer }; - - // TODO: (Joe) stop doing things in a 'create' call after the instance has been created - const instance = new MultiChainValidationModule(configForConstructor); - if (moduleConfig.moduleAddress) { - instance.moduleAddress = moduleConfig.moduleAddress; - } else if (moduleConfig.version) { - const moduleAddr = MULTICHAIN_VALIDATION_MODULE_ADDRESSES_BY_VERSION[moduleConfig.version] as Hex; - if (!moduleAddr) { - throw new Error(`Invalid version ${moduleConfig.version}`); - } - instance.moduleAddress = moduleAddr; - instance.version = moduleConfig.version as ModuleVersion; - } else { - instance.moduleAddress = DEFAULT_MULTICHAIN_MODULE; - // Note: in this case Version remains the default one - } - return instance; - } - - getAddress(): Hex { - return this.moduleAddress; - } - - async getSigner(): Promise<SmartAccountSigner> { - return Promise.resolve(this.signer); - } - - async getDummySignature(): Promise<Hex> { - const moduleAddress = getAddress(this.getAddress()); - const dynamicPart = moduleAddress.substring(2).padEnd(40, "0"); - return `0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000${dynamicPart}000000000000000000000000000000000000000000000000000000000000004181d4b4981670cb18f99f0b4a66446df1bf5b204d24cfcb659bf38ba27a4359b5711649ec2423c5e1247245eba2964679b6a1dbb85c992ae40b9b00c6935b02ff1b00000000000000000000000000000000000000000000000000000000000000`; - } - - // Note: other modules may need additional attributes to build init data - async getInitData(): Promise<Hex> { - const ecdsaOwnerAddress = await this.signer.getAddress(); - const moduleRegistryParsedAbi = parseAbi(["function initForSmartAccount(address owner)"]); - const ecdsaOwnershipInitData = encodeFunctionData({ - abi: moduleRegistryParsedAbi, - functionName: "initForSmartAccount", - args: [ecdsaOwnerAddress], - }); - return ecdsaOwnershipInitData; - } - - async signUserOpHash(userOpHash: string): Promise<Hex> { - const sig = await this.signer.signMessage({ raw: toBytes(userOpHash) }); - return sig; - } - - /** - * Signs a message using the appropriate method based on the type of signer. - * - * @param {Uint8Array | string} message - The message to be signed. - * @returns {Promise<string>} A promise resolving to the signature or error message. - * @throws {Error} If the signer type is invalid or unsupported. - */ - async signMessage(_message: Uint8Array | string): Promise<string> { - const message = typeof _message === "string" ? _message : { raw: _message }; - let signature = await this.signer.signMessage(message); - - const potentiallyIncorrectV = parseInt(signature.slice(-2), 16); - if (![27, 28].includes(potentiallyIncorrectV)) { - const correctV = potentiallyIncorrectV + 27; - signature = signature.slice(0, -2) + correctV.toString(16); - } - return signature; - } - - async signUserOps(multiChainUserOps: MultiChainUserOpDto[]): Promise<UserOperationStruct[]> { - try { - const leaves: string[] = []; - - // Iterate over each userOp and process them - for (const multiChainOp of multiChainUserOps) { - const validUntil = multiChainOp.validUntil ?? 0; - const validAfter = multiChainOp.validAfter ?? 0; - const leaf = concat([ - pad(toHex(validUntil), { size: 6 }), - pad(toHex(validAfter), { size: 6 }), - pad(getUserOpHash(multiChainOp.userOp, this.entryPointAddress, multiChainOp.chainId), { size: 32 }), - ]); - - leaves.push(keccak256(leaf)); - } - - // Create a new Merkle tree using the leaves array - const merkleTree = new MerkleTree(leaves, keccak256, { sortPairs: true }); - - let multichainSignature = await this.signer.signMessage({ raw: toBytes(merkleTree.getHexRoot()) }); - - const potentiallyIncorrectV = parseInt(multichainSignature.slice(-2), 16); - if (![27, 28].includes(potentiallyIncorrectV)) { - const correctV = potentiallyIncorrectV + 27; - multichainSignature = multichainSignature.slice(0, -2) + correctV.toString(16); - } - - // Create an array to store updated userOps - const updatedUserOps: UserOperationStruct[] = []; - - for (let i = 0; i < leaves.length; i++) { - const merkleProof = merkleTree.getHexProof(leaves[i]); - - const validUntil = multiChainUserOps[i].validUntil ?? 0; - const validAfter = multiChainUserOps[i].validAfter ?? 0; - - // Create the moduleSignature - const moduleSignature = encodeAbiParameters(parseAbiParameters(["uint48, uint48, bytes32, bytes32[], bytes"]), [ - validUntil, - validAfter, - merkleTree.getHexRoot() as Hex, - merkleProof as Hex[], - multichainSignature as Hex, - ]); - - // Note: Because accountV2 does not directly call this method. hence we need to add validation module address to the signature - const signatureWithModuleAddress = encodeAbiParameters(parseAbiParameters(["bytes, address"]), [moduleSignature, this.getAddress()]); - - // Update userOp with the final signature - const updatedUserOp: UserOperationStruct = { - ...(multiChainUserOps[i].userOp as UserOperationStruct), - signature: signatureWithModuleAddress as `0x${string}`, - }; - - updatedUserOps.push(updatedUserOp); - } - return updatedUserOps; - } catch (error) { - Logger.error("Error in signing multi chain userops"); - throw new Error(JSON.stringify(error)); - } - } -} diff --git a/packages/modules/src/index.ts b/packages/modules/src/index.ts deleted file mode 100644 index ca954778b..000000000 --- a/packages/modules/src/index.ts +++ /dev/null @@ -1,26 +0,0 @@ -export * from "./utils/Types.js"; -export * from "./utils/Constants.js"; -export * from "./interfaces/IValidationModule.js"; -export * from "./interfaces/ISessionValidationModule.js"; -export * from "./BaseValidationModule.js"; -export * from "./ECDSAOwnershipValidationModule.js"; -export * from "./MultichainValidationModule.js"; -export * from "./SessionKeyManagerModule.js"; -export * from "./BatchedSessionRouterModule.js"; -export * from "./session-validation-modules/ERC20SessionValidationModule.js"; - -import { - BatchedSessionRouterModule, - ECDSAOwnershipValidationModule, - MultiChainValidationModule, - SessionKeyManagerModule, - ERC20SessionValidationModule, -} from "./index.js"; - -export const createBatchedSessionRouterModule = BatchedSessionRouterModule.create; -export const createMultiChainValidationModule = MultiChainValidationModule.create; -export const createECDSAOwnershipValidationModule = ECDSAOwnershipValidationModule.create; -export const createSessionKeyManagerModule = SessionKeyManagerModule.create; -export const createERC20SessionValidationModule = ERC20SessionValidationModule.create; - -// export * from './PasskeyValidationModule' diff --git a/packages/modules/src/interfaces/IValidationModule.ts b/packages/modules/src/interfaces/IValidationModule.ts deleted file mode 100644 index ee3da28a9..000000000 --- a/packages/modules/src/interfaces/IValidationModule.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { SmartAccountSigner } from "@alchemy/aa-core"; -import { Hex } from "viem"; - -export interface IValidationModule { - getAddress(): Hex; - getInitData(): Promise<Hex>; - getSigner(): Promise<SmartAccountSigner>; - signUserOpHash(_userOpHash: string): Promise<Hex>; - signMessage(_message: string | Uint8Array): Promise<string>; - getDummySignature(): Promise<Hex>; -} diff --git a/packages/modules/src/session-storage/SessionLocalStorage.ts b/packages/modules/src/session-storage/SessionLocalStorage.ts deleted file mode 100644 index 97a1d6953..000000000 --- a/packages/modules/src/session-storage/SessionLocalStorage.ts +++ /dev/null @@ -1,179 +0,0 @@ -import { Hex, createWalletClient, http, toHex } from "viem"; -import { SmartAccountSigner, WalletClientSigner } from "@alchemy/aa-core"; -import { ISessionStorage, SessionLeafNode, SessionSearchParam, SessionStatus } from "../interfaces/ISessionStorage.js"; -import { mainnet } from "viem/chains"; -import { generatePrivateKey, privateKeyToAccount } from "viem/accounts"; -import { SignerData } from "../utils/Types.js"; - -export class SessionLocalStorage implements ISessionStorage { - private smartAccountAddress: string; - - constructor(smartAccountAddress: string) { - this.smartAccountAddress = smartAccountAddress.toLowerCase(); - } - - private validateSearchParam(param: SessionSearchParam): void { - if (param.sessionID) { - return; - } else if (!param.sessionID && param.sessionPublicKey && param.sessionValidationModule) { - return; - } else { - throw new Error("Either pass sessionId or a combination of sessionPublicKey and sessionValidationModule address."); - } - } - - private getSessionStore(): any { - // @ts-ignore: LocalStorage is not available in node - const data = localStorage.getItem(this.getStorageKey("sessions")); - return data ? JSON.parse(data) : { merkleRoot: "", leafNodes: [] }; - } - - private getSignerStore(): any { - // @ts-ignore: LocalStorage is not available in node - const data = localStorage.getItem(this.getStorageKey("signers")); - return data ? JSON.parse(data) : {}; - } - - private getStorageKey(type: "sessions" | "signers"): string { - return `${this.smartAccountAddress}_${type}`; - } - - private toLowercaseAddress(address: string): string { - return address.toLowerCase(); - } - - async addSessionData(leaf: SessionLeafNode): Promise<void> { - const data = this.getSessionStore(); - leaf.sessionValidationModule = this.toLowercaseAddress(leaf.sessionValidationModule) as Hex; - leaf.sessionPublicKey = this.toLowercaseAddress(leaf.sessionPublicKey) as Hex; - data.leafNodes.push(leaf); - // @ts-ignore: LocalStorage is not available in node - localStorage.setItem(this.getStorageKey("sessions"), JSON.stringify(data)); - } - - async getSessionData(param: SessionSearchParam): Promise<SessionLeafNode> { - this.validateSearchParam(param); - - const sessions = this.getSessionStore().leafNodes; - const session = sessions.find((s: SessionLeafNode) => { - if (param.sessionID) { - return s.sessionID === param.sessionID && (!param.status || s.status === param.status); - } else if (param.sessionPublicKey && param.sessionValidationModule) { - return ( - s.sessionPublicKey === this.toLowercaseAddress(param.sessionPublicKey) && - s.sessionValidationModule === this.toLowercaseAddress(param.sessionValidationModule) && - (!param.status || s.status === param.status) - ); - } else { - return undefined; - } - }); - - if (!session) { - throw new Error("Session not found."); - } - return session; - } - - async updateSessionStatus(param: SessionSearchParam, status: SessionStatus): Promise<void> { - this.validateSearchParam(param); - - const data = this.getSessionStore(); - const session = data.leafNodes.find((s: SessionLeafNode) => { - if (param.sessionID) { - return s.sessionID === param.sessionID; - } else if (param.sessionPublicKey && param.sessionValidationModule) { - return ( - s.sessionPublicKey === this.toLowercaseAddress(param.sessionPublicKey) && - s.sessionValidationModule === this.toLowercaseAddress(param.sessionValidationModule) - ); - } else { - return undefined; - } - }); - - if (!session) { - throw new Error("Session not found."); - } - - session.status = status; - // @ts-ignore: LocalStorage is not available in node - localStorage.setItem(this.getStorageKey("sessions"), JSON.stringify(data)); - } - - async clearPendingSessions(): Promise<void> { - const data = this.getSessionStore(); - data.leafNodes = data.leafNodes.filter((s: SessionLeafNode) => s.status !== "PENDING"); - // @ts-ignore: LocalStorage is not available in node - localStorage.setItem(this.getStorageKey("sessions"), JSON.stringify(data)); - } - - async addSigner(signerData: SignerData): Promise<SmartAccountSigner> { - const signers = this.getSignerStore(); - let signer: SignerData; - if (!signerData) { - const pkey = generatePrivateKey(); - signer = { - pvKey: pkey, - pbKey: privateKeyToAccount(pkey).publicKey, - }; - } else { - signer = signerData; - } - const accountSigner = privateKeyToAccount(toHex(signer.pvKey)); - const client = createWalletClient({ - account: accountSigner, - chain: signerData.chainId, - transport: http(), - }); - const walletClientSigner = new WalletClientSigner( - client, - "json-rpc", // signerType - ); - signers[this.toLowercaseAddress(accountSigner.address)] = signerData; - // @ts-ignore: LocalStorage is not available in node - localStorage.setItem(this.getStorageKey("signers"), JSON.stringify(signers)); - return walletClientSigner; - } - - async getSignerByKey(sessionPublicKey: string): Promise<SmartAccountSigner> { - const signers = this.getSignerStore(); - const signerData = signers[this.toLowercaseAddress(sessionPublicKey)]; - if (!signerData) { - throw new Error("Signer not found."); - } - const account = privateKeyToAccount(signerData.privateKey); - const client = createWalletClient({ - account, - chain: mainnet, - transport: http(), - }); - const signer = new WalletClientSigner(client, "viem"); - return signer; - } - - async getSignerBySession(param: SessionSearchParam): Promise<SmartAccountSigner> { - const session = await this.getSessionData(param); - return this.getSignerByKey(session.sessionPublicKey); - } - - async getAllSessionData(param?: SessionSearchParam): Promise<SessionLeafNode[]> { - const sessions = this.getSessionStore().leafNodes; - if (!param || !param.status) { - return sessions; - } - return sessions.filter((s: SessionLeafNode) => s.status === param.status); - } - - async getMerkleRoot(): Promise<string> { - return this.getSessionStore().merkleRoot; - } - - setMerkleRoot(merkleRoot: string): Promise<void> { - const data = this.getSessionStore(); - data.merkleRoot = merkleRoot; - // @ts-ignore: LocalStorage is not available in node - localStorage.setItem(this.getStorageKey("sessions"), JSON.stringify(data)); - return Promise.resolve(); - } -} diff --git a/packages/modules/src/utils/Constants.ts b/packages/modules/src/utils/Constants.ts deleted file mode 100644 index 7a2a308fa..000000000 --- a/packages/modules/src/utils/Constants.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { ModuleVersion } from "./Types.js"; - -export const DEFAULT_MODULE_VERSION: ModuleVersion = "V1_0_0"; - -export const DEFAULT_ENTRYPOINT_ADDRESS = "0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789"; -export const ENTRYPOINT_ADDRESSES = { - "0x27a4db290b89ae3373ce4313cbeae72112ae7da9": "V0_0_5", - "0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789": "V0_0_6", -}; - -export const ENTRYPOINT_ADDRESSES_BY_VERSION = { - V0_0_5: "0x27a4db290b89ae3373ce4313cbeae72112ae7da9", - V0_0_6: "0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789", -}; - -// Note: we could append these defaults with ADDRESS suffix -export const DEFAULT_ECDSA_OWNERSHIP_MODULE = "0x0000001c5b32F37F5beA87BDD5374eB2aC54eA8e"; - -export const ECDSA_OWNERSHIP_MODULE_ADDRESSES_BY_VERSION = { - V1_0_0: "0x0000001c5b32F37F5beA87BDD5374eB2aC54eA8e", -}; - -export const DEFAULT_SESSION_KEY_MANAGER_MODULE = "0x000002FbFfedd9B33F4E7156F2DE8D48945E7489"; - -export const SESSION_MANAGER_MODULE_ADDRESSES_BY_VERSION = { - V1_0_0: "0x000000456b395c4e107e0302553B90D1eF4a32e9", - V1_0_1: "0x000002FbFfedd9B33F4E7156F2DE8D48945E7489", -}; - -export const DEFAULT_BATCHED_SESSION_ROUTER_MODULE = "0x00000D09967410f8C76752A104c9848b57ebba55"; - -export const BATCHED_SESSION_ROUTER_MODULE_ADDRESSES_BY_VERSION = { - V1_0_0: "0x00000D09967410f8C76752A104c9848b57ebba55", -}; - -export const DEFAULT_ERC20_MODULE = "0x000000D50C68705bd6897B2d17c7de32FB519fDA"; - -export const DEFAULT_MULTICHAIN_MODULE = "0x000000824dc138db84FD9109fc154bdad332Aa8E"; - -export const MULTICHAIN_VALIDATION_MODULE_ADDRESSES_BY_VERSION = { - V1_0_0: "0x000000824dc138db84FD9109fc154bdad332Aa8E", -}; - -// similarly others here or in module / signer classes -// Mapping / Reverse mapping of version -> module address can be kept here - -export const ERC20_ABI = [ - "function transfer(address to, uint256 value) external returns (bool)", - "function transferFrom(address from, address to, uint256 value) external returns (bool)", - "function approve(address spender, uint256 value) external returns (bool)", - "function allowance(address owner, address spender) external view returns (uint256)", - "function balanceOf(address owner) external view returns (uint256)", -]; diff --git a/packages/modules/src/utils/Helper.ts b/packages/modules/src/utils/Helper.ts deleted file mode 100644 index b0b6fc43d..000000000 --- a/packages/modules/src/utils/Helper.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { UserOperationStruct } from "@alchemy/aa-core"; -import { Hex, encodeAbiParameters, keccak256, parseAbiParameters, concat, pad, toHex } from "viem"; - -export interface Rule { - offset: number; - condition: number; - referenceValue: `0x${string}`; -} - -export interface Permission { - destContract: `0x${string}`; - functionSelector: `0x${string}`; - valueLimit: bigint; - rules: Rule[]; -} - -function packUserOp(op: Partial<UserOperationStruct>, forSignature = true): string { - if (!op.initCode || !op.callData || !op.paymasterAndData) throw new Error("Missing userOp properties"); - if (forSignature) { - return encodeAbiParameters(parseAbiParameters("address, uint256, bytes32, bytes32, uint256, uint256, uint256, uint256, uint256, bytes32"), [ - op.sender as Hex, - BigInt(op.nonce as Hex), - keccak256(op.initCode as Hex), - keccak256(op.callData as Hex), - BigInt(op.callGasLimit as Hex), - BigInt(op.verificationGasLimit as Hex), - BigInt(op.preVerificationGas as Hex), - BigInt(op.maxFeePerGas as Hex), - BigInt(op.maxPriorityFeePerGas as Hex), - keccak256(op.paymasterAndData as Hex), - ]); - } else { - // for the purpose of calculating gas cost encode also signature (and no keccak of bytes) - return encodeAbiParameters(parseAbiParameters("address, uint256, bytes, bytes, uint256, uint256, uint256, uint256, uint256, bytes, bytes"), [ - op.sender as Hex, - BigInt(op.nonce as Hex), - op.initCode as Hex, - op.callData as Hex, - BigInt(op.callGasLimit as Hex), - BigInt(op.verificationGasLimit as Hex), - BigInt(op.preVerificationGas as Hex), - BigInt(op.maxFeePerGas as Hex), - BigInt(op.maxPriorityFeePerGas as Hex), - op.paymasterAndData as Hex, - op.signature as Hex, - ]); - } -} - -export const getUserOpHash = (userOp: Partial<UserOperationStruct>, entryPointAddress: Hex, chainId: number): Hex => { - const userOpHash = keccak256(packUserOp(userOp, true) as Hex); - const enc = encodeAbiParameters(parseAbiParameters("bytes32, address, uint256"), [userOpHash, entryPointAddress, BigInt(chainId)]); - return keccak256(enc); -}; - -export async function getABISVMSessionKeyData(sessionKey: `0x${string}` | Uint8Array, permission: Permission): Promise<`0x${string}` | Uint8Array> { - let sessionKeyData = concat([ - sessionKey, - permission.destContract, - permission.functionSelector, - pad(toHex(permission.valueLimit), { size: 16 }), - pad(toHex(permission.rules.length), { size: 2 }), // this can't be more 2**11 (see below), so uint16 (2 bytes) is enough - ]) as `0x${string}`; - - for (let i = 0; i < permission.rules.length; i++) { - sessionKeyData = concat([ - sessionKeyData, - pad(toHex(permission.rules[i].offset), { size: 2 }), // offset is uint16, so there can't be more than 2**16/32 args = 2**11 - pad(toHex(permission.rules[i].condition), { size: 1 }), // uint8 - permission.rules[i].referenceValue, - ]); - } - return sessionKeyData; -} diff --git a/packages/modules/tests/batchedSessionValidationModule.e2e.spec.ts b/packages/modules/tests/batchedSessionValidationModule.e2e.spec.ts deleted file mode 100644 index 47f542e54..000000000 --- a/packages/modules/tests/batchedSessionValidationModule.e2e.spec.ts +++ /dev/null @@ -1,214 +0,0 @@ -import { - DEFAULT_BATCHED_SESSION_ROUTER_MODULE, - DEFAULT_SESSION_KEY_MANAGER_MODULE, - createBatchedSessionRouterModule, - createSessionKeyManagerModule, -} from "@biconomy/modules"; -import { SessionFileStorage } from "./utils/customSession"; -import { WalletClientSigner, createSmartAccountClient } from "../../account/src/index"; -import { encodeAbiParameters, encodeFunctionData, parseAbi, parseUnits } from "viem"; -import { TestData } from "../../../tests"; -import { checkBalance } from "../../../tests/utils"; -import { PaymasterMode } from "@biconomy/paymaster"; -import { Logger } from "@biconomy/common"; - -describe("Batched Session Router Tests", () => { - let mumbai: TestData; - - beforeEach(() => { - // @ts-ignore: Comes from setup-e2e-tests - [mumbai] = testDataPerChain; - }); - - // TODO(Gabi): Fix Batched Session Router Module tests - it.skip("Should send a user op using Batched Session Validation Module", async () => { - let sessionSigner: WalletClientSigner; - - const { - whale: { - account: { address: sessionKeyEOA }, - privateKey: pvKey, - viemWallet, - }, - minnow: { publicAddress: recipient }, - publicClient, - bundlerUrl, - biconomyPaymasterApiKey, - chainId, - viemChain, - } = mumbai; - - // Create smart account - let smartAccount = await createSmartAccountClient({ - signer: viemWallet, - bundlerUrl, - biconomyPaymasterApiKey, - index: 3, // Increasing index to not conflict with other test cases and use a new smart account - }); - - const smartAccountAddress = await smartAccount.getAddress(); - - const sessionFileStorage: SessionFileStorage = new SessionFileStorage(smartAccountAddress); - - try { - sessionSigner = await sessionFileStorage.getSignerByKey(sessionKeyEOA); - } catch (error) { - sessionSigner = await sessionFileStorage.addSigner({ pbKey: sessionKeyEOA, pvKey, chainId: viemChain }); - } - - expect(sessionSigner).toBeTruthy(); - - // First we need to check if smart account is deployed - // if not deployed, send an empty transaction to deploy it - const isDeployed = await smartAccount.isAccountDeployed(); - - if (!isDeployed) { - const { wait } = await smartAccount.deploy({ paymasterServiceData: { mode: PaymasterMode.SPONSORED } }); - const { success } = await wait(); - expect(success).toBe("true"); - } - - // Create session module - const sessionModule = await createSessionKeyManagerModule({ - moduleAddress: DEFAULT_SESSION_KEY_MANAGER_MODULE, - smartAccountAddress, - sessionStorageClient: sessionFileStorage, - }); - - // Create batched session module - const batchedSessionModule = await createBatchedSessionRouterModule({ - moduleAddress: DEFAULT_BATCHED_SESSION_ROUTER_MODULE, - smartAccountAddress, - sessionKeyManagerModule: sessionModule, - }); - - // Set enabled call on session, only allows calling USDC contract transfer with <= 10 USDC - const sessionKeyData = encodeAbiParameters( - [{ type: "address" }, { type: "address" }, { type: "address" }, { type: "uint256" }], - [ - sessionKeyEOA, - "0xdA5289fCAAF71d52a80A254da614a192b693e977", // erc20 token address - recipient, // receiver address - parseUnits("10", 6), - ], - ); - - // only requires that the caller is the session key - // can call anything using the mock session module - const sessionKeyData2 = encodeAbiParameters([{ type: "address" }], [sessionKeyEOA]); - - const erc20ModuleAddr = "0x000000D50C68705bd6897B2d17c7de32FB519fDA"; - const mockSessionModuleAddr = "0x7Ba4a7338D7A90dfA465cF975Cc6691812C3772E"; - - const sessionTxData = await batchedSessionModule.createSessionData([ - { - validUntil: 0, - validAfter: 0, - sessionValidationModule: erc20ModuleAddr, - sessionPublicKey: sessionKeyEOA, - sessionKeyData: sessionKeyData, - }, - { - validUntil: 0, - validAfter: 0, - sessionValidationModule: mockSessionModuleAddr, - sessionPublicKey: sessionKeyEOA, - sessionKeyData: sessionKeyData2, - }, - ]); - - const setSessionAllowedTrx = { - to: DEFAULT_SESSION_KEY_MANAGER_MODULE, - data: sessionTxData.data, - }; - - const txArray: any = []; - - // Check if session module is enabled - const isEnabled = await smartAccount.isModuleEnabled(DEFAULT_SESSION_KEY_MANAGER_MODULE); - if (!isEnabled) { - const enableModuleTrx = await smartAccount.getEnableModuleData(DEFAULT_SESSION_KEY_MANAGER_MODULE); - txArray.push(enableModuleTrx); - } - - // Check if batched session module is enabled - const isBRMenabled = await smartAccount.isModuleEnabled(DEFAULT_BATCHED_SESSION_ROUTER_MODULE); - if (!isBRMenabled) { - // -----> enableModule batched session router module - const tx2 = await smartAccount.getEnableModuleData(DEFAULT_BATCHED_SESSION_ROUTER_MODULE); - txArray.push(tx2); - } - - txArray.push(setSessionAllowedTrx); - - const userOpResponse1 = await smartAccount.sendTransaction(txArray, { paymasterServiceData: { mode: PaymasterMode.SPONSORED } }); // this user op will enable the modules and setup session allowed calls - const transactionDetails = await userOpResponse1.wait(); - expect(transactionDetails.success).toBe("true"); - Logger.log("Tx Hash: ", transactionDetails.receipt.transactionHash); - - const usdcBalance = await checkBalance(publicClient, smartAccountAddress, "0xdA5289fCAAF71d52a80A254da614a192b693e977"); - expect(usdcBalance).toBeGreaterThan(0); - - smartAccount = smartAccount.setActiveValidationModule(batchedSessionModule); - - // WARNING* If the smart account does not have enough USDC, user op execution will FAIL - const encodedCall = encodeFunctionData({ - abi: parseAbi(["function transfer(address _to, uint256 _value)"]), - functionName: "transfer", - args: [recipient, parseUnits("0.001", 6)], - }); - - const encodedCall2 = encodeFunctionData({ - abi: parseAbi(["function transfer(address _to, uint256 _value)"]), - functionName: "transfer", - args: ["0xd3C85Fdd3695Aee3f0A12B3376aCD8DC54020549", parseUnits("0.001", 6)], - }); - - const transferTx = { - to: "0xdA5289fCAAF71d52a80A254da614a192b693e977", - data: encodedCall, - }; - - const transferTx2 = { - to: "0xdA5289fCAAF71d52a80A254da614a192b693e977", - data: encodedCall2, - }; - - const activeModule = smartAccount.activeValidationModule; - expect(activeModule).toEqual(batchedSessionModule); - - const maticBalanceBefore = await checkBalance(publicClient, smartAccountAddress); - - // failing with dummyTx because of invalid sessionKeyData - const userOpResponse2 = await smartAccount.sendTransaction([transferTx, transferTx2], { - params: { - batchSessionParams: [ - { - sessionSigner: sessionSigner, - sessionValidationModule: erc20ModuleAddr, - }, - { - sessionSigner: sessionSigner, - sessionValidationModule: mockSessionModuleAddr, - }, - ], - }, - paymasterServiceData: { - mode: PaymasterMode.SPONSORED, - }, - }); - - const receipt = await userOpResponse2.wait(); - console.log(receipt.userOpHash, "Batched user op hash"); - expect(receipt.success).toBe("true"); - - expect(userOpResponse2.userOpHash).toBeTruthy(); - expect(userOpResponse2.userOpHash).not.toBeNull(); - - const maticBalanceAfter = await checkBalance(publicClient, smartAccountAddress); - - expect(maticBalanceAfter).toEqual(maticBalanceBefore); - - Logger.log(`Tx at: https://jiffyscan.xyz/userOpHash/${userOpResponse2.userOpHash}?network=mumbai`); - }, 60000); -}); diff --git a/packages/modules/tests/ecdsaValidationModule.e2e.spec.ts b/packages/modules/tests/ecdsaValidationModule.e2e.spec.ts deleted file mode 100644 index 84b3f627e..000000000 --- a/packages/modules/tests/ecdsaValidationModule.e2e.spec.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { PaymasterMode } from "@biconomy/paymaster"; -import { TestData } from "../../../tests"; -import { createSmartAccountClient } from "../../account/src/index"; -import { Hex, encodeFunctionData, parseAbi } from "viem"; -import { DEFAULT_MULTICHAIN_MODULE, createECDSAOwnershipValidationModule } from "@biconomy/modules"; - -describe("Account with ECDSAOwnershipValidationModule Module Tests", () => { - let mumbai: TestData; - let baseSepolia: TestData; - - beforeEach(() => { - // @ts-ignore: Comes from setup-e2e-tests - [mumbai, baseSepolia] = testDataPerChain; - }); - - it("should create a ECDSAOwnershipValidationModule with signer", async () => { - const { - bundlerUrl, - whale: { viemWallet: signer }, - } = mumbai; - - const defaultValidationModule = await createECDSAOwnershipValidationModule({ signer }); - // Should not require a signer or chainId - const smartAccount = await createSmartAccountClient({ - bundlerUrl, - defaultValidationModule, - signer, - }); - const address = await smartAccount.getAccountAddress(); - expect(address).toBeTruthy(); - expect(smartAccount.activeValidationModule).toEqual(defaultValidationModule); - }); - - it("should create a ECDSAOwnershipValidationModule without signer", async () => { - const { - bundlerUrl, - whale: { viemWallet: signer }, - } = mumbai; - - const defaultValidationModule = await createECDSAOwnershipValidationModule({ signer }); - // Should not require a signer or chainId - const smartAccount = await createSmartAccountClient({ - bundlerUrl, - defaultValidationModule, - }); - const address = await smartAccount.getAccountAddress(); - expect(address).toBeTruthy(); - expect(smartAccount.activeValidationModule).toEqual(defaultValidationModule); - }); - - it("should create a ECDSAOwnershipValidationModule by default, without explicitly setting it on the smart account", async () => { - const { - bundlerUrl, - whale: { viemWallet: signer }, - } = mumbai; - const defaultValidationModule = await createECDSAOwnershipValidationModule({ signer }); - const smartAccount = await createSmartAccountClient({ bundlerUrl, signer }); - const address = await smartAccount.getAccountAddress(); - expect(address).toBeTruthy(); - const smartAccountValidationModuleAddress = await smartAccount.activeValidationModule.getAddress(); - expect(smartAccountValidationModuleAddress).toEqual(defaultValidationModule.moduleAddress); - }); -}); diff --git a/packages/modules/tests/modules.e2e.spec.ts b/packages/modules/tests/modules.e2e.spec.ts deleted file mode 100644 index 9de6d50ee..000000000 --- a/packages/modules/tests/modules.e2e.spec.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { TestData } from "../../../tests"; -import { PaymasterMode, Transaction, createSmartAccountClient } from "@biconomy/account"; -import { DEFAULT_BATCHED_SESSION_ROUTER_MODULE, DEFAULT_ERC20_MODULE, DEFAULT_SESSION_KEY_MANAGER_MODULE } from "../src"; - -describe("Account Tests", () => { - let mumbai: TestData; - - beforeEach(() => { - // @ts-ignore: Comes from setup-unit-tests - [mumbai] = testDataPerChain; - }); - - it("should enable batched module", async () => { - const { - whale: { viemWallet: signer }, - bundlerUrl, - biconomyPaymasterApiKey, - } = mumbai; - - const smartAccount = await createSmartAccountClient({ - signer, - bundlerUrl, - biconomyPaymasterApiKey, - }); - - const isBRMenabled = await smartAccount.isModuleEnabled(DEFAULT_BATCHED_SESSION_ROUTER_MODULE); - - if (!isBRMenabled) { - const tx = await smartAccount.getEnableModuleData(DEFAULT_BATCHED_SESSION_ROUTER_MODULE); - const { wait } = await smartAccount.sendTransaction(tx, { - paymasterServiceData: { mode: PaymasterMode.SPONSORED }, - }); - const { success } = await wait(); - expect(success).toBe("true"); - } - }, 50000); - - it("should enable session module", async () => { - const { - whale: { viemWallet: signer }, - bundlerUrl, - biconomyPaymasterApiKey, - } = mumbai; - - const smartAccount = await createSmartAccountClient({ - signer, - bundlerUrl, - biconomyPaymasterApiKey, - }); - - const isSessionKeyEnabled = await smartAccount.isModuleEnabled(DEFAULT_SESSION_KEY_MANAGER_MODULE); - - if (!isSessionKeyEnabled) { - const tx = await smartAccount.getEnableModuleData(DEFAULT_SESSION_KEY_MANAGER_MODULE); - const { wait } = await smartAccount.sendTransaction(tx, { - paymasterServiceData: { mode: PaymasterMode.SPONSORED }, - }); - const { success } = await wait(); - expect(success).toBe("true"); - } - }, 50000); -}); diff --git a/packages/modules/tests/modules.spec.ts b/packages/modules/tests/modules.spec.ts deleted file mode 100644 index a799a6760..000000000 --- a/packages/modules/tests/modules.spec.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { TestData } from "../../../tests"; -import { createSmartAccountClient } from "@biconomy/account"; -import { createECDSAOwnershipValidationModule, createMultiChainValidationModule } from "../src"; - -describe("Account Tests", () => { - let ganache: TestData; - - beforeEach(() => { - // @ts-ignore: Comes from setup-unit-tests - [ganache] = testDataPerChain; - }); - - it("should create a MultiChainValidationModule from an ethers signer using convertSigner", async () => { - const { - bundlerUrl, - whale: { ethersSigner: signer }, - viemChain, - } = ganache; - - const defaultValidationModule = await createMultiChainValidationModule({ signer }); - // Should not require a signer or chainId - const smartAccount = await createSmartAccountClient({ bundlerUrl, defaultValidationModule, rpcUrl: viemChain.rpcUrls.default.http[0], }); - const address = await smartAccount.getAccountAddress(); - expect(address).toBeTruthy(); - // expect the relevant module to be set - expect(smartAccount.activeValidationModule).toEqual(defaultValidationModule); - }, 50000); - - it("should create a ECDSAOwnershipValidationModule from a viem signer using convertSigner", async () => { - const { - bundlerUrl, - whale: { viemWallet: signer }, - viemChain, - } = ganache; - - const defaultValidationModule = await createECDSAOwnershipValidationModule({ signer }); - // Should not require a signer or chainId - const smartAccount = await createSmartAccountClient({ - bundlerUrl, - defaultValidationModule, - rpcUrl: viemChain.rpcUrls.default.http[0], - }); - const address = await smartAccount.getAccountAddress(); - expect(address).toBeTruthy(); - // expect the relevant module to be set - expect(smartAccount.activeValidationModule).toEqual(defaultValidationModule); - }, 50000); -}); diff --git a/packages/modules/tests/multiChainValidationModule.e2e.spec.ts b/packages/modules/tests/multiChainValidationModule.e2e.spec.ts deleted file mode 100644 index 996be004c..000000000 --- a/packages/modules/tests/multiChainValidationModule.e2e.spec.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { PaymasterMode } from "@biconomy/paymaster"; -import { TestData } from "../../../tests"; -import { createSmartAccountClient } from "../../account/src/index"; -import { Hex, encodeFunctionData, parseAbi } from "viem"; -import { DEFAULT_MULTICHAIN_MODULE, MultiChainValidationModule } from "@biconomy/modules"; -import { Logger } from "@biconomy/common"; - -describe("MultiChainValidation Module Tests", () => { - let mumbai: TestData; - let baseSepolia: TestData; - - beforeEach(() => { - // @ts-ignore: Comes from setup-e2e-tests - [mumbai, baseSepolia] = testDataPerChain; - }); - - it("Should mint an NFT gasless on baseSepolia and mumbai", async () => { - const { - whale: { alchemyWalletClientSigner: signerMumbai, publicAddress: recipientForBothChains }, - paymasterUrl: biconomyPaymasterApiKeyMumbai, - bundlerUrl: bundlerUrlMumbai, - chainId: chainIdMumbai, - } = mumbai; - - const { - whale: { alchemyWalletClientSigner: signerBase }, - paymasterUrl: biconomyPaymasterApiKeyBase, - bundlerUrl: bundlerUrlBase, - chainId: chainIdBase, - } = baseSepolia; - - const nftAddress: Hex = "0x1758f42Af7026fBbB559Dc60EcE0De3ef81f665e"; - - const multiChainModule = await MultiChainValidationModule.create({ - signer: signerMumbai, - moduleAddress: DEFAULT_MULTICHAIN_MODULE, - }); - - const [polygonAccount, baseAccount] = await Promise.all([ - createSmartAccountClient({ - chainId: chainIdMumbai, - signer: signerMumbai, - bundlerUrl: bundlerUrlMumbai, - defaultValidationModule: multiChainModule, - activeValidationModule: multiChainModule, - paymasterUrl: biconomyPaymasterApiKeyMumbai, - }), - createSmartAccountClient({ - chainId: chainIdBase, - signer: signerBase, - bundlerUrl: bundlerUrlBase, - defaultValidationModule: multiChainModule, - activeValidationModule: multiChainModule, - paymasterUrl: biconomyPaymasterApiKeyBase, - }), - ]); - - // Check if the smart account has been deployed - const [isPolygonDeployed, isBaseDeployed] = await Promise.all([polygonAccount.isAccountDeployed(), baseAccount.isAccountDeployed()]); - if (!isPolygonDeployed) { - const { wait } = await polygonAccount.deploy({ paymasterServiceData: { mode: PaymasterMode.SPONSORED } }); - const { success } = await wait(); - expect(success).toBe("true"); - } - if (!isBaseDeployed) { - const { wait } = await baseAccount.deploy({ paymasterServiceData: { mode: PaymasterMode.SPONSORED } }); - const { success } = await wait(); - expect(success).toBe("true"); - } - - const moduleEnabled1 = await polygonAccount.isModuleEnabled(DEFAULT_MULTICHAIN_MODULE); - const moduleActive1 = polygonAccount.activeValidationModule; - expect(moduleEnabled1).toBeTruthy(); - expect(moduleActive1.getAddress()).toBe(DEFAULT_MULTICHAIN_MODULE); - - const moduleEnabled2 = await baseAccount.isModuleEnabled(DEFAULT_MULTICHAIN_MODULE); - const moduleActive2 = polygonAccount.activeValidationModule; - expect(moduleEnabled2).toBeTruthy(); - expect(moduleActive2.getAddress()).toBe(DEFAULT_MULTICHAIN_MODULE); - - const encodedCall = encodeFunctionData({ - abi: parseAbi(["function safeMint(address owner) view returns (uint balance)"]), - functionName: "safeMint", - args: [recipientForBothChains], - }); - - const transaction = { - to: nftAddress, - data: encodedCall, - }; - - const [partialUserOp1, partialUserOp2] = await Promise.all([ - baseAccount.buildUserOp([transaction], { paymasterServiceData: { mode: PaymasterMode.SPONSORED } }), - polygonAccount.buildUserOp([transaction], { paymasterServiceData: { mode: PaymasterMode.SPONSORED } }), - ]); - - expect(partialUserOp1.paymasterAndData).not.toBe("0x"); - expect(partialUserOp2.paymasterAndData).not.toBe("0x"); - - // Sign the user ops using multiChainModule - const returnedOps = await multiChainModule.signUserOps([ - { userOp: partialUserOp1, chainId: chainIdBase }, - { userOp: partialUserOp2, chainId: chainIdMumbai }, - ]); - - // Send the signed user ops on both chains - const userOpResponse1 = await baseAccount.sendSignedUserOp(returnedOps[0] as any); - const userOpResponse2 = await polygonAccount.sendSignedUserOp(returnedOps[1] as any); - - Logger.log(userOpResponse1.userOpHash, "MULTICHAIN BASE USER OP HASH"); - Logger.log(userOpResponse2.userOpHash, "MULTICHAIN POLYGON USER OP HASH"); - - expect(userOpResponse1.userOpHash).toBeTruthy(); - expect(userOpResponse2.userOpHash).toBeTruthy(); - - const { success: success1 } = await userOpResponse1.wait(); - const { success: success2 } = await userOpResponse2.wait(); - - expect(success1).toBe("true"); - expect(success2).toBe("true"); - }, 50000); -}); diff --git a/packages/modules/tests/sessionValidationModule.e2e.spec.ts b/packages/modules/tests/sessionValidationModule.e2e.spec.ts deleted file mode 100644 index 286cfb9a7..000000000 --- a/packages/modules/tests/sessionValidationModule.e2e.spec.ts +++ /dev/null @@ -1,166 +0,0 @@ -import { DEFAULT_SESSION_KEY_MANAGER_MODULE, createSessionKeyManagerModule } from "@biconomy/modules"; -import { SessionFileStorage } from "./utils/customSession"; -import { WalletClientSigner, createSmartAccountClient } from "../../account/src/index"; -import { Hex, encodeAbiParameters, encodeFunctionData, pad, parseAbi, parseEther, parseUnits, slice, toFunctionSelector } from "viem"; -import { TestData } from "../../../tests"; -import { checkBalance } from "../../../tests/utils"; -import { PaymasterMode } from "@biconomy/paymaster"; -import { Logger } from "@biconomy/common"; -import { getABISVMSessionKeyData } from "../src/utils/Helper"; -import { privateKeyToAccount, generatePrivateKey } from "viem/accounts"; - -describe("Session Validation Module Tests", () => { - let mumbai: TestData; - - beforeEach(() => { - // @ts-ignore: Comes from setup-e2e-tests - [mumbai] = testDataPerChain; - }); - - // TODO(Gabi): Fix Session Validation Module tests - it.skip("Should send a user op using Session Validation Module", async () => { - let sessionSigner: WalletClientSigner; - const { - whale: { - account: { address: sessionKeyEOA }, - privateKey: pvKey, - viemWallet, - }, - viemChain, - minnow: { publicAddress: recipient }, - publicClient, - chainId, - bundlerUrl, - biconomyPaymasterApiKey, - } = mumbai; - - // Create smart account - let smartAccount = await createSmartAccountClient({ - chainId, - signer: viemWallet, - bundlerUrl, - biconomyPaymasterApiKey, - index: 1, // Increasing index to not conflict with other test cases and use a new smart account - }); - - const accountAddress = await smartAccount.getAccountAddress(); - const sessionFileStorage: SessionFileStorage = new SessionFileStorage(accountAddress); - - // First we need to check if smart account is deployed - // if not deployed, send an empty transaction to deploy it - const isDeployed = await smartAccount.isAccountDeployed(); - - Logger.log("session", { isDeployed }); - - if (!isDeployed) { - const { wait } = await smartAccount.deploy({ paymasterServiceData: { mode: PaymasterMode.SPONSORED } }); - const { success } = await wait(); - expect(success).toBe("true"); - } - - try { - sessionSigner = await sessionFileStorage.getSignerByKey(sessionKeyEOA); - } catch (error) { - sessionSigner = await sessionFileStorage.addSigner({ pbKey: sessionKeyEOA, pvKey, chainId: viemChain }); - } - expect(sessionSigner).toBeTruthy(); - - // Create session module - const sessionModule = await createSessionKeyManagerModule({ - moduleAddress: DEFAULT_SESSION_KEY_MANAGER_MODULE, - smartAccountAddress: await smartAccount.getAddress(), - sessionStorageClient: sessionFileStorage, - }); - - const functionSelector = slice(toFunctionSelector("safeMint(address)"), 0, 4); - // Set enabled call on session - const sessionKeyData = await getABISVMSessionKeyData(sessionKeyEOA as Hex, { - destContract: "0xdd526eba63ef200ed95f0f0fb8993fe3e20a23d0" as Hex, // nft address - functionSelector: functionSelector, - valueLimit: parseEther("0"), - rules: [ - { - offset: 0, // offset 0 means we are checking first parameter of safeMint (recipient address) - condition: 0, // 0 = Condition.EQUAL - referenceValue: pad("0xd3C85Fdd3695Aee3f0A12B3376aCD8DC54020549", { size: 32 }), // recipient address - }, - ], - }); - - const abiSvmAddress = "0x000006bC2eCdAe38113929293d241Cf252D91861"; - - const sessionTxData = await sessionModule.createSessionData([ - { - validUntil: 0, - validAfter: 0, - sessionValidationModule: abiSvmAddress, - sessionPublicKey: sessionKeyEOA as Hex, - sessionKeyData: sessionKeyData as Hex, - }, - ]); - - const setSessionAllowedTrx = { - to: DEFAULT_SESSION_KEY_MANAGER_MODULE, - data: sessionTxData.data, - }; - - const txArray: any = []; - - // Check if module is enabled - const isEnabled = await smartAccount.isModuleEnabled(DEFAULT_SESSION_KEY_MANAGER_MODULE); - - if (!isEnabled) { - const enableModuleTrx = await smartAccount.getEnableModuleData(DEFAULT_SESSION_KEY_MANAGER_MODULE); - txArray.push(enableModuleTrx); - txArray.push(setSessionAllowedTrx); - } else { - Logger.log("MODULE ALREADY ENABLED"); - txArray.push(setSessionAllowedTrx); - } - - const userOp = await smartAccount.buildUserOp(txArray, { - paymasterServiceData: { - mode: PaymasterMode.SPONSORED, - }, - }); - - const userOpResponse1 = await smartAccount.sendUserOp(userOp); - const transactionDetails = await userOpResponse1.wait(); - expect(transactionDetails.success).toBe("true"); - Logger.log("Tx Hash: ", transactionDetails.receipt.transactionHash); - - const encodedCall = encodeFunctionData({ - abi: parseAbi(["function safeMint(address _to)"]), - functionName: "safeMint", - args: ["0xd3C85Fdd3695Aee3f0A12B3376aCD8DC54020549"], - }); - - const nftMintTx = { - to: "0xdd526eba63ef200ed95f0f0fb8993fe3e20a23d0", - data: encodedCall, - }; - - smartAccount = smartAccount.setActiveValidationModule(sessionModule); - - const maticBalanceBefore = await checkBalance(publicClient, await smartAccount.getAccountAddress()); - - const userOpResponse2 = await smartAccount.sendTransaction(nftMintTx, { - params: { - sessionSigner: sessionSigner, - sessionValidationModule: abiSvmAddress, - }, - paymasterServiceData: { - mode: PaymasterMode.SPONSORED, - }, - }); - - expect(userOpResponse2.userOpHash).toBeTruthy(); - expect(userOpResponse2.userOpHash).not.toBeNull(); - - const maticBalanceAfter = await checkBalance(publicClient, await smartAccount.getAccountAddress()); - - expect(maticBalanceAfter).toEqual(maticBalanceBefore); - - Logger.log(`Tx at: https://jiffyscan.xyz/userOpHash/${userOpResponse2.userOpHash}?network=mumbai`); - }, 60000); -}); diff --git a/packages/modules/tests/utils/customSession.ts b/packages/modules/tests/utils/customSession.ts deleted file mode 100644 index 1326c4871..000000000 --- a/packages/modules/tests/utils/customSession.ts +++ /dev/null @@ -1,230 +0,0 @@ -import * as fs from "fs"; -import { SmartAccountSigner, WalletClientSigner, getChain } from "@alchemy/aa-core"; -import { SignerData } from "@biconomy/modules/src"; -import { generatePrivateKey, privateKeyToAccount } from "viem/accounts"; -import { Hex, createWalletClient, http } from "viem"; -import { polygonMumbai } from "viem/chains"; -import { ISessionStorage, SessionLeafNode, SessionSearchParam, SessionStatus } from "@biconomy/modules/src/interfaces/ISessionStorage.js"; -import { Logger } from "@biconomy/common"; - -export class SessionFileStorage implements ISessionStorage { - private smartAccountAddress: string; - - constructor(smartAccountAddress: string) { - this.smartAccountAddress = smartAccountAddress.toLowerCase(); - } - - // This method reads data from the file and returns it in the JSON format - private async readDataFromFile(type: "sessions" | "signers"): Promise<any> { - return new Promise((resolve) => { - fs.readFile(this.getStorageFilePath(type), "utf8", (err, data) => { - if (err) { - // Handle errors appropriately - resolve(undefined); - } else { - if (!data) { - resolve(null); - } else { - resolve(JSON.parse(data)); - } - // resolve(JSON.parse(data)); - } - }); - }); - } - - private getStorageFilePath(type: "sessions" | "signers"): string { - return `./packages/modules/tests/utils/sessionStorageData/${this.smartAccountAddress}_${type}.json`; - } - - private async writeDataToFile(data: any, type: "sessions" | "signers"): Promise<void> { - return new Promise((resolve, reject) => { - const filePath = this.getStorageFilePath(type); - fs.writeFile(filePath, JSON.stringify(data), "utf8", (err) => { - if (err) { - // Handle errors appropriately - reject(err); - } else { - resolve(); - } - }); - }); - } - - private validateSearchParam(param: SessionSearchParam): void { - if (param.sessionID) { - return; - } else if (!param.sessionID && param.sessionPublicKey && param.sessionValidationModule) { - return; - } else { - throw new Error("Either pass sessionId or a combination of sessionPublicKey and sessionValidationModule address."); - } - } - - // Session store is in the form of mekrleRoot and leafnodes, each object will have a root and an array of leafNodes. - private async getSessionStore(): Promise<any> { - // eslint-disable-next-line no-useless-catch - try { - const data = await this.readDataFromFile("sessions"); - return data || { merkleRoot: "", leafNodes: [] }; - } catch (error) { - // Handle errors appropriately - throw error; - } - } - - private async getSignerStore(): Promise<any> { - // eslint-disable-next-line no-useless-catch - try { - const data = await this.readDataFromFile("signers"); - return data || {}; - } catch (error) { - // Handle errors appropriately - throw error; - } - } - - private getStorageKey(type: "sessions" | "signers"): string { - return `${this.smartAccountAddress}_${type}`; - } - - private toLowercaseAddress(address: string): Hex { - return address.toLowerCase() as Hex; - } - - async getSessionData(param: SessionSearchParam): Promise<SessionLeafNode> { - const sessions = (await this.getSessionStore()).leafNodes; - const session = sessions.find((s: SessionLeafNode) => { - if (param.sessionID) { - return s.sessionID === param.sessionID && (!param.status || s.status === param.status); - } else if (param.sessionPublicKey && param.sessionValidationModule) { - return ( - s.sessionPublicKey === this.toLowercaseAddress(param.sessionPublicKey) && - s.sessionValidationModule === this.toLowercaseAddress(param.sessionValidationModule) && - (!param.status || s.status === param.status) - ); - } else { - return undefined; - } - }); - - if (!session) { - throw new Error("Session not found."); - } - return session; - } - - async addSessionData(leaf: SessionLeafNode): Promise<void> { - Logger.log("Add session Data", leaf); - const data = await this.getSessionStore(); - leaf.sessionValidationModule = this.toLowercaseAddress(leaf.sessionValidationModule); - leaf.sessionPublicKey = this.toLowercaseAddress(leaf.sessionPublicKey); - data.leafNodes.push(leaf); - await this.writeDataToFile(data, "sessions"); // Use 'sessions' as the type - } - - async updateSessionStatus(param: SessionSearchParam, status: SessionStatus): Promise<void> { - this.validateSearchParam(param); - - const data = await this.getSessionStore(); - const session = data.leafNodes.find((s: SessionLeafNode) => { - if (param.sessionID) { - return s.sessionID === param.sessionID; - } else if (param.sessionPublicKey && param.sessionValidationModule) { - return ( - s.sessionPublicKey === this.toLowercaseAddress(param.sessionPublicKey) && - s.sessionValidationModule === this.toLowercaseAddress(param.sessionValidationModule) - ); - } else { - return undefined; - } - }); - - if (!session) { - throw new Error("Session not found."); - } - - session.status = status; - await this.writeDataToFile(data, "sessions"); // Use 'sessions' as the type - } - - async clearPendingSessions(): Promise<void> { - const data = await this.getSessionStore(); - data.leafNodes = data.leafNodes.filter((s: SessionLeafNode) => s.status !== "PENDING"); - await this.writeDataToFile(data, "sessions"); // Use 'sessions' as the type - } - - async addSigner(signerData: SignerData): Promise<WalletClientSigner> { - const signers = await this.getSignerStore(); - let signer: SignerData; - if (!signerData) { - const pkey = generatePrivateKey(); - signer = { - pvKey: pkey, - pbKey: privateKeyToAccount(pkey).publicKey, - }; - } else { - signer = signerData; - } - const accountSigner = privateKeyToAccount(signer.pvKey); - const viemChain = getChain(signerData?.chainId?.id || 1); - const client = createWalletClient({ - account: accountSigner, - chain: signerData.chainId, - transport: http(viemChain.rpcUrls.default.http[0]), - }); - const walletClientSigner: SmartAccountSigner = new WalletClientSigner( - client, - "json-rpc", // signerType - ); - signers[this.toLowercaseAddress(accountSigner.address)] = { - pvKey: signer.pvKey, - pbKey: signer.pbKey, - }; - await this.writeDataToFile(signers, "signers"); // Use 'signers' as the type - return walletClientSigner; - } - - async getSignerByKey(sessionPublicKey: string): Promise<WalletClientSigner> { - const signers = await this.getSignerStore(); - Logger.log("Got signers", signers); - - const signerData: SignerData = signers[this.toLowercaseAddress(sessionPublicKey)]; - if (!signerData) { - throw new Error("Signer not found."); - } - Logger.log(signerData.pvKey, "PVKEY"); - - const signer = privateKeyToAccount(signerData.pvKey); - const walletClient = createWalletClient({ - account: signer, - transport: http(polygonMumbai.rpcUrls.default.http[0]), - }); - return new WalletClientSigner(walletClient, "json-rpc"); - } - - async getSignerBySession(param: SessionSearchParam): Promise<WalletClientSigner> { - const session = await this.getSessionData(param); - Logger.log("got session", session); - const walletClientSinger = await this.getSignerByKey(session.sessionPublicKey); - return walletClientSinger; - } - - async getAllSessionData(param?: SessionSearchParam): Promise<SessionLeafNode[]> { - const sessions = (await this.getSessionStore()).leafNodes; - if (!param || !param.status) { - return sessions; - } - return sessions.filter((s: SessionLeafNode) => s.status === param.status); - } - - async getMerkleRoot(): Promise<string> { - return (await this.getSessionStore()).merkleRoot; - } - - async setMerkleRoot(merkleRoot: string): Promise<void> { - const data = await this.getSessionStore(); - data.merkleRoot = merkleRoot; - await this.writeDataToFile(data, "sessions"); // Use 'sessions' as the type - } -} diff --git a/packages/modules/tests/utils/sessionStorageData/.gitkeep b/packages/modules/tests/utils/sessionStorageData/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/packages/modules/tsconfig.build.json b/packages/modules/tsconfig.build.json deleted file mode 100644 index 4ac8b8026..000000000 --- a/packages/modules/tsconfig.build.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "display": "Build", - "compilerOptions": { - "lib": ["es2022", "dom"], - "target": "es2021", - "types": ["node"], - "allowJs": false, - "skipLibCheck": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "module": "esnext", - "moduleResolution": "node", - "resolveJsonModule": true, - "isolatedModules": true, - "verbatimModuleSyntax": false, - "useDefineForClassFields": true, - "noFallthroughCasesInSwitch": true, - "noImplicitReturns": true, - "useUnknownInCatchVariables": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "declaration": true, - "inlineSources": true, - "noEmit": false, - "sourceMap": true - }, - "exclude": ["**/*/node_modules", "**/*/tests", "tests"], - "include": ["src"] -} \ No newline at end of file diff --git a/packages/modules/tsconfig.json b/packages/modules/tsconfig.json deleted file mode 100644 index adc19ded0..000000000 --- a/packages/modules/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../../tsconfig.settings.json", - "compilerOptions": { - "composite": true, - "outDir": "dist", - "baseUrl": "src", - "resolveJsonModule": true, - "esModuleInterop": true, - "lib": ["es2020"], - "types": ["node"], - }, - "include": ["src", "src/**/*.json"] -} diff --git a/packages/particle-auth/.esbuild.js b/packages/particle-auth/.esbuild.js deleted file mode 100644 index ca355e346..000000000 --- a/packages/particle-auth/.esbuild.js +++ /dev/null @@ -1,58 +0,0 @@ -const esbuildPluginTsc = require("esbuild-plugin-tsc"); -const esbuild = require("esbuild"); -const { dependencies, peerDependencies = {} } = require("./package.json"); -const { Generator } = require("npm-dts"); - -const COMMON_SETTINGS = { - entryPoints: ["src/index.ts"], - minify: true, - bundle: true, - plugins: [esbuildPluginTsc({ force: true })], -}; - -const ESM_SETTINGS = { - ...COMMON_SETTINGS, - sourcemap: true, - outfile: "dist/esm/index.js", - platform: "browser", - target: "esnext", - format: "esm", - mainFields: ["browser", "module", "main"], -}; -const buildForESM = async () => await esbuild.build(ESM_SETTINGS); - -const CJS_SETTINGS = { - ...COMMON_SETTINGS, - format: "cjs", - sourcemap: false, - outfile: "dist/cjs/index.js", - platform: "node", -}; - -const watchForCJS = async () => { - let ctx = await esbuild.context(CJS_SETTINGS); - await ctx.watch(); - await ctx.serve({ servedir: "dist/src" }); - console.log("watching..."); -}; - -const buildForCJS = async () => await esbuild.build(CJS_SETTINGS); -const buildForTYP = async () => await new Generator({ entry: "src/index.ts", output: "dist/types/index.d.ts" }).generate(); - -(async () => { - const buildType = process.argv.slice(2)[0]; - const shouldWatch = process.argv.slice(3)[0] === "--watch"; - if (!buildType) { - console.log("No build type provided"); - process.exit(1); - } - console.log(`Building for ${buildType}`); - if (buildType === "ESM") { - await buildForESM(); - } else if (buildType === "CJS") { - console.log("watching? " + shouldWatch); - await (shouldWatch ? watchForCJS : buildForCJS)(); - } else if (buildType === "TYP") { - await buildForTYP(); - } -})(); diff --git a/packages/particle-auth/CHANGELOG.md b/packages/particle-auth/CHANGELOG.md deleted file mode 100644 index 9ebd16ef1..000000000 --- a/packages/particle-auth/CHANGELOG.md +++ /dev/null @@ -1,66 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## 4.1.1 (2023-07-03) - -VERSION Bump Only. - -## 4.1.0 (2023-04-03) - -VERSION Bump Only. - -## 4.0.3 (2023-28-02) - -Fix build - -## 4.0.2 (2023-12-28) - -Fix build - -## 4.0.1 (2023-02-22) - -VERSION Bump Only. - -## 4.0.0 (2023-12-28) - -VERSION Bump Only. - -## 3.1.3 (2023-12-28) - -VERSION Bump Only. - -## 3.1.2 (2023-12-28) - -VERSION Bump Only. - -## 3.1.1 (2023-11-09) - -### Features - -- Upgrade package version ([])(https://github.com/bcnmy/biconomy-client-sdk/commit/d467b85) - -## 3.1.0 (2023-09-20) - -Version Bump Only. - -# 3.0.0 (2023-08-28) - -### Features - -- particle auth integration ([7b8fb1d](https://github.com/bcnmy/biconomy-client-sdk/commit/7b8fb1d05e3cc0196bc15806fa48100701af181e)) - -## 3.0.0-alpha.0 (2023-07-12) - -## 2.0.1 (2023-06-10) - -### Bug Fixes - -- typo ([0a63ff1](https://github.com/bcnmy/biconomy-client-sdk/commit/0a63ff17bb38b1bc2fd68669b74c2efd5a959d31)) - -## 2.0.0 (2023-30-05) - -### Features - -- particle-auth ([7b8fb1d](https://github.com/bcnmy/biconomy-client-sdk/commit/7b8fb1d05e3cc0196bc15806fa48100701af181e)) diff --git a/packages/particle-auth/README.md b/packages/particle-auth/README.md deleted file mode 100644 index 8d3a34187..000000000 --- a/packages/particle-auth/README.md +++ /dev/null @@ -1,41 +0,0 @@ -# `@biconomy/particle-auth` - -> A library to import the particle-auth for web directly from [Biconomy SDK](https://github.com/bcnmy/biconomy-client-sdk) - -## Usage - -```ts -import { ParticleNetwork, WalletEntryPosition } from "@biconomy/particle-auth"; -import { ParticleProvider } from "@biconomy/particle-auth"; -import Web3 from "web3"; - -const particle = new ParticleNetwork({ - projectId: "xx", - clientKey: "xx", - appId: "xx", - chainName: "Ethereum", //optional: current chain name, default Ethereum. - chainId: 1, //optional: current chain id, default 1. - wallet: { - //optional: by default, the wallet entry is displayed in the bottom right corner of the webpage. - displayWalletEntry: true, //show wallet entry when connect particle. - defaultWalletEntryPosition: WalletEntryPosition.BR, //wallet entry position - uiMode: "dark", //optional: light or dark, if not set, the default is the same as web auth. - supportChains: [ - { id: 1, name: "Ethereum" }, - { id: 5, name: "Ethereum" }, - ], // optional: web wallet support chains. - customStyle: {}, //optional: custom wallet style - }, -}); - -const particleProvider = new ParticleProvider(particle.auth); - -//if you use web3.js -window.web3 = new Web3(particleProvider); -window.web3.currentProvider.isParticleNetwork; // => true - -//if you use ethers.js -import { ethers } from "ethers"; -const ethersProvider = new ethers.providers.Web3Provider(particleProvider, "any"); -const ethersSigner = ethersProvider.getSigner(); -``` diff --git a/packages/particle-auth/package.json b/packages/particle-auth/package.json deleted file mode 100644 index 87f407661..000000000 --- a/packages/particle-auth/package.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "name": "@biconomy/particle-auth", - "version": "4.1.1", - "description": "Particle auth for Biconomy SDK", - "main": "./dist/cjs/index.js", - "module": "./dist/esm/index.js", - "types": "./dist/types/index.d.ts", - "typings": "./dist/types/index.d.ts", - "exports": { - ".": { - "import": "./dist/esm/index.js", - "types": "./dist/types/index.d.ts", - "default": "./dist/cjs/index.js" - }, - "./package.json": "./package.json" - }, - "keywords": [ - "legos", - "batching", - "one-click", - "cross-chain", - "particle", - "particle-auth" - ], - "author": "Biconomy", - "homepage": "https://github.com/bcnmy/biconomy-client-sdk#readme", - "license": "MIT", - "files": [ - "dist/*", - "README.md" - ], - "repository": { - "type": "git", - "url": "git+https://github.com/bcnmy/biconomy-client-sdk.git" - }, - "scripts": { - "unbuild": "rimraf dist *.tsbuildinfo", - "build:watch": "yarn build:tsc --watch", - "dist:minify": "esbuild ./dist/esm/**/*.js ./dist/esm/*.js --minify --outdir=./dist/esm --bundle=false --allow-overwrite", - "build": "yarn unbuild && yarn build:tsc", - "build:esbuild": "yarn build:esbuild:cjs && yarn build:esbuild:esm && yarn build:typ", - "build:tsc:cjs": "tsc --project tsconfig.build.json --module commonjs --outDir ./dist/cjs --removeComments --verbatimModuleSyntax false && echo > ./dist/cjs/package.json '{\"type\":\"commonjs\"}'", - "build:tsc:esm": "tsc --project tsconfig.build.json --module esnext --outDir ./dist/esm --removeComments && echo > ./dist/esm/package.json '{\"type\":\"module\"}'", - "build:esbuild:cjs": "node .esbuild.js CJS && echo > ./dist/cjs/package.json '{\"type\":\"commonjs\"}'", - "build:esbuild:esm": "node .esbuild.js ESM && echo > ./dist/esm/package.json '{\"type\":\"module\"}'", - "build:typ": "tsc --project tsconfig.build.json --module esnext --declarationDir ./dist/types --emitDeclarationOnly --declaration --declarationMap", - "build:tsc": "yarn build:tsc:cjs && yarn build:tsc:esm && yarn build:typ && yarn dist:minify", - "format": "prettier --write \"{src,tests}/**/*.ts\"", - "lint": "tslint -p tsconfig.json" - }, - "bugs": { - "url": "https://github.com/bcnmy/biconomy-client-sdk/issues" - }, - "publishConfig": { - "access": "public" - }, - "dependencies": { - "@particle-network/auth": "^1.2.1", - "@particle-network/biconomy": "^1.0.0", - "@particle-network/provider": "^1.2.0" - }, - "devDependencies": { - "@types/node": "^20.11.10", - "esbuild": "^0.19.11", - "esbuild-plugin-tsc": "^0.4.0", - "npm-dts": "^1.3.12" - } -} diff --git a/packages/particle-auth/src/index.ts b/packages/particle-auth/src/index.ts deleted file mode 100644 index 03966301b..000000000 --- a/packages/particle-auth/src/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -import * as ParticleAuth from "@particle-network/auth"; -import * as BiconomyAccount from "@particle-network/biconomy"; -export { ParticleProvider, ParticleDelegateProvider } from "@particle-network/provider"; -export { ParticleAuth as ParticleAuthModule, BiconomyAccount as BiconomyAccountModule }; diff --git a/packages/particle-auth/tests/particle-auth.spec.ts b/packages/particle-auth/tests/particle-auth.spec.ts deleted file mode 100644 index 97866f6b6..000000000 --- a/packages/particle-auth/tests/particle-auth.spec.ts +++ /dev/null @@ -1,5 +0,0 @@ -describe("Particle Auth Tests", () => { - it("should have a basic test", () => { - expect(true).toBe(true); - }); -}); diff --git a/packages/particle-auth/tsconfig.build.json b/packages/particle-auth/tsconfig.build.json deleted file mode 100644 index 4ac8b8026..000000000 --- a/packages/particle-auth/tsconfig.build.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "display": "Build", - "compilerOptions": { - "lib": ["es2022", "dom"], - "target": "es2021", - "types": ["node"], - "allowJs": false, - "skipLibCheck": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "module": "esnext", - "moduleResolution": "node", - "resolveJsonModule": true, - "isolatedModules": true, - "verbatimModuleSyntax": false, - "useDefineForClassFields": true, - "noFallthroughCasesInSwitch": true, - "noImplicitReturns": true, - "useUnknownInCatchVariables": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "declaration": true, - "inlineSources": true, - "noEmit": false, - "sourceMap": true - }, - "exclude": ["**/*/node_modules", "**/*/tests", "tests"], - "include": ["src"] -} \ No newline at end of file diff --git a/packages/particle-auth/tsconfig.json b/packages/particle-auth/tsconfig.json deleted file mode 100644 index cda17a184..000000000 --- a/packages/particle-auth/tsconfig.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../../tsconfig.settings.json", - "compilerOptions": { - "composite": true, - "outDir": "dist", - "baseUrl": "src", - "resolveJsonModule": true, - "esModuleInterop": true, - "lib": ["es2020"], - }, - "include": ["src", "src/**/*.json"] -} diff --git a/packages/paymaster/.esbuild.js b/packages/paymaster/.esbuild.js deleted file mode 100644 index ca355e346..000000000 --- a/packages/paymaster/.esbuild.js +++ /dev/null @@ -1,58 +0,0 @@ -const esbuildPluginTsc = require("esbuild-plugin-tsc"); -const esbuild = require("esbuild"); -const { dependencies, peerDependencies = {} } = require("./package.json"); -const { Generator } = require("npm-dts"); - -const COMMON_SETTINGS = { - entryPoints: ["src/index.ts"], - minify: true, - bundle: true, - plugins: [esbuildPluginTsc({ force: true })], -}; - -const ESM_SETTINGS = { - ...COMMON_SETTINGS, - sourcemap: true, - outfile: "dist/esm/index.js", - platform: "browser", - target: "esnext", - format: "esm", - mainFields: ["browser", "module", "main"], -}; -const buildForESM = async () => await esbuild.build(ESM_SETTINGS); - -const CJS_SETTINGS = { - ...COMMON_SETTINGS, - format: "cjs", - sourcemap: false, - outfile: "dist/cjs/index.js", - platform: "node", -}; - -const watchForCJS = async () => { - let ctx = await esbuild.context(CJS_SETTINGS); - await ctx.watch(); - await ctx.serve({ servedir: "dist/src" }); - console.log("watching..."); -}; - -const buildForCJS = async () => await esbuild.build(CJS_SETTINGS); -const buildForTYP = async () => await new Generator({ entry: "src/index.ts", output: "dist/types/index.d.ts" }).generate(); - -(async () => { - const buildType = process.argv.slice(2)[0]; - const shouldWatch = process.argv.slice(3)[0] === "--watch"; - if (!buildType) { - console.log("No build type provided"); - process.exit(1); - } - console.log(`Building for ${buildType}`); - if (buildType === "ESM") { - await buildForESM(); - } else if (buildType === "CJS") { - console.log("watching? " + shouldWatch); - await (shouldWatch ? watchForCJS : buildForCJS)(); - } else if (buildType === "TYP") { - await buildForTYP(); - } -})(); diff --git a/packages/paymaster/CHANGELOG.md b/packages/paymaster/CHANGELOG.md deleted file mode 100644 index f4db34b38..000000000 --- a/packages/paymaster/CHANGELOG.md +++ /dev/null @@ -1,78 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## 4.1.1 (2023-07-03) - -VERSION Bump Only. - -## 4.1.0 (2023-04-03) - -VERSION Bump Only. - -## 4.0.3 (2023-28-02) - -VERSION Bump Only. - -## 4.0.2 (2023-26-02) - -VERSION Bump Only. - -## 4.0.1 (2023-02-22) - -VERSION Bump Only. - -## 4.0.0 (2023-07-02) - -Export createPaymaster alias for static Paymaster.create call - -## 3.1.3 (2023-12-28) - -VERSION Bump Only. - -## 3.1.2 (2023-12-28) - -VERSION Bump Only. - -## 3.1.1 (2023-11-09) - -### Bug Fixes - -- lint warning and errors ([2135498](https://github.com/bcnmy/biconomy-client-sdk/commit/2135498896beb54d25add820c1521ffa22d5db7c)) - -## 3.1.0 (2023-09-20) - -Version Bump Only. - -## 3.0.0 (2023-08-28) - -Modular SDK - consists stable version of below updates done in Alphas. - -## 3.0.0-alpha.0 (2023-08-02) - -### Features - -- letting maxFee and maxPriority not be undefined([46b985c](https://github.com/bcnmy/biconomy-client-sdk/commit/46b985c75fd135f151c9ac4380a65438cccc6f39)) -- passing on paymasterAndData([ae267f1])(https://github.com/bcnmy/biconomy-client-sdk/commit/ae267f1a103f37856eb233a38db7063bfcc4cb45) -- handle undefined values([e53d4a7])(https://github.com/bcnmy/biconomy-client-sdk/commit/e53d4a78aded8c8802786173daf12b27d445d4a0) -- handling userOp null values([c89ac42])(https://github.com/bcnmy/biconomy-client-sdk/commit/c89ac42ae1d7fd985ef2396d925cc63ec5cf926b) -- using signature provided by userop([0c40641])(https://github.com/bcnmy/biconomy-client-sdk/commit/0c40641e4cd6133f7348bb3e3022f8ab78fe299b) - -# 3.1.0-alpha.0 (2023-07-24) - -VERSION Bump Only. - -## 3.0.0-alpha.0 (2023-07-12) - -### Bug Fixes - -- linting ([563befe](https://github.com/bcnmy/biconomy-client-sdk/commit/563befedcc37aee4c531e01809b47e559a33f526)) -- linting ([d2f5f1a](https://github.com/bcnmy/biconomy-client-sdk/commit/d2f5f1afadc2a561c4ef01c0821a25b9d7fe776e)) - -### Features - -- covert gas limits to numbers for making pm service call ([b1fe96f](https://github.com/bcnmy/biconomy-client-sdk/commit/b1fe96f7a312ceaf7aa689939b7c69718c710dd1)) -- get fee quote or data method in biconomy paymaster ([47748a6](https://github.com/bcnmy/biconomy-client-sdk/commit/47748a6384c2b74e1d9be4d570554098e1ac02e7)) -- update responses to support calculateGasLimits flag + update interfaces ([55bbd38](https://github.com/bcnmy/biconomy-client-sdk/commit/55bbd38b4ef8acaf8da1d52e36846557b134aba4)) -- using hybrid paymaster interface ([5fc56a7](https://github.com/bcnmy/biconomy-client-sdk/commit/5fc56a7db2de4a3f4bb87cd4d75584e79010b206)) diff --git a/packages/paymaster/Readme.md b/packages/paymaster/Readme.md deleted file mode 100644 index 562a790f6..000000000 --- a/packages/paymaster/Readme.md +++ /dev/null @@ -1,74 +0,0 @@ -# **Paymaster** - -ERC4337, Account abstraction, introduces the concept of Paymasters. These specialised entities play a pivotal role in revolutionising the traditional gas payment system in EVM transactions. Paymasters, acting as third-party intermediaries, possess the capability to sponsor gas fees for an account, provided specific predefined conditions are satisfied. - -## Installation - -Using `npm` package manager - -```bash -npm i @biconomy/paymaster -``` - -OR - -Using `yarn` package manager - -```bash -yarn add @biconomy/paymaster -``` - -**Usage** - -```typescript -// This is how you create paymaster instance in your dapp's -import { IPaymaster, createPaymaster } from "@biconomy/paymaster"; - -// Currently this package only exports Biconomy Paymaster which acts as a Hybrid paymaster for gas abstraction. You can sponsor user transactions but can also make users pay gas in supported ERC20 tokens. - -const paymaster = await createPaymaster({ - paymasterUrl: "", // you can get this value from biconomy dashboard. https://dashboard.biconomy.io -}); -``` - -**paymasterUrl** you can get this value from biconomy dashboard. - -Following are the methods that can be called on paymaster instance - -```typescript -export interface IHybridPaymaster<T> extends IPaymaster { - getPaymasterAndData(userOp: Partial<UserOperation>, paymasterServiceData?: T): Promise<PaymasterAndDataResponse>; - buildTokenApprovalTransaction(tokenPaymasterRequest: BiconomyTokenPaymasterRequest): Promise<Transaction>; - getPaymasterFeeQuotesOrData(userOp: Partial<UserOperation>, paymasterServiceData: FeeQuotesOrDataDto): Promise<FeeQuotesOrDataResponse>; -} -``` - -One can also build their own Paymaster API class and submit a PR or just provide instance of it in the account package / use standalone to generate paymasterAndData - -It should follow below Interface. - -```typescript -export interface IPaymaster { - // Implementing class may add extra parameter (for example paymasterServiceData with it's own type) in below function signature - getPaymasterAndData(userOp: Partial<UserOperation>): Promise<PaymasterAndDataResponse>; - getDummyPaymasterAndData(userOp: Partial<UserOperation>): Promise<string>; -} -``` - -### Below API methods can be used for Biconomy Hybrid paymaster - -**[getPaymasterAndData](https://bcnmy.github.io/biconomy-client-sdk/classes/Paymaster.html#getPaymasterAndData)** - -This function accepts a **`Partial<UserOperation>`** object that includes all properties of **`userOp`** except for the **`signature`** and **`paymasterAndData`** field. It returns **`paymasterAndData`** as part of the **`PaymasterAndDataResponse`** - -**[buildTokenApprovalTransaction](https://bcnmy.github.io/biconomy-client-sdk/classes/Paymaster.html#buildTokenApprovalTransaction)** - -This function is specifically used for token paymaster sponsorship. The primary purpose of this function is to create an approve transaction for paymaster that gets batched with the rest of your transactions. - -Note: You don't need to call this function. It will automatically get called as part of the **`buildTokenPaymasterUserOp`** function call. - -**[getPaymasterFeeQuotesOrData](https://bcnmy.github.io/biconomy-client-sdk/classes/Paymaster.html#getPaymasterFeeQuotesOrData)** - -This function is used to fetch quote information or paymaster data based on provided userOperation and paymasterServiceData. If explicit mode is not provided it tries for sponsorship first and then falls back to serving fee quotes for supported/requested token/s - -Note: This function can return **paymasterAndData** as well in case all of the policies checks get passed. diff --git a/packages/paymaster/package.json b/packages/paymaster/package.json deleted file mode 100644 index 2b6008747..000000000 --- a/packages/paymaster/package.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "name": "@biconomy/paymaster", - "version": "4.1.1", - "description": "Biconomy Paymaster to interact with Paymaster Services that interacts with ( veriying and token ) paymasters", - "main": "./dist/cjs/index.js", - "module": "./dist/esm/index.js", - "types": "./dist/types/index.d.ts", - "typings": "./dist/types/index.d.ts", - "exports": { - ".": { - "import": "./dist/esm/index.js", - "types": "./dist/types/index.d.ts", - "default": "./dist/cjs/index.js" - }, - "./package.json": "./package.json" - }, - "keywords": [ - "Ethereum", - "Veriying Paymaster", - "Token Paymaster", - "ERC4337", - "Gasless Transaction", - "Biconomy", - "SDK" - ], - "scripts": { - "unbuild": "rimraf dist *.tsbuildinfo", - "build:watch": "yarn build:tsc --watch", - "dist:minify": "esbuild ./dist/esm/**/*.js ./dist/esm/*.js --minify --outdir=./dist/esm --bundle=false --allow-overwrite", - "build": "yarn unbuild && yarn build:tsc", - "build:esbuild": "yarn build:esbuild:cjs && yarn build:esbuild:esm && yarn build:typ", - "build:tsc:cjs": "tsc --project tsconfig.build.json --module commonjs --outDir ./dist/cjs --removeComments --verbatimModuleSyntax false && echo > ./dist/cjs/package.json '{\"type\":\"commonjs\"}'", - "build:tsc:esm": "tsc --project tsconfig.build.json --module esnext --outDir ./dist/esm --removeComments && echo > ./dist/esm/package.json '{\"type\":\"module\"}'", - "build:esbuild:cjs": "node .esbuild.js CJS && echo > ./dist/cjs/package.json '{\"type\":\"commonjs\"}'", - "build:esbuild:esm": "node .esbuild.js ESM && echo > ./dist/esm/package.json '{\"type\":\"module\"}'", - "build:typ": "tsc --project tsconfig.build.json --module esnext --declarationDir ./dist/types --emitDeclarationOnly --declaration --declarationMap", - "build:tsc": "yarn build:tsc:cjs && yarn build:tsc:esm && yarn build:typ && yarn dist:minify", - "format": "prettier --write \"{src,tests}/**/*.ts\"", - "lint": "tslint -p tsconfig.json", - "test": "jest tests/**/*.spec.ts --runInBand" - }, - "author": "Biconomy", - "repository": { - "type": "git", - "url": "git+https://github.com/bcnmy/biconomy-client-sdk.git" - }, - "license": "MIT", - "files": [ - "dist/*", - "README.md" - ], - "publishConfig": { - "access": "public" - }, - "dependencies": { - "@alchemy/aa-core": "^3.1.1", - "@biconomy/common": "^4.1.1", - "viem": "^2.7.12" - }, - "devDependencies": { - "@types/node": "^20.11.10", - "esbuild": "^0.19.11", - "esbuild-plugin-tsc": "^0.4.0", - "npm-dts": "^1.3.12" - } -} diff --git a/packages/paymaster/src/index.ts b/packages/paymaster/src/index.ts deleted file mode 100644 index 4d78b3a0a..000000000 --- a/packages/paymaster/src/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { BiconomyPaymaster } from "./BiconomyPaymaster.js"; -export * from "./interfaces/IPaymaster.js"; -export * from "./interfaces/IHybridPaymaster.js"; -export * from "./utils/Types.js"; -export * from "./BiconomyPaymaster.js"; - -export const Paymaster = BiconomyPaymaster; -export const createPaymaster = Paymaster.create; diff --git a/packages/paymaster/src/interfaces/IHybridPaymaster.ts b/packages/paymaster/src/interfaces/IHybridPaymaster.ts deleted file mode 100644 index 5b73bfd5e..000000000 --- a/packages/paymaster/src/interfaces/IHybridPaymaster.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { type UserOperationStruct } from "@alchemy/aa-core"; -import { - FeeQuotesOrDataResponse, - BiconomyTokenPaymasterRequest, - FeeQuotesOrDataDto, - PaymasterAndDataResponse, - type Transaction, -} from "../utils/Types.js"; -import { IPaymaster } from "./IPaymaster.js"; - -export interface IHybridPaymaster<T> extends IPaymaster { - getPaymasterAndData(_userOp: Partial<UserOperationStruct>, _paymasterServiceData?: T): Promise<PaymasterAndDataResponse>; - getDummyPaymasterAndData(_userOp: Partial<UserOperationStruct>, _paymasterServiceData?: T): Promise<string>; - buildTokenApprovalTransaction(_tokenPaymasterRequest: BiconomyTokenPaymasterRequest): Promise<Transaction>; - getPaymasterFeeQuotesOrData(_userOp: Partial<UserOperationStruct>, _paymasterServiceData: FeeQuotesOrDataDto): Promise<FeeQuotesOrDataResponse>; -} diff --git a/packages/paymaster/src/interfaces/IPaymaster.ts b/packages/paymaster/src/interfaces/IPaymaster.ts deleted file mode 100644 index b9938797d..000000000 --- a/packages/paymaster/src/interfaces/IPaymaster.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { type UserOperationStruct } from "@alchemy/aa-core"; -import { PaymasterAndDataResponse } from "../utils/Types.js"; - -export interface IPaymaster { - // Implementing class may add extra parameter (for example paymasterServiceData with it's own type) in below function signature - getPaymasterAndData(_userOp: Partial<UserOperationStruct>): Promise<PaymasterAndDataResponse>; - getDummyPaymasterAndData(_userOp: Partial<UserOperationStruct>): Promise<string>; -} diff --git a/packages/paymaster/src/utils/Types.ts b/packages/paymaster/src/utils/Types.ts deleted file mode 100644 index 9d5f849d4..000000000 --- a/packages/paymaster/src/utils/Types.ts +++ /dev/null @@ -1,176 +0,0 @@ -import { BigNumberish } from "@alchemy/aa-core"; -export type Hex = `0x${string}`; - -export type PaymasterServiceErrorResponse = { - jsonrpc: string; - id: number; - error: JsonRpcError; -}; - -export type JsonRpcResponse = { - jsonrpc: string; - id: number; - result?: any; - error?: JsonRpcError; -}; - -export type JsonRpcError = { - code: string; - message: string; - data: any; -}; - -export type PaymasterConfig = { - paymasterUrl: string; - strictMode?: boolean; -}; - -export type SponsorUserOperationDto = { - /** mode: sponsored or erc20 */ - mode: PaymasterMode; - /** Always recommended, especially when using token paymaster */ - calculateGasLimits?: boolean; - /** Expiry duration in seconds */ - expiryDuration?: number; - /** Webhooks to be fired after user op is sent */ - webhookData?: Record<string, any>; - /** Smart account meta data */ - smartAccountInfo?: SmartAccountData; - /** the fee-paying token address */ - feeTokenAddress?: string; -}; - -export type FeeQuotesOrDataDto = { - /** mode: sponsored or erc20 */ - mode?: PaymasterMode; - /** Expiry duration in seconds */ - expiryDuration?: number; - /** Always recommended, especially when using token paymaster */ - calculateGasLimits?: boolean; - /** List of tokens to be used for fee quotes, if ommitted fees for all supported will be returned */ - tokenList?: string[]; - /** preferredToken: Can be ommitted to return all quotes */ - preferredToken?: string; - /** Webhooks to be fired after user op is sent */ - webhookData?: Record<string, any>; - /** Smart account meta data */ - smartAccountInfo?: SmartAccountData; -}; - -export type FeeQuoteParams = { - tokenList?: string[]; - preferredToken?: string; -}; - -export type FeeTokenInfo = { - feeTokenAddress: string; -}; - -export type SponsorpshipInfo = { - /** Webhooks to be fired after user op is sent */ - webhookData?: Record<string, any>; - /** Smart account meta data */ - smartAccountInfo: SmartAccountData; -}; - -export type SmartAccountData = { - /** name: Name of the smart account */ - name: string; - /** version: Version of the smart account */ - version: string; -}; - -export type PaymasterFeeQuote = { - /** symbol: Token symbol */ - symbol: string; - /** tokenAddress: Token address */ - tokenAddress: string; - /** decimal: Token decimal */ - decimal: number; - logoUrl?: string; - /** maxGasFee: in wei */ - maxGasFee: number; - /** maxGasFee: in dollars */ - maxGasFeeUSD?: number; - usdPayment?: number; - /** The premium paid on the token */ - premiumPercentage: number; - /** validUntil: Unix timestamp */ - validUntil?: number; -}; - -export type BiconomyTokenPaymasterRequest = { - /** The feeQuote to be used for the transaction */ - feeQuote: PaymasterFeeQuote; - /** The address of the spender. This is usually set to {@link FeeQuotesOrDataResponse.tokenPaymasterAddress} */ - spender: Hex; - /** Not recommended */ - maxApproval?: boolean; - /* skip option to patch callData if approval is already given to the paymaster */ - skipPatchCallData?: boolean; -}; - -export type FeeQuotesOrDataResponse = { - /** Array of results from the paymaster */ - feeQuotes?: PaymasterFeeQuote[]; - /** Normally set to the spender in the proceeding call to send the tx */ - tokenPaymasterAddress?: Hex; - /** Relevant Data returned from the paymaster */ - paymasterAndData?: Uint8Array | Hex; - /* Gas overhead of this UserOperation */ - preVerificationGas?: BigNumberish; - /* Actual gas used by the validation of this UserOperation */ - verificationGasLimit?: BigNumberish; - /* Value used by inner account execution */ - callGasLimit?: BigNumberish; -}; - -export type PaymasterAndDataResponse = { - paymasterAndData: Hex; - /* Gas overhead of this UserOperation */ - preVerificationGas: number; - /* Actual gas used by the validation of this UserOperation */ - verificationGasLimit: number; - /* Value used by inner account execution */ - callGasLimit: number; -}; - -export enum PaymasterMode { - ERC20 = "ERC20", - SPONSORED = "SPONSORED", -} - -// Converted to JsonRpcResponse with strict type -export type EstimateUserOpGasResponse = { - jsonrpc: string; - id: number; - result: UserOpGasResponse; - error?: JsonRpcError; -}; - -export type UserOpGasResponse = { - paymasterAndData: string; - /* Gas overhead of this UserOperation */ - preVerificationGas: string; - maxPriorityFeePerGas: string; - maxFeePerGas: string; - /* Actual gas used by the validation of this UserOperation */ - verificationGasLimit: string; - callGasLimit: string; -}; - -type RequireAtLeastOne<T, Keys extends keyof T = keyof T> = Pick<T, Exclude<keyof T, Keys>> & - { - [K in Keys]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<Keys, K>>>; - }[Keys]; - -type ValueOrData = RequireAtLeastOne< - { - value: BigNumberish | string; - data: string; - }, - "value" | "data" ->; -export type Transaction = { - to: string; -} & ValueOrData; diff --git a/packages/paymaster/tests/paymaster.e2e.spec.ts b/packages/paymaster/tests/paymaster.e2e.spec.ts deleted file mode 100644 index 3a634f491..000000000 --- a/packages/paymaster/tests/paymaster.e2e.spec.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { TestData } from "../../../tests"; - -describe("Paymaster Unit Tests", () => { - let mumbai: TestData; - let baseSepolia: TestData; - - beforeEach(() => { - // @ts-ignore: Comes from setup-e2e-tests - [mumbai, baseSepolia] = testDataPerChain; - }); - - it("should have chain data for mumbai", () => { - expect(mumbai).toHaveProperty("chainId"); - }); - - it("should also have chain data for base", () => { - expect(baseSepolia).toHaveProperty("chainId"); - }); -}); diff --git a/packages/paymaster/tests/paymaster.spec.ts b/packages/paymaster/tests/paymaster.spec.ts deleted file mode 100644 index 0b3508a6b..000000000 --- a/packages/paymaster/tests/paymaster.spec.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { TestData } from "../../../tests"; - -describe("Paymaster Unit Tests", () => { - let ganache: TestData; - - beforeEach(() => { - // @ts-ignore: Comes from setup-unit-tests - [ganache] = testDataPerChain; - }); - - it("should have chain data for mumbai", () => { - expect(ganache).toHaveProperty("chainId"); - }); -}); diff --git a/packages/paymaster/tsconfig.build.json b/packages/paymaster/tsconfig.build.json deleted file mode 100644 index 4ac8b8026..000000000 --- a/packages/paymaster/tsconfig.build.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "display": "Build", - "compilerOptions": { - "lib": ["es2022", "dom"], - "target": "es2021", - "types": ["node"], - "allowJs": false, - "skipLibCheck": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "module": "esnext", - "moduleResolution": "node", - "resolveJsonModule": true, - "isolatedModules": true, - "verbatimModuleSyntax": false, - "useDefineForClassFields": true, - "noFallthroughCasesInSwitch": true, - "noImplicitReturns": true, - "useUnknownInCatchVariables": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "declaration": true, - "inlineSources": true, - "noEmit": false, - "sourceMap": true - }, - "exclude": ["**/*/node_modules", "**/*/tests", "tests"], - "include": ["src"] -} \ No newline at end of file diff --git a/packages/paymaster/tsconfig.json b/packages/paymaster/tsconfig.json deleted file mode 100644 index d6269c535..000000000 --- a/packages/paymaster/tsconfig.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../../tsconfig.settings.json", - "compilerOptions": { - "composite": true, - "outDir": "dist", - "baseUrl": "src", - "resolveJsonModule": true, - "esModuleInterop": true, - "types": ["node"] - }, - "include": ["src", "src/**/*.json"] -} diff --git a/packages/transak/.esbuild.js b/packages/transak/.esbuild.js deleted file mode 100644 index ca355e346..000000000 --- a/packages/transak/.esbuild.js +++ /dev/null @@ -1,58 +0,0 @@ -const esbuildPluginTsc = require("esbuild-plugin-tsc"); -const esbuild = require("esbuild"); -const { dependencies, peerDependencies = {} } = require("./package.json"); -const { Generator } = require("npm-dts"); - -const COMMON_SETTINGS = { - entryPoints: ["src/index.ts"], - minify: true, - bundle: true, - plugins: [esbuildPluginTsc({ force: true })], -}; - -const ESM_SETTINGS = { - ...COMMON_SETTINGS, - sourcemap: true, - outfile: "dist/esm/index.js", - platform: "browser", - target: "esnext", - format: "esm", - mainFields: ["browser", "module", "main"], -}; -const buildForESM = async () => await esbuild.build(ESM_SETTINGS); - -const CJS_SETTINGS = { - ...COMMON_SETTINGS, - format: "cjs", - sourcemap: false, - outfile: "dist/cjs/index.js", - platform: "node", -}; - -const watchForCJS = async () => { - let ctx = await esbuild.context(CJS_SETTINGS); - await ctx.watch(); - await ctx.serve({ servedir: "dist/src" }); - console.log("watching..."); -}; - -const buildForCJS = async () => await esbuild.build(CJS_SETTINGS); -const buildForTYP = async () => await new Generator({ entry: "src/index.ts", output: "dist/types/index.d.ts" }).generate(); - -(async () => { - const buildType = process.argv.slice(2)[0]; - const shouldWatch = process.argv.slice(3)[0] === "--watch"; - if (!buildType) { - console.log("No build type provided"); - process.exit(1); - } - console.log(`Building for ${buildType}`); - if (buildType === "ESM") { - await buildForESM(); - } else if (buildType === "CJS") { - console.log("watching? " + shouldWatch); - await (shouldWatch ? watchForCJS : buildForCJS)(); - } else if (buildType === "TYP") { - await buildForTYP(); - } -})(); diff --git a/packages/transak/CHANGELOG.md b/packages/transak/CHANGELOG.md deleted file mode 100644 index 4af2afc36..000000000 --- a/packages/transak/CHANGELOG.md +++ /dev/null @@ -1,62 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## 4.1.1 (2023-07-03) - -VERSION Bump Only. - -## 4.1.0 (2023-04-03) - -VERSION Bump Only. - -## 4.0.3 (2023-28-02) - -VERSION Bump Only. - -## 4.0.2 (2023-26-02) - -VERSION Bump Only. - -## 4.0.1 (2023-26-02) - -VERSION Bump Only. - -## 4.0.0 (2023-12-28) - -VERSION Bump Only. - -## 3.1.3 (2023-12-28) - -VERSION Bump Only. - -## 3.1.2 (2023-12-28) - -VERSION Bump Only. - -## 3.1.1 (2023-11-09) - -VERSION Bump Only. - -## 3.1.0 (2023-09-20) - -### Bug Fixes - -- lint warning and errors ([2135498](https://github.com/bcnmy/biconomy-client-sdk/commit/2135498896beb54d25add820c1521ffa22d5db7c)) - -# 3.0.0 (2023-08-28) - -VERSION Bump Only. - -## 2.0.0 (2023-04-07) - -### Features - -- transak wrapper module ([102e6eb](https://github.com/bcnmy/biconomy-client-sdk/commit/102e6eb5f179e4aff77d1e91973e0b32fa7b8f9a)) - -## 1.0.0 (2023-01-03) - -### Features - -- transak wrapper module ([102e6eb](https://github.com/bcnmy/biconomy-client-sdk/commit/102e6eb5f179e4aff77d1e91973e0b32fa7b8f9a)) diff --git a/packages/transak/README.md b/packages/transak/README.md deleted file mode 100644 index ea5b73266..000000000 --- a/packages/transak/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# `@biconomy/transak` - -> A library to import the transak for web directly from [Biconomy SDK](https://github.com/bcnmy/biconomy-client-sdk) - -## Usage - -No need to create api key from transak dashboard. - -```ts -import Transak from "@biconomy/transak"; -const transak = new Transak("STAGING"); -transak.init(); -``` diff --git a/packages/transak/package.json b/packages/transak/package.json deleted file mode 100644 index 4232ed243..000000000 --- a/packages/transak/package.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "name": "@biconomy/transak", - "version": "4.1.1", - "description": "transak for biconomy sdk", - "main": "./dist/cjs/index.js", - "module": "./dist/esm/index.js", - "types": "./dist/types/index.d.ts", - "typings": "./dist/types/index.d.ts", - "exports": { - ".": { - "import": "./dist/esm/index.js", - "types": "./dist/types/index.d.ts", - "default": "./dist/cjs/index.js" - }, - "./package.json": "./package.json" - }, - "keywords": [ - "legos", - "batching", - "one-click", - "cross-chain", - "transak" - ], - "author": "Biconomy", - "homepage": "https://github.com/bcnmy/biconomy-client-sdk#readme", - "license": "MIT", - "files": [ - "dist/*", - "README.md" - ], - "repository": { - "type": "git", - "url": "git+https://github.com/bcnmy/biconomy-client-sdk.git" - }, - "scripts": { - "unbuild": "rimraf dist *.tsbuildinfo", - "build:watch": "yarn build:tsc --watch", - "dist:minify": "esbuild ./dist/esm/**/*.js ./dist/esm/*.js --minify --outdir=./dist/esm --bundle=false --allow-overwrite", - "build": "yarn unbuild && yarn build:tsc", - "build:esbuild": "yarn build:esbuild:cjs && yarn build:esbuild:esm && yarn build:typ", - "build:tsc:cjs": "tsc --project tsconfig.build.json --module commonjs --outDir ./dist/cjs --removeComments --verbatimModuleSyntax false && echo > ./dist/cjs/package.json '{\"type\":\"commonjs\"}'", - "build:tsc:esm": "tsc --project tsconfig.build.json --module esnext --outDir ./dist/esm --removeComments && echo > ./dist/esm/package.json '{\"type\":\"module\"}'", - "build:esbuild:cjs": "node .esbuild.js CJS && echo > ./dist/cjs/package.json '{\"type\":\"commonjs\"}'", - "build:esbuild:esm": "node .esbuild.js ESM && echo > ./dist/esm/package.json '{\"type\":\"module\"}'", - "build:typ": "tsc --project tsconfig.build.json --module esnext --declarationDir ./dist/types --emitDeclarationOnly --declaration --declarationMap", - "build:tsc": "yarn build:tsc:cjs && yarn build:tsc:esm && yarn build:typ && yarn dist:minify", - "format": "prettier --write \"{src,tests}/**/*.ts\"", - "lint": "tslint -p tsconfig.json" - }, - "bugs": { - "url": "https://github.com/bcnmy/biconomy-client-sdk/issues" - }, - "publishConfig": { - "access": "public" - }, - "dependencies": { - "@transak/transak-sdk": "^1.2.3" - }, - "devDependencies": { - "@types/node": "^20.11.10", - "esbuild": "^0.19.11", - "esbuild-plugin-tsc": "^0.4.0", - "npm-dts": "^1.3.12" - } -} diff --git a/packages/transak/src/index.ts b/packages/transak/src/index.ts deleted file mode 100644 index 36f5dcfd9..000000000 --- a/packages/transak/src/index.ts +++ /dev/null @@ -1,42 +0,0 @@ -/* eslint-disable @typescript-eslint/ban-ts-comment */ -// @ts-ignore -import transakSDK from "@transak/transak-sdk"; -import { ITransakDto, environments } from "./interface.js"; - -class TransakSDK { - apiKey: string; - - /* eslint-disable @typescript-eslint/no-explicit-any */ - transak: any; - - constructor(environment: environments, transakData: ITransakDto = {}) { - if (environment === "PRODUCTION") { - this.apiKey = "f7d64c91-8f89-4018-9577-9098e42290af"; - } else { - this.apiKey = "c71ecd4a-0819-46a7-8d63-c8b7148aaf63"; - } - const transak = new transakSDK({ - apiKey: this.apiKey, - widgetHeight: "625px", - widgetWidth: "500px", - environment: environment, - ...transakData, - }); - this.transak = transak; - } - - init(): void { - try { - this.transak.init(); - /* eslint-disable @typescript-eslint/no-explicit-any */ - } catch (err: any) { - throw new Error(`Error while init transakSDK ${err}`); - } - } - - getTransak(): any { - return this.transak; - } -} - -export default TransakSDK; diff --git a/packages/transak/src/interface.ts b/packages/transak/src/interface.ts deleted file mode 100644 index fd1218340..000000000 --- a/packages/transak/src/interface.ts +++ /dev/null @@ -1,64 +0,0 @@ -export type environments = "PRODUCTION" | "STAGING"; - -export interface IConfigBasic { - // apiKey: string - // environment: environments - redirectURL?: string; - cryptoCurrencyCode?: string; - fiatCurrencyCode?: string; - themeColor?: string; - defaultCryptoCurrency?: string; - defaultFiatCurrency?: string; - walletAddress?: string; - fiatAmount?: number; - defaultFiatAmount?: number; - defaultCryptoAmount?: number; - fiatCurrency?: string; - countryCode?: string; - paymentMethod?: string; - defaultPaymentMethod?: string; - isAutoFillUserData?: boolean; - isFeeCalculationHidden?: boolean; - email?: string; - disablePaymentMethods?: string; - partnerOrderId?: string; - partnerCustomerId?: string; - exchangeScreenTitle?: string; - hideMenu?: boolean; - accessToken?: string; - hideExchangeScreen?: boolean; - isDisableCrypto?: boolean; - disableWalletAddressForm?: boolean; - defaultNetwork?: string; - network?: string; - widgetWidth?: string | number; - widgetHeight?: string | number; -} - -export interface ITransakDto extends IConfigBasic { - networks?: string; - cryptoCurrencyList?: string; - userData?: { - firstName: string; - lastName: string; - email: string; - mobileNumber: string; - dob: string; - address: { - addressLine1: string; - addressLine2: string; - city: string; - state: string; - postCode: string; - countryCode: string; - }; - }; - walletAddressesData?: { - networks?: { - [key: string]: { address: string; addressAdditionalData?: string }; - }; - coins?: { - [key: string]: { address: string; addressAdditionalData?: string }; - }; - }; -} diff --git a/packages/transak/tests/transak.spec.ts b/packages/transak/tests/transak.spec.ts deleted file mode 100644 index 4c5cad00c..000000000 --- a/packages/transak/tests/transak.spec.ts +++ /dev/null @@ -1,5 +0,0 @@ -describe("Transak Tests", () => { - it("should have a basic test", () => { - expect(true).toBe(true); - }); -}); diff --git a/packages/transak/tsconfig.build.json b/packages/transak/tsconfig.build.json deleted file mode 100644 index 4ac8b8026..000000000 --- a/packages/transak/tsconfig.build.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "display": "Build", - "compilerOptions": { - "lib": ["es2022", "dom"], - "target": "es2021", - "types": ["node"], - "allowJs": false, - "skipLibCheck": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "module": "esnext", - "moduleResolution": "node", - "resolveJsonModule": true, - "isolatedModules": true, - "verbatimModuleSyntax": false, - "useDefineForClassFields": true, - "noFallthroughCasesInSwitch": true, - "noImplicitReturns": true, - "useUnknownInCatchVariables": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "declaration": true, - "inlineSources": true, - "noEmit": false, - "sourceMap": true - }, - "exclude": ["**/*/node_modules", "**/*/tests", "tests"], - "include": ["src"] -} \ No newline at end of file diff --git a/packages/transak/tsconfig.json b/packages/transak/tsconfig.json deleted file mode 100644 index d9b305a9a..000000000 --- a/packages/transak/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../../tsconfig.settings.json", - "compilerOptions": { - "composite": true, - "outDir": "dist", - "baseUrl": "src", - "resolveJsonModule": true, - "esModuleInterop": true, - "lib": ["es2020"], - "types": ["node"] - }, - "include": ["src", "src/**/*.json"] -} diff --git a/rebuild.sh b/rebuild.sh deleted file mode 100755 index 39c4c1a94..000000000 --- a/rebuild.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/sh -rm -rf package-lock.json -rm -rf yarn.lock -rm -rf node_modules - -rm -rf packages/account/node_modules -rm -rf packages/account/yarn.lock -rm -rf packages/account/package-lock.json -rm -rf packages/account/dist - -rm -rf packages/bundler/node_modules -rm -rf packages/bundler/yarn.lock -rm -rf packages/bundler/package-lock.json -rm -rf packages/bundler/dist - -rm -rf packages/common/node_modules -rm -rf packages/common/yarn.lock -rm -rf packages/common/package-lock.json -rm -rf packages/common/dist - -rm -rf packages/paymaster/node_modules -rm -rf packages/paymaster/yarn.lock -rm -rf packages/paymaster/package-lock.json -rm -rf packages/paymaster/dist - -rm -rf packages/modules/node_modules -rm -rf packages/modules/yarn.lock -rm -rf packages/modules/package-lock.json -rm -rf packages/modules/dist - -rm -rf packages/transak/node_modules -rm -rf packages/transak/yarn.lock -rm -rf packages/transak/package-lock.json -rm -rf packages/transak/dist - -rm -rf packages/particle-auth/node_modules -rm -rf packages/particle-auth/yarn.lock -rm -rf packages/particle-auth/package-lock.json -rm -rf packages/particle-auth/dist - -#npx lerna bootstrap --force-local -#npm run build -#npm link \ No newline at end of file diff --git a/src/account/BaseSmartContractAccount.ts b/src/account/BaseSmartContractAccount.ts new file mode 100644 index 000000000..c6b0568ff --- /dev/null +++ b/src/account/BaseSmartContractAccount.ts @@ -0,0 +1,354 @@ +import { + http, + type Address, + type GetContractReturnType, + type Hash, + type Hex, + type PublicClient, + createPublicClient, + getContract, + trim +} from "viem" +import { EntryPointAbi } from "./abi/EntryPointAbi.js" +import { Logger, type SmartAccountSigner, getChain } from "./index.js" +import { DEFAULT_ENTRYPOINT_ADDRESS } from "./utils/Constants.js" +import type { + BasSmartContractAccountProps, + BatchUserOperationCallData, + ISmartContractAccount, + SignTypedDataParams +} from "./utils/Types.js" +import { wrapSignatureWith6492 } from "./utils/Utils.js" + +export enum DeploymentState { + UNDEFINED = "0x0", + NOT_DEPLOYED = "0x1", + DEPLOYED = "0x2" +} + +export abstract class BaseSmartContractAccount< + TSigner extends SmartAccountSigner = SmartAccountSigner +> implements ISmartContractAccount<TSigner> +{ + protected factoryAddress: Address + + protected deploymentState: DeploymentState = DeploymentState.UNDEFINED + + protected accountAddress?: Address + + protected accountInitCode?: Hex + + protected signer: TSigner + + protected entryPoint: GetContractReturnType< + typeof EntryPointAbi, + PublicClient + > + + protected entryPointAddress: Address + + readonly rpcProvider: PublicClient + + constructor(params: BasSmartContractAccountProps) { + this.entryPointAddress = + params.entryPointAddress ?? DEFAULT_ENTRYPOINT_ADDRESS + + this.rpcProvider = createPublicClient({ + chain: params.viemChain ?? getChain(params.chainId), + transport: http( + params.rpcUrl || getChain(params.chainId).rpcUrls.default.http[0] + ) + }) as PublicClient + + this.accountAddress = params.accountAddress + this.factoryAddress = params.factoryAddress + this.signer = params.signer as TSigner + this.accountInitCode = params.initCode + + this.entryPoint = getContract({ + address: this.entryPointAddress, + abi: EntryPointAbi, + client: this.rpcProvider as PublicClient + }) + } + + //#region abstract-methods + + /** + * This method should return a signature that will not `revert` during validation. + * It does not have to pass validation, just not cause the contract to revert. + * This is required for gas estimation so that the gas estimate are accurate. + * + */ + abstract getDummySignature(): Hash + + /** + * this method should return the abi encoded function data for a call to your contract's `execute` method + * + * @param target -- equivalent to `to` in a normal transaction + * @param value -- equivalent to `value` in a normal transaction + * @param data -- equivalent to `data` in a normal transaction + * @returns abi encoded function data for a call to your contract's `execute` method + */ + abstract encodeExecute( + target: string, + value: bigint, + data: string + ): Promise<Hash> + + /** + * this should return an ERC-191 compliant message and is used to sign UO Hashes + * + * @param msg -- the message to sign + */ + abstract signMessage(msg: string | Uint8Array): Promise<Hash> + + /** + * this should return the init code that will be used to create an account if one does not exist. + * This is the concatenation of the account's factory address and the abi encoded function data of the account factory's `createAccount` method. + * https://github.com/eth-infinitism/account-abstraction/blob/abff2aca61a8f0934e533d0d352978055fddbd96/contracts/core/SenderCreator.sol#L12 + */ + protected abstract getAccountInitCode(): Promise<Hash> + + //#endregion abstract-methods + + //#region optional-methods + + /** + * If your account handles 1271 signatures of personal_sign differently + * than it does UserOperations, you can implement two different approaches to signing + * + * @param uoHash -- The hash of the UserOperation to sign + * @returns the signature of the UserOperation + */ + async signUserOperationHash(uoHash: Hash): Promise<Hash> { + return this.signMessage(uoHash) + } + + /** + * If your contract supports signing and verifying typed data, + * you should implement this method. + * + * @param _params -- Typed Data params to sign + */ + async signTypedData(_params: SignTypedDataParams): Promise<`0x${string}`> { + throw new Error("signTypedData not supported") + } + + /** + * This method should wrap the result of `signMessage` as per + * [EIP-6492](https://eips.ethereum.org/EIPS/eip-6492) + * + * @param msg -- the message to sign + */ + async signMessageWith6492(msg: string | Uint8Array): Promise<`0x${string}`> { + const [isDeployed, signature] = await Promise.all([ + this.isAccountDeployed(), + this.signMessage(msg) + ]) + + return this.create6492Signature(isDeployed, signature) + } + + /** + * Similar to the signMessageWith6492 method above, + * this method should wrap the result of `signTypedData` as per + * [EIP-6492](https://eips.ethereum.org/EIPS/eip-6492) + * + * @param params -- Typed Data params to sign + */ + async signTypedDataWith6492( + params: SignTypedDataParams + ): Promise<`0x${string}`> { + const [isDeployed, signature] = await Promise.all([ + this.isAccountDeployed(), + this.signTypedData(params) + ]) + + return this.create6492Signature(isDeployed, signature) + } + + /** + * Not all contracts support batch execution. + * If your contract does, this method should encode a list of + * transactions into the call data that will be passed to your + * contract's batch execution method. + * + * @param _txs -- the transactions to batch execute + */ + async encodeBatchExecute( + _txs: BatchUserOperationCallData + ): Promise<`0x${string}`> { + throw new Error("Batch execution not supported") + } + + /** + * If your contract supports UUPS, you can implement this method which can be + * used to upgrade the implementation of the account. + * + * @param upgradeToImplAddress -- the implementation address of the contract you want to upgrade to + * @param upgradeToInitData -- the initialization data required by that account + */ + encodeUpgradeToAndCall = async ( + _upgradeToImplAddress: Address, + _upgradeToInitData: Hex + ): Promise<Hex> => { + throw new Error("Upgrade ToAndCall Not Supported") + } + //#endregion optional-methods + + // Extra implementations + async getNonce(): Promise<bigint> { + if (!(await this.isAccountDeployed())) { + return 0n + } + const address = await this.getAddress() + return this.entryPoint.read.getNonce([address, BigInt(0)]) + } + + async getInitCode(): Promise<Hex> { + if (this.deploymentState === DeploymentState.DEPLOYED) { + return "0x" + } + + const contractCode = await this.rpcProvider.getBytecode({ + address: await this.getAddress() + }) + + if ((contractCode?.length ?? 0) > 2) { + this.deploymentState = DeploymentState.DEPLOYED + return "0x" + } + + this.deploymentState = DeploymentState.NOT_DEPLOYED + + return this._getAccountInitCode() + } + + async getAddress(): Promise<Address> { + if (!this.accountAddress) { + const initCode = await this._getAccountInitCode() + Logger.log("[BaseSmartContractAccount](getAddress) initCode: ", initCode) + try { + await this.entryPoint.simulate.getSenderAddress([initCode]) + } catch (err: any) { + Logger.log( + "[BaseSmartContractAccount](getAddress) getSenderAddress err: ", + err + ) + + if (err.cause?.data?.errorName === "SenderAddressResult") { + this.accountAddress = err.cause.data.args[0] as Address + Logger.log( + "[BaseSmartContractAccount](getAddress) entryPoint.getSenderAddress result:", + this.accountAddress + ) + return this.accountAddress + } + + if (err.details === "Invalid URL") { + throw new Error("Invalid URL") + } + } + + throw new Error("Failed to get counterfactual account address") + } + + return this.accountAddress + } + + extend = <R>(fn: (self: this) => R): this & R => { + const extended = fn(this) as any + // this should make it so extensions can't overwrite the base methods + for (const key in this) { + delete extended[key] + } + return Object.assign(this, extended) + } + + getSigner(): TSigner { + return this.signer + } + + getFactoryAddress(): Address { + return this.factoryAddress + } + + getEntryPointAddress(): Address { + return this.entryPointAddress + } + + async isAccountDeployed(): Promise<boolean> { + return (await this.getDeploymentState()) === DeploymentState.DEPLOYED + } + + async getDeploymentState(): Promise<DeploymentState> { + if (this.deploymentState === DeploymentState.UNDEFINED) { + const initCode = await this.getInitCode() + return initCode === "0x" + ? DeploymentState.DEPLOYED + : DeploymentState.NOT_DEPLOYED + } + return this.deploymentState + } + + /** + * https://eips.ethereum.org/EIPS/eip-4337#first-time-account-creation + * The initCode field (if non-zero length) is parsed as a 20-byte address, + * followed by calldata to pass to this address. + * The factory address is the first 40 char after the 0x, and the callData is the rest. + */ + protected async parseFactoryAddressFromAccountInitCode(): Promise< + [Address, Hex] + > { + const initCode = await this._getAccountInitCode() + const factoryAddress = `0x${initCode.substring(2, 42)}` as Address + const factoryCalldata = `0x${initCode.substring(42)}` as Hex + return [factoryAddress, factoryCalldata] + } + + protected async getImplementationAddress(): Promise<"0x0" | Address> { + const accountAddress = await this.getAddress() + + const storage = await this.rpcProvider.getStorageAt({ + address: accountAddress, + // This is the default slot for the implementation address for Proxies + slot: "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + }) + + if (storage == null) { + throw new Error( + "Failed to get storage slot 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + ) + } + + return trim(storage) + } + + private async _getAccountInitCode(): Promise<Hash> { + return this.accountInitCode ?? this.getAccountInitCode() + } + + private async create6492Signature( + isDeployed: boolean, + signature: Hash + ): Promise<Hash> { + if (isDeployed) { + return signature + } + + const [factoryAddress, factoryCalldata] = + await this.parseFactoryAddressFromAccountInitCode() + + Logger.log( + `[BaseSmartContractAccount](create6492Signature)\ + factoryAddress: ${factoryAddress}, factoryCalldata: ${factoryCalldata}` + ) + + return wrapSignatureWith6492({ + factoryAddress, + factoryCalldata, + signature + }) + } +} diff --git a/src/account/BiconomySmartAccountV2.ts b/src/account/BiconomySmartAccountV2.ts new file mode 100644 index 000000000..b6899f1b7 --- /dev/null +++ b/src/account/BiconomySmartAccountV2.ts @@ -0,0 +1,1930 @@ +import { + http, + type GetContractReturnType, + type Hex, + type PublicClient, + concat, + concatHex, + createPublicClient, + decodeFunctionData, + encodeAbiParameters, + encodeFunctionData, + encodePacked, + formatUnits, + getContract, + getCreate2Address, + keccak256, + parseAbi, + parseAbiParameters, + toBytes, + toHex +} from "viem" +import type { IBundler } from "../bundler/IBundler.js" +import { + Bundler, + type UserOpResponse, + extractChainIdFromBundlerUrl +} from "../bundler/index.js" +import { + BaseValidationModule, + type ModuleInfo, + type SendUserOpParams, + createECDSAOwnershipValidationModule +} from "../modules" +import { + BiconomyPaymaster, + type FeeQuotesOrDataDto, + type FeeQuotesOrDataResponse, + type IHybridPaymaster, + type IPaymaster, + Paymaster, + PaymasterMode, + type SponsorUserOperationDto +} from "../paymaster" +import { + type BigNumberish, + Logger, + type SmartAccountSigner, + type StateOverrideSet, + type UserOperationStruct, + convertSigner, + getChain +} from "./" +import { BaseSmartContractAccount } from "./BaseSmartContractAccount.js" +import { AccountResolverAbi } from "./abi/AccountResolver.js" +import { BiconomyFactoryAbi } from "./abi/Factory.js" +import { BiconomyAccountAbi } from "./abi/SmartAccount.js" +import { + ADDRESS_RESOLVER_ADDRESS, + ADDRESS_ZERO, + BICONOMY_IMPLEMENTATION_ADDRESSES_BY_VERSION, + DEFAULT_BICONOMY_FACTORY_ADDRESS, + DEFAULT_ENTRYPOINT_ADDRESS, + DEFAULT_FALLBACK_HANDLER_ADDRESS, + ERC20_ABI, + ERROR_MESSAGES, + MAGIC_BYTES, + NATIVE_TOKEN_ALIAS, + PROXY_CREATION_CODE +} from "./utils/Constants.js" +import type { + BalancePayload, + BatchUserOperationCallData, + BiconomySmartAccountV2Config, + BiconomySmartAccountV2ConfigConstructorProps, + BiconomyTokenPaymasterRequest, + BuildUserOpOptions, + CounterFactualAddressParam, + NonceOptions, + PaymasterUserOperationDto, + QueryParamsForAddressResolver, + SimulationType, + SupportedToken, + Transaction, + WithdrawalRequest +} from "./utils/Types.js" +import { + addressEquals, + compareChainIds, + isNullOrUndefined, + isValidRpcUrl, + packUserOp +} from "./utils/Utils.js" + +type UserOperationKey = keyof UserOperationStruct + +export class BiconomySmartAccountV2 extends BaseSmartContractAccount { + private SENTINEL_MODULE = "0x0000000000000000000000000000000000000001" + + private index: number + + private chainId: number + + private provider: PublicClient + + paymaster?: IPaymaster + + bundler?: IBundler + + private accountContract?: GetContractReturnType< + typeof BiconomyAccountAbi, + PublicClient + > + + private defaultFallbackHandlerAddress: Hex + + private implementationAddress: Hex + + private scanForUpgradedAccountsFromV1!: boolean + + private maxIndexForScan!: number + + // Validation module responsible for account deployment initCode. This acts as a default authorization module. + defaultValidationModule!: BaseValidationModule + + // Deployed Smart Account can have more than one module enabled. When sending a transaction activeValidationModule is used to prepare and validate userOp signature. + activeValidationModule!: BaseValidationModule + + private constructor( + readonly biconomySmartAccountConfig: BiconomySmartAccountV2ConfigConstructorProps + ) { + super({ + ...biconomySmartAccountConfig, + chain: + biconomySmartAccountConfig.viemChain ?? + getChain(biconomySmartAccountConfig.chainId), + rpcClient: + biconomySmartAccountConfig.rpcUrl || + getChain(biconomySmartAccountConfig.chainId).rpcUrls.default.http[0], + entryPointAddress: + (biconomySmartAccountConfig.entryPointAddress as Hex) ?? + DEFAULT_ENTRYPOINT_ADDRESS, + accountAddress: + (biconomySmartAccountConfig.accountAddress as Hex) ?? undefined, + factoryAddress: + biconomySmartAccountConfig.factoryAddress ?? + DEFAULT_BICONOMY_FACTORY_ADDRESS + }) + + this.defaultValidationModule = + biconomySmartAccountConfig.defaultValidationModule + this.activeValidationModule = + biconomySmartAccountConfig.activeValidationModule + + this.index = biconomySmartAccountConfig.index ?? 0 + this.chainId = biconomySmartAccountConfig.chainId + this.bundler = biconomySmartAccountConfig.bundler + this.implementationAddress = + biconomySmartAccountConfig.implementationAddress ?? + (BICONOMY_IMPLEMENTATION_ADDRESSES_BY_VERSION.V2_0_0 as Hex) + + if (biconomySmartAccountConfig.paymasterUrl) { + this.paymaster = new Paymaster({ + paymasterUrl: biconomySmartAccountConfig.paymasterUrl + }) + } else if (biconomySmartAccountConfig.biconomyPaymasterApiKey) { + this.paymaster = new Paymaster({ + paymasterUrl: `https://paymaster.biconomy.io/api/v1/${biconomySmartAccountConfig.chainId}/${biconomySmartAccountConfig.biconomyPaymasterApiKey}` + }) + } else { + this.paymaster = biconomySmartAccountConfig.paymaster + } + + this.bundler = biconomySmartAccountConfig.bundler + + const defaultFallbackHandlerAddress = + this.factoryAddress === DEFAULT_BICONOMY_FACTORY_ADDRESS + ? DEFAULT_FALLBACK_HANDLER_ADDRESS + : biconomySmartAccountConfig.defaultFallbackHandler + if (!defaultFallbackHandlerAddress) { + throw new Error("Default Fallback Handler address is not provided") + } + this.defaultFallbackHandlerAddress = defaultFallbackHandlerAddress + + // Added bang operator to avoid null check as the constructor have these params as optional + this.defaultValidationModule = + // biome-ignore lint/style/noNonNullAssertion: <explanation> + biconomySmartAccountConfig.defaultValidationModule! + this.activeValidationModule = + // biome-ignore lint/style/noNonNullAssertion: <explanation> + biconomySmartAccountConfig.activeValidationModule! + + this.provider = createPublicClient({ + chain: + biconomySmartAccountConfig.viemChain ?? + getChain(biconomySmartAccountConfig.chainId), + transport: http( + biconomySmartAccountConfig.rpcUrl || + getChain(biconomySmartAccountConfig.chainId).rpcUrls.default.http[0] + ) + }) + + this.scanForUpgradedAccountsFromV1 = + biconomySmartAccountConfig.scanForUpgradedAccountsFromV1 ?? false + this.maxIndexForScan = biconomySmartAccountConfig.maxIndexForScan ?? 10 + } + + /** + * Creates a new instance of BiconomySmartAccountV2 + * + * This method will create a BiconomySmartAccountV2 instance but will not deploy the Smart Account + * Deployment of the Smart Account will be donewith the first user operation. + * + * - Docs: https://docs.biconomy.io/Account/integration#integration-1 + * + * @param biconomySmartAccountConfig - Configuration for initializing the BiconomySmartAccountV2 instance. + * @returns A promise that resolves to a new instance of BiconomySmartAccountV2. + * @throws An error if something is wrong with the smart account instance creation. + * + * @example + * import { createClient } from "viem" + * import { createSmartAccountClient, BiconomySmartAccountV2 } from "@biconomy/account" + * import { createWalletClient, http } from "viem"; + * import { polygonAmoy } from "viem/chains"; + * + * const signer = createWalletClient({ + * account, + * chain: polygonAmoy, + * transport: http(), + * }); + * + * const bundlerUrl = "" // Retrieve bundler url from dashboard + * + * const smartAccountFromStaticCreate = await BiconomySmartAccountV2.create({ signer, bundlerUrl }); + * + * // Is the same as... + * + * const smartAccount = await createSmartAccountClient({ signer, bundlerUrl }); + * + */ + public static async create( + biconomySmartAccountConfig: BiconomySmartAccountV2Config + ): Promise<BiconomySmartAccountV2> { + let chainId = biconomySmartAccountConfig.chainId + let rpcUrl = biconomySmartAccountConfig.rpcUrl + let resolvedSmartAccountSigner!: SmartAccountSigner + + // Signer needs to be initialised here before defaultValidationModule is set + if (biconomySmartAccountConfig.signer) { + const signerResult = await convertSigner( + biconomySmartAccountConfig.signer, + !!chainId, + rpcUrl + ) + if (!chainId && !!signerResult.chainId) { + chainId = signerResult.chainId + } + if (!rpcUrl && !!signerResult.rpcUrl) { + if (isValidRpcUrl(signerResult.rpcUrl)) { + rpcUrl = signerResult.rpcUrl + } + } + resolvedSmartAccountSigner = signerResult.signer + } + if (!chainId) { + // Get it from bundler + if (biconomySmartAccountConfig.bundlerUrl) { + chainId = extractChainIdFromBundlerUrl( + biconomySmartAccountConfig.bundlerUrl + ) + } else if (biconomySmartAccountConfig.bundler) { + const bundlerUrlFromBundler = + biconomySmartAccountConfig.bundler.getBundlerUrl() + chainId = extractChainIdFromBundlerUrl(bundlerUrlFromBundler) + } + } + if (!chainId) { + throw new Error("chainId required") + } + const bundler: IBundler = + biconomySmartAccountConfig.bundler ?? + new Bundler({ + // biome-ignore lint/style/noNonNullAssertion: <explanation> + bundlerUrl: biconomySmartAccountConfig.bundlerUrl!, + chainId + }) + let defaultValidationModule = + biconomySmartAccountConfig.defaultValidationModule + + // Note: If no module is provided, we will use ECDSA_OWNERSHIP as default + if (!defaultValidationModule) { + const newModule = await createECDSAOwnershipValidationModule({ + // biome-ignore lint/style/noNonNullAssertion: <explanation> + signer: resolvedSmartAccountSigner! + }) + defaultValidationModule = newModule + } + const activeValidationModule = + biconomySmartAccountConfig?.activeValidationModule ?? + defaultValidationModule + if (!resolvedSmartAccountSigner) { + resolvedSmartAccountSigner = await activeValidationModule.getSigner() + } + if (!resolvedSmartAccountSigner) { + throw new Error("signer required") + } + const config: BiconomySmartAccountV2ConfigConstructorProps = { + ...biconomySmartAccountConfig, + defaultValidationModule, + activeValidationModule, + chainId, + bundler, + signer: resolvedSmartAccountSigner, + rpcUrl + } + + // We check if chain ids match (skip this if chainId is passed by in the config) + // This check is at the end of the function for cases when the signer is not passed in the config but a validation modules is and we get the signer from the validation module in this case + if (!biconomySmartAccountConfig.chainId) { + await compareChainIds( + biconomySmartAccountConfig.signer || resolvedSmartAccountSigner, + config, + false + ) + } + + return new BiconomySmartAccountV2(config) + } + + // Calls the getCounterFactualAddress + override async getAddress(params?: CounterFactualAddressParam): Promise<Hex> { + if (this.accountAddress == null) { + // means it needs deployment + this.accountAddress = await this.getCounterFactualAddress(params) + } + return this.accountAddress + } + + // Calls the getCounterFactualAddress + async getAccountAddress( + params?: CounterFactualAddressParam + ): Promise<`0x${string}`> { + if (this.accountAddress == null || this.accountAddress === undefined) { + // means it needs deployment + this.accountAddress = await this.getCounterFactualAddress(params) + } + return this.accountAddress + } + + /** + * Returns an upper estimate for the gas spent on a specific user operation + * + * This method will fetch an approximate gas estimate for the user operation, given the current state of the network. + * It is regularly an overestimate, and the actual gas spent will likely be lower. + * It is unlikely to be an underestimate unless the network conditions rapidly change. + * + * @param transactions Array of {@link Transaction} to be sent. + * @param buildUseropDto {@link BuildUserOpOptions}. + * @returns Promise<bigint> - The estimated gas cost in wei. + * + * @example + * import { createClient } from "viem" + * import { createSmartAccountClient } from "@biconomy/account" + * import { createWalletClient, http } from "viem"; + * import { polygonAmoy } from "viem/chains"; + * + * const signer = createWalletClient({ + * account, + * chain: polygonAmoy, + * transport: http(), + * }); + * + * const smartAccount = await createSmartAccountClient({ signer, bundlerUrl, paymasterUrl }); // Retrieve bundler/paymaster url from dashboard + * const encodedCall = encodeFunctionData({ + * abi: parseAbi(["function safeMint(address to) public"]), + * functionName: "safeMint", + * args: ["0x..."], + * }); + * + * const tx = { + * to: nftAddress, + * data: encodedCall + * } + * + * const amountInWei = await smartAccount.getGasEstimates([tx, tx], { + * paymasterServiceData: { + * mode: PaymasterMode.SPONSORED, + * }, + * }); + * + * console.log(amountInWei.toString()); + * + */ + public async getGasEstimate( + transactions: Transaction[], + buildUseropDto?: BuildUserOpOptions + ): Promise<bigint> { + const { + callGasLimit, + preVerificationGas, + verificationGasLimit, + maxFeePerGas + } = await this.buildUserOp(transactions, buildUseropDto) + + const _callGasLimit = BigInt(callGasLimit || 0) + const _preVerificationGas = BigInt(preVerificationGas || 0) + const _verificationGasLimit = BigInt(verificationGasLimit || 0) + const _maxFeePerGas = BigInt(maxFeePerGas || 0) + + if (!buildUseropDto?.paymasterServiceData?.mode) { + return ( + (_callGasLimit + _preVerificationGas + _verificationGasLimit) * + _maxFeePerGas + ) + } + return ( + (_callGasLimit + + BigInt(3) * _verificationGasLimit + + _preVerificationGas) * + _maxFeePerGas + ) + } + + /** + * Returns balances for the smartAccount instance. + * + * This method will fetch tokens info given an array of token addresses for the smartAccount instance. + * The balance of the native token will always be returned as the last element in the reponse array, with the address set to 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE. + * + * @param addresses - Optional. Array of asset addresses to fetch the balances of. If not provided, the method will return only the balance of the native token. + * @returns Promise<Array<BalancePayload>> - An array of token balances (plus the native token balance) of the smartAccount instance. + * + * @example + * import { createClient } from "viem" + * import { createSmartAccountClient } from "@biconomy/account" + * import { createWalletClient, http } from "viem"; + * import { polygonAmoy } from "viem/chains"; + * + * const signer = createWalletClient({ + * account, + * chain: polygonAmoy, + * transport: http(), + * }); + * + * const token = "0x747A4168DB14F57871fa8cda8B5455D8C2a8e90a"; + * const smartAccount = await createSmartAccountClient({ signer, bundlerUrl }); + * const [tokenBalanceFromSmartAccount, nativeTokenBalanceFromSmartAccount] = await smartAccount.getBalances([token]); + * + * console.log(tokenBalanceFromSmartAccount); + * // { + * // amount: 1000000000000000n, + * // decimals: 6, + * // address: "0x747A4168DB14F57871fa8cda8B5455D8C2a8e90a", + * // formattedAmount: "1000000", + * // chainId: 80002 + * // } + * + * // or to get the nativeToken balance + * + * const [nativeTokenBalanceFromSmartAccount] = await smartAccount.getBalances(); + * + * console.log(nativeTokenBalanceFromSmartAccount); + * // { + * // amount: 1000000000000000n, + * // decimals: 18, + * // address: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", + * // formattedAmount: "1", + * // chainId: 80002 + * // } + * + */ + public async getBalances( + addresses?: Array<Hex> + ): Promise<Array<BalancePayload>> { + const accountAddress = await this.getAccountAddress() + const result: BalancePayload[] = [] + + if (addresses) { + const tokenContracts = addresses.map((address) => + getContract({ + address, + abi: parseAbi(ERC20_ABI), + client: this.provider + }) + ) + + const balancePromises = tokenContracts.map((tokenContract) => + tokenContract.read.balanceOf([accountAddress]) + ) as Promise<bigint>[] + const decimalsPromises = tokenContracts.map((tokenContract) => + tokenContract.read.decimals() + ) as Promise<number>[] + const [balances, decimalsPerToken] = await Promise.all([ + Promise.all(balancePromises), + Promise.all(decimalsPromises) + ]) + + balances.forEach((amount, index) => + result.push({ + amount, + decimals: decimalsPerToken[index], + address: addresses[index], + formattedAmount: formatUnits(amount, decimalsPerToken[index]), + chainId: this.chainId + }) + ) + } + + const balance = await this.provider.getBalance({ address: accountAddress }) + + result.push({ + amount: balance, + decimals: 18, + address: NATIVE_TOKEN_ALIAS, + formattedAmount: formatUnits(balance, 18), + chainId: this.chainId + }) + + return result + } + + /** + * Transfers funds from Smart Account to recipient (usually EOA) + * @param recipient - Address of the recipient + * @param withdrawalRequests - Array of withdrawal requests {@link WithdrawalRequest}. If withdrawal request is an empty array, it will transfer the balance of the native token. Using a paymaster will ensure no dust remains in the smart account. + * @param buildUseropDto - Optional. {@link BuildUserOpOptions} + * + * @returns Promise<UserOpResponse> - An object containing the status of the transaction. + * + * @example + * import { createClient } from "viem" + * import { createSmartAccountClient, NATIVE_TOKEN_ALIAS } from "@biconomy/account" + * import { createWalletClient, http } from "viem"; + * import { polygonMumbai } from "viem/chains"; + * + * const token = "0x747A4168DB14F57871fa8cda8B5455D8C2a8e90a"; + * const signer = createWalletClient({ + * account, + * chain: polygonMumbai, + * transport: http(), + * }); + * + * const smartAccount = await createSmartAccountClient({ signer, bundlerUrl, biconomyPaymasterApiKey }); + * + * const { wait } = await smartAccount.withdraw( + * [ + * { address: token }, // omit the amount to withdraw the full balance + * { address: NATIVE_TOKEN_ALIAS, amount: BigInt(1) } + * ], + * account.address, // Default recipient used if no recipient is present in the withdrawal request + * { + * paymasterServiceData: { mode: PaymasterMode.SPONSORED }, + * } + * ); + * + * // OR to withdraw all of the native token, leaving no dust in the smart account + * + * const { wait } = await smartAccount.withdraw([], account.address, { + * paymasterServiceData: { mode: PaymasterMode.SPONSORED }, + * }); + * + * const { success } = await wait(); + */ + public async withdraw( + withdrawalRequests?: WithdrawalRequest[] | null, + defaultRecipient?: Hex | null, + buildUseropDto?: BuildUserOpOptions + ): Promise<UserOpResponse> { + const accountAddress = + this.accountAddress ?? (await this.getAccountAddress()) + + if ( + !defaultRecipient && + withdrawalRequests?.some(({ recipient }) => !recipient) + ) { + throw new Error(ERROR_MESSAGES.NO_RECIPIENT) + } + + // Remove the native token from the withdrawal requests + let tokenRequests = + withdrawalRequests?.filter( + ({ address }) => !addressEquals(address, NATIVE_TOKEN_ALIAS) + ) ?? [] + + // Check if the amount is not present in all withdrawal requests + const shouldFetchMaxBalances = tokenRequests.some(({ amount }) => !amount) + + // Get the balances of the tokens if the amount is not present in the withdrawal requests + if (shouldFetchMaxBalances) { + const balances = await this.getBalances( + tokenRequests.map(({ address }) => address) + ) + tokenRequests = tokenRequests.map(({ amount, address }, i) => ({ + address, + amount: amount ?? balances[i].amount + })) + } + + // Create the transactions + const txs: Transaction[] = tokenRequests.map( + ({ address, amount, recipient: recipientFromRequest }) => ({ + to: address, + data: encodeFunctionData({ + abi: parseAbi(ERC20_ABI), + functionName: "transfer", + args: [recipientFromRequest || defaultRecipient, amount] + }) + }) + ) + + // Check if eth alias is present in the original withdrawal requests + const nativeTokenRequest = withdrawalRequests?.find(({ address }) => + addressEquals(address, NATIVE_TOKEN_ALIAS) + ) + const hasNoRequests = !withdrawalRequests?.length + if (!!nativeTokenRequest || hasNoRequests) { + // Check that an amount is present in the withdrawal request, if no paymaster service data is present, as max amounts cannot be calculated without a paymaster. + if ( + !nativeTokenRequest?.amount && + !buildUseropDto?.paymasterServiceData?.mode + ) { + throw new Error(ERROR_MESSAGES.NATIVE_TOKEN_WITHDRAWAL_WITHOUT_AMOUNT) + } + + // get eth balance if not present in withdrawal requests + const nativeTokenAmountToWithdraw = + nativeTokenRequest?.amount ?? + (await this.provider.getBalance({ address: accountAddress })) + + txs.push({ + to: (nativeTokenRequest?.recipient ?? defaultRecipient) as Hex, + value: nativeTokenAmountToWithdraw + }) + } + + return this.sendTransaction(txs, buildUseropDto) + } + + /** + * Return the account's address. This value is valid even before deploying the contract. + */ + async getCounterFactualAddress( + params?: CounterFactualAddressParam + ): Promise<Hex> { + const validationModule = + params?.validationModule ?? this.defaultValidationModule + const index = params?.index ?? this.index + + const maxIndexForScan = params?.maxIndexForScan ?? this.maxIndexForScan + // Review: default behavior + const scanForUpgradedAccountsFromV1 = + params?.scanForUpgradedAccountsFromV1 ?? + this.scanForUpgradedAccountsFromV1 + + // if it's intended to detect V1 upgraded accounts + if (scanForUpgradedAccountsFromV1) { + const eoaSigner = await validationModule.getSigner() + const eoaAddress = (await eoaSigner.getAddress()) as Hex + const moduleAddress = validationModule.getAddress() as Hex + const moduleSetupData = (await validationModule.getInitData()) as Hex + const queryParams = { + eoaAddress, + index, + moduleAddress, + moduleSetupData, + maxIndexForScan + } + const accountAddress = await this.getV1AccountsUpgradedToV2(queryParams) + if (accountAddress !== ADDRESS_ZERO) { + return accountAddress + } + } + + const counterFactualAddressV2 = await this.getCounterFactualAddressV2({ + validationModule, + index + }) + return counterFactualAddressV2 + } + + private async getCounterFactualAddressV2( + params?: CounterFactualAddressParam + ): Promise<Hex> { + const validationModule = + params?.validationModule ?? this.defaultValidationModule + const index = params?.index ?? this.index + + try { + const initCalldata = encodeFunctionData({ + abi: BiconomyAccountAbi, + functionName: "init", + args: [ + this.defaultFallbackHandlerAddress, + validationModule.getAddress() as Hex, + (await validationModule.getInitData()) as Hex + ] + }) + + const proxyCreationCodeHash = keccak256( + encodePacked( + ["bytes", "uint256"], + [PROXY_CREATION_CODE, BigInt(this.implementationAddress)] + ) + ) + + const salt = keccak256( + encodePacked( + ["bytes32", "uint256"], + [keccak256(initCalldata), BigInt(index)] + ) + ) + + const counterFactualAddress = getCreate2Address({ + from: this.factoryAddress, + salt: salt, + bytecodeHash: proxyCreationCodeHash + }) + + return counterFactualAddress + } catch (e) { + throw new Error(`Failed to get counterfactual address, ${e}`) + } + } + + async _getAccountContract(): Promise< + GetContractReturnType<typeof BiconomyAccountAbi, PublicClient> + > { + if (this.accountContract == null) { + this.accountContract = getContract({ + address: await this.getAddress(), + abi: BiconomyAccountAbi, + client: this.provider as PublicClient + }) + } + return this.accountContract + } + + isActiveValidationModuleDefined(): boolean { + if (!this.activeValidationModule) + throw new Error("Must provide an instance of active validation module.") + return true + } + + isDefaultValidationModuleDefined(): boolean { + if (!this.defaultValidationModule) + throw new Error("Must provide an instance of default validation module.") + return true + } + + setActiveValidationModule( + validationModule: BaseValidationModule + ): BiconomySmartAccountV2 { + if (validationModule instanceof BaseValidationModule) { + this.activeValidationModule = validationModule + } + return this + } + + setDefaultValidationModule( + validationModule: BaseValidationModule + ): BiconomySmartAccountV2 { + if (validationModule instanceof BaseValidationModule) { + this.defaultValidationModule = validationModule + } + return this + } + + async getV1AccountsUpgradedToV2( + params: QueryParamsForAddressResolver + ): Promise<Hex> { + const maxIndexForScan = params.maxIndexForScan ?? this.maxIndexForScan + + const addressResolver = getContract({ + address: ADDRESS_RESOLVER_ADDRESS, + abi: AccountResolverAbi, + client: { + public: this.provider as PublicClient + } + }) + // Note: depending on moduleAddress and moduleSetupData passed call this. otherwise could call resolveAddresses() + + if (params.moduleAddress && params.moduleSetupData) { + const result = await addressResolver.read.resolveAddressesFlexibleForV2([ + params.eoaAddress, + maxIndexForScan, + params.moduleAddress, + params.moduleSetupData + ]) + + const desiredV1Account = result.find( + (smartAccountInfo: { + factoryVersion: string + currentVersion: string + deploymentIndex: { toString: () => string } + }) => + smartAccountInfo.factoryVersion === "v1" && + smartAccountInfo.currentVersion === "2.0.0" && + Number(smartAccountInfo.deploymentIndex.toString()) === params.index + ) + + if (desiredV1Account) { + const smartAccountAddress = desiredV1Account.accountAddress + return smartAccountAddress + } + return ADDRESS_ZERO + } + return ADDRESS_ZERO + } + + /** + * Return the value to put into the "initCode" field, if the account is not yet deployed. + * This value holds the "factory" address, followed by this account's information + */ + async getAccountInitCode(): Promise<Hex> { + this.isDefaultValidationModuleDefined() + + if (await this.isAccountDeployed()) return "0x" + + return concatHex([ + this.factoryAddress as Hex, + (await this.getFactoryData()) ?? "0x" + ]) + } + + /** + * + * @param to { target } address of transaction + * @param value represents amount of native tokens + * @param data represent data associated with transaction + * @returns encoded data for execute function + */ + async encodeExecute(to: Hex, value: bigint, data: Hex): Promise<Hex> { + // return accountContract.interface.encodeFunctionData("execute_ncC", [to, value, data]) as Hex; + return encodeFunctionData({ + abi: BiconomyAccountAbi, + functionName: "execute_ncC", + args: [to, value, data] + }) + } + + /** + * + * @param to { target } array of addresses in transaction + * @param value represents array of amount of native tokens associated with each transaction + * @param data represent array of data associated with each transaction + * @returns encoded data for executeBatch function + */ + async encodeExecuteBatch( + to: Array<Hex>, + value: Array<bigint>, + data: Array<Hex> + ): Promise<Hex> { + return encodeFunctionData({ + abi: BiconomyAccountAbi, + functionName: "executeBatch_y6U", + args: [to, value, data] + }) + } + + override async encodeBatchExecute( + txs: BatchUserOperationCallData + ): Promise<Hex> { + const [targets, datas, value] = txs.reduce( + (accum, curr) => { + accum[0].push(curr.target) + accum[1].push(curr.data) + accum[2].push(curr.value || BigInt(0)) + + return accum + }, + [[], [], []] as [Hex[], Hex[], bigint[]] + ) + + return this.encodeExecuteBatch(targets, value, datas) + } + + // dummy signature depends on the validation module supplied. + async getDummySignatures(params?: ModuleInfo): Promise<Hex> { + this.isActiveValidationModuleDefined() + return (await this.activeValidationModule.getDummySignature(params)) as Hex + } + + // TODO: review this + getDummySignature(): Hex { + throw new Error("Method not implemented! Call getDummySignatures instead.") + } + + // Might use provided paymaster instance to get dummy data (from pm service) + getDummyPaymasterData(): string { + return "0x" + } + + validateUserOp( + userOp: Partial<UserOperationStruct>, + requiredFields: UserOperationKey[] + ): boolean { + for (const field of requiredFields) { + if (isNullOrUndefined(userOp[field])) { + throw new Error(`${String(field)} is missing in the UserOp`) + } + } + return true + } + + async signUserOp( + userOp: Partial<UserOperationStruct>, + params?: SendUserOpParams + ): Promise<UserOperationStruct> { + this.isActiveValidationModuleDefined() + const requiredFields: UserOperationKey[] = [ + "sender", + "nonce", + "initCode", + "callData", + "callGasLimit", + "verificationGasLimit", + "preVerificationGas", + "maxFeePerGas", + "maxPriorityFeePerGas", + "paymasterAndData" + ] + this.validateUserOp(userOp, requiredFields) + const userOpHash = await this.getUserOpHash(userOp) + + const moduleSig = (await this.activeValidationModule.signUserOpHash( + userOpHash, + params + )) as Hex + + const signatureWithModuleAddress = this.getSignatureWithModuleAddress( + moduleSig, + this.activeValidationModule.getAddress() as Hex + ) + + userOp.signature = signatureWithModuleAddress + return userOp as UserOperationStruct + } + + getSignatureWithModuleAddress( + moduleSignature: Hex, + moduleAddress?: Hex + ): Hex { + const moduleAddressToUse = + moduleAddress ?? (this.activeValidationModule.getAddress() as Hex) + return encodeAbiParameters(parseAbiParameters("bytes, address"), [ + moduleSignature, + moduleAddressToUse + ]) + } + + public async getPaymasterUserOp( + userOp: Partial<UserOperationStruct>, + paymasterServiceData: PaymasterUserOperationDto + ): Promise<Partial<UserOperationStruct>> { + if (paymasterServiceData.mode === PaymasterMode.SPONSORED) { + return this.getPaymasterAndData(userOp, paymasterServiceData) + } + if (paymasterServiceData.mode === PaymasterMode.ERC20) { + if (paymasterServiceData?.feeQuote) { + const { feeQuote, spender, maxApproval = false } = paymasterServiceData + Logger.log("there is a feeQuote: ", JSON.stringify(feeQuote, null, 2)) + if (!spender) throw new Error(ERROR_MESSAGES.SPENDER_REQUIRED) + if (!feeQuote) throw new Error(ERROR_MESSAGES.FAILED_FEE_QUOTE_FETCH) + if ( + paymasterServiceData.skipPatchCallData && + paymasterServiceData.skipPatchCallData === true + ) { + return this.getPaymasterAndData(userOp, { + ...paymasterServiceData, + feeTokenAddress: feeQuote.tokenAddress + }) + } + const partialUserOp = await this.buildTokenPaymasterUserOp(userOp, { + ...paymasterServiceData, + spender, + maxApproval, + feeQuote + }) + return this.getPaymasterAndData(partialUserOp, { + ...paymasterServiceData, + feeTokenAddress: feeQuote.tokenAddress, + calculateGasLimits: true // Always recommended and especially when using token paymaster + }) + } + if (paymasterServiceData?.preferredToken) { + const { preferredToken } = paymasterServiceData + Logger.log("there is a preferred token: ", preferredToken) + const feeQuotesResponse = await this.getPaymasterFeeQuotesOrData( + userOp, + paymasterServiceData + ) + const spender = feeQuotesResponse.tokenPaymasterAddress + const feeQuote = feeQuotesResponse.feeQuotes?.[0] + if (!spender) throw new Error(ERROR_MESSAGES.SPENDER_REQUIRED) + if (!feeQuote) throw new Error(ERROR_MESSAGES.FAILED_FEE_QUOTE_FETCH) + return this.getPaymasterUserOp(userOp, { + ...paymasterServiceData, + feeQuote, + spender + }) // Recursively call getPaymasterUserOp with the feeQuote + } + Logger.log( + "ERC20 mode without feeQuote or preferredToken provided. Passing through unchanged." + ) + return userOp + } + throw new Error("Invalid paymaster mode") + } + + private async getPaymasterAndData( + userOp: Partial<UserOperationStruct>, + paymasterServiceData: PaymasterUserOperationDto + ): Promise<Partial<UserOperationStruct>> { + const paymaster = this + .paymaster as IHybridPaymaster<PaymasterUserOperationDto> + const paymasterData = await paymaster.getPaymasterAndData( + userOp, + paymasterServiceData + ) + return { ...userOp, ...paymasterData } + } + + private async getPaymasterFeeQuotesOrData( + userOp: Partial<UserOperationStruct>, + feeQuotesOrData: FeeQuotesOrDataDto + ): Promise<FeeQuotesOrDataResponse> { + const paymaster = this + .paymaster as IHybridPaymaster<PaymasterUserOperationDto> + const tokenList = feeQuotesOrData?.preferredToken + ? [feeQuotesOrData?.preferredToken] + : feeQuotesOrData?.tokenList?.length + ? feeQuotesOrData?.tokenList + : [] + return paymaster.getPaymasterFeeQuotesOrData(userOp, { + ...feeQuotesOrData, + tokenList + }) + } + + /** + * + * @description This function will retrieve fees from the paymaster in erc20 mode + * + * @param manyOrOneTransactions Array of {@link Transaction} to be batched and sent. Can also be a single {@link Transaction}. + * @param buildUseropDto {@link BuildUserOpOptions}. + * @returns Promise<FeeQuotesOrDataResponse> + * + * @example + * import { createClient } from "viem" + * import { createSmartAccountClient } from "@biconomy/account" + * import { createWalletClient, http } from "viem"; + * import { polygonAmoy } from "viem/chains"; + * + * const signer = createWalletClient({ + * account, + * chain: polygonAmoy, + * transport: http(), + * }); + * + * const smartAccount = await createSmartAccountClient({ signer, bundlerUrl }); // Retrieve bundler url from dashboard + * const encodedCall = encodeFunctionData({ + * abi: parseAbi(["function safeMint(address to) public"]), + * functionName: "safeMint", + * args: ["0x..."], + * }); + * + * const transaction = { + * to: nftAddress, + * data: encodedCall + * } + * + * const feeQuotesResponse: FeeQuotesOrDataResponse = await smartAccount.getTokenFees(transaction, { paymasterServiceData: { mode: PaymasterMode.ERC20 } }); + * + * const userSeletedFeeQuote = feeQuotesResponse.feeQuotes?.[0]; + * + * const { wait } = await smartAccount.sendTransaction(transaction, { + * paymasterServiceData: { + * mode: PaymasterMode.ERC20, + * feeQuote: userSeletedFeeQuote, + * spender: feeQuotesResponse.tokenPaymasterAddress, + * }, + * }); + * + * const { success, receipt } = await wait(); + * + */ + public async getTokenFees( + manyOrOneTransactions: Transaction | Transaction[], + buildUseropDto: BuildUserOpOptions + ): Promise<FeeQuotesOrDataResponse> { + const txs = Array.isArray(manyOrOneTransactions) + ? manyOrOneTransactions + : [manyOrOneTransactions] + const userOp = await this.buildUserOp(txs, buildUseropDto) + if (!buildUseropDto.paymasterServiceData) + throw new Error("paymasterServiceData was not provided") + return this.getPaymasterFeeQuotesOrData( + userOp, + buildUseropDto.paymasterServiceData + ) + } + + /** + * + * @description This function will return an array of supported tokens from the erc20 paymaster associated with the Smart Account + * @returns Promise<{@link SupportedToken}> + * + * @example + * import { createClient } from "viem" + * import { createSmartAccountClient } from "@biconomy/account" + * import { createWalletClient, http } from "viem"; + * import { polygonAmoy } from "viem/chains"; + * + * const signer = createWalletClient({ + * account, + * chain: polygonAmoy, + * transport: http(), + * }); + * + * const smartAccount = await createSmartAccountClient({ signer, bundlerUrl, biconomyPaymasterApiKey }); // Retrieve bundler url from dashboard + * const tokens = await smartAccount.getSupportedTokens(); + * + * // [ + * // { + * // symbol: "USDC", + * // tokenAddress: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", + * // decimal: 6, + * // logoUrl: "https://assets.coingecko.com/coins/images/279/large/usd-coin.png?1595353707", + * // premiumPercentage: 0.1, + * // } + * // ] + * + */ + public async getSupportedTokens(): Promise<SupportedToken[]> { + const feeQuotesResponse = await this.getTokenFees( + { + data: "0x", + value: BigInt(0), + to: await this.getAccountAddress() + }, + { + paymasterServiceData: { mode: PaymasterMode.ERC20 } + } + ) + + return await Promise.all( + (feeQuotesResponse?.feeQuotes ?? []).map(async (quote) => { + const [tokenBalance] = await this.getBalances([ + quote.tokenAddress as Hex + ]) + return { + symbol: quote.symbol, + tokenAddress: quote.tokenAddress, + decimal: quote.decimal, + logoUrl: quote.logoUrl, + premiumPercentage: quote.premiumPercentage, + balance: tokenBalance + } + }) + ) + } + + /** + * + * @param userOp + * @param params + * @description This function will take a user op as an input, sign it with the owner key, and send it to the bundler. + * @returns Promise<UserOpResponse> + * Sends a user operation + * + * - Docs: https://docs.biconomy.io/Account/transactions/userpaid#send-useroperation + * + * @param userOp Partial<{@link UserOperationStruct}> the userOp params to be sent. + * @param params {@link SendUserOpParams}. + * @returns Promise<{@link UserOpResponse}> that you can use to track the user operation. + * + * @example + * import { createClient } from "viem" + * import { createSmartAccountClient } from "@biconomy/account" + * import { createWalletClient, http } from "viem"; + * import { polygonAmoy } from "viem/chains"; + * + * const signer = createWalletClient({ + * account, + * chain: polygonAmoy, + * transport: http(), + * }); + * + * const smartAccount = await createSmartAccountClient({ signer, bundlerUrl }); // Retrieve bundler url from dashboard + * const encodedCall = encodeFunctionData({ + * abi: parseAbi(["function safeMint(address to) public"]), + * functionName: "safeMint", + * args: ["0x..."], + * }); + * + * const transaction = { + * to: nftAddress, + * data: encodedCall + * } + * + * const userOp = await smartAccount.buildUserOp([transaction]); + * + * const { wait } = await smartAccount.sendUserOp(userOp); + * const { success, receipt } = await wait(); + * + */ + async sendUserOp( + userOp: Partial<UserOperationStruct>, + params?: SendUserOpParams + ): Promise<UserOpResponse> { + // biome-ignore lint/performance/noDelete: <explanation> + delete userOp.signature + const userOperation = await this.signUserOp(userOp, params) + const bundlerResponse = await this.sendSignedUserOp( + userOperation, + params?.simulationType + ) + return bundlerResponse + } + + /** + * + * @param userOp - The signed user operation to send + * @param simulationType - The type of simulation to perform ("validation" | "validation_and_execution") + * @description This function call will take 'signedUserOp' as input and send it to the bundler + * @returns + */ + async sendSignedUserOp( + userOp: UserOperationStruct, + simulationType?: SimulationType + ): Promise<UserOpResponse> { + const requiredFields: UserOperationKey[] = [ + "sender", + "nonce", + "initCode", + "callData", + "callGasLimit", + "verificationGasLimit", + "preVerificationGas", + "maxFeePerGas", + "maxPriorityFeePerGas", + "paymasterAndData", + "signature" + ] + this.validateUserOp(userOp, requiredFields) + if (!this.bundler) throw new Error("Bundler is not provided") + Logger.warn( + "userOp being sent to the bundler", + JSON.stringify(userOp, null, 2) + ) + const bundlerResponse = await this.bundler.sendUserOp( + userOp, + simulationType + ) + return bundlerResponse + } + + async getUserOpHash(userOp: Partial<UserOperationStruct>): Promise<Hex> { + const userOpHash = keccak256(packUserOp(userOp, true) as Hex) + const enc = encodeAbiParameters( + parseAbiParameters("bytes32, address, uint256"), + [userOpHash, this.entryPoint.address, BigInt(this.chainId)] + ) + return keccak256(enc) + } + + async estimateUserOpGas( + userOp: Partial<UserOperationStruct>, + stateOverrideSet?: StateOverrideSet + ): Promise<Partial<UserOperationStruct>> { + if (!this.bundler) throw new Error("Bundler is not provided") + const requiredFields: UserOperationKey[] = [ + "sender", + "nonce", + "initCode", + "callData" + ] + this.validateUserOp(userOp, requiredFields) + + const finalUserOp = userOp + + // Making call to bundler to get gas estimations for userOp + const { + callGasLimit, + verificationGasLimit, + preVerificationGas, + maxFeePerGas, + maxPriorityFeePerGas + } = await this.bundler.estimateUserOpGas(userOp, stateOverrideSet) + // if neither user sent gas fee nor the bundler, estimate gas from provider + if ( + !userOp.maxFeePerGas && + !userOp.maxPriorityFeePerGas && + (!maxFeePerGas || !maxPriorityFeePerGas) + ) { + const feeData = await this.provider.estimateFeesPerGas() + if (feeData.maxFeePerGas?.toString()) { + finalUserOp.maxFeePerGas = `0x${feeData.maxFeePerGas.toString( + 16 + )}` as Hex + } else if (feeData.gasPrice?.toString()) { + finalUserOp.maxFeePerGas = `0x${feeData.gasPrice.toString(16)}` as Hex + } else { + finalUserOp.maxFeePerGas = `0x${( + await this.provider.getGasPrice() + ).toString(16)}` as Hex + } + + if (feeData.maxPriorityFeePerGas?.toString()) { + finalUserOp.maxPriorityFeePerGas = + `0x${feeData.maxPriorityFeePerGas?.toString()}` as Hex + } else if (feeData.gasPrice?.toString()) { + finalUserOp.maxPriorityFeePerGas = toHex( + Number(feeData.gasPrice?.toString()) + ) + } else { + finalUserOp.maxPriorityFeePerGas = `0x${( + await this.provider.getGasPrice() + ).toString(16)}` as Hex + } + } else { + finalUserOp.maxFeePerGas = + toHex(Number(maxFeePerGas)) ?? userOp.maxFeePerGas + finalUserOp.maxPriorityFeePerGas = + toHex(Number(maxPriorityFeePerGas)) ?? userOp.maxPriorityFeePerGas + } + finalUserOp.verificationGasLimit = + toHex(Number(verificationGasLimit)) ?? userOp.verificationGasLimit + finalUserOp.callGasLimit = + toHex(Number(callGasLimit)) ?? userOp.callGasLimit + finalUserOp.preVerificationGas = + toHex(Number(preVerificationGas)) ?? userOp.preVerificationGas + if (!finalUserOp.paymasterAndData) { + finalUserOp.paymasterAndData = "0x" + } + + return finalUserOp + } + + override async getNonce(nonceKey?: number): Promise<bigint> { + const nonceSpace = nonceKey ?? 0 + try { + const address = await this.getAddress() + return await this.entryPoint.read.getNonce([address, BigInt(nonceSpace)]) + } catch (e) { + return BigInt(0) + } + } + + private async getBuildUserOpNonce( + nonceOptions: NonceOptions | undefined + ): Promise<BigNumberish> { + let nonce = BigInt(0) + try { + if (nonceOptions?.nonceOverride) { + nonce = BigInt(nonceOptions?.nonceOverride) + } else { + const _nonceSpace = nonceOptions?.nonceKey ?? 0 + nonce = await this.getNonce(_nonceSpace) + } + } catch (error) { + // Not throwing this error as nonce would be 0 if this.getNonce() throw exception, which is expected flow for undeployed account + Logger.warn( + "Error while getting nonce for the account. This is expected for undeployed accounts set nonce to 0" + ) + } + return nonce + } + + /** + * Sends a transaction (builds and sends a user op in sequence) + * + * - Docs: https://docs.biconomy.io/Account/transactions/userpaid#send-transaction + * + * @param manyOrOneTransactions Array of {@link Transaction} to be batched and sent. Can also be a single {@link Transaction}. + * @param buildUseropDto {@link BuildUserOpOptions}. + * @returns Promise<{@link UserOpResponse}> that you can use to track the user operation. + * + * @example + * import { createClient } from "viem" + * import { createSmartAccountClient } from "@biconomy/account" + * import { createWalletClient, http } from "viem"; + * import { polygonAmoy } from "viem/chains"; + * + * const signer = createWalletClient({ + * account, + * chain: polygonAmoy, + * transport: http(), + * }); + * + * const smartAccount = await createSmartAccountClient({ signer, bundlerUrl }); // Retrieve bundler url from dashboard + * const encodedCall = encodeFunctionData({ + * abi: parseAbi(["function safeMint(address to) public"]), + * functionName: "safeMint", + * args: ["0x..."], + * }); + * + * const transaction = { + * to: nftAddress, + * data: encodedCall + * } + * + * const { waitForTxHash } = await smartAccount.sendTransaction(transaction); + * const { transactionHash, userOperationReceipt } = await wait(); + * + */ + async sendTransaction( + manyOrOneTransactions: Transaction | Transaction[], + buildUseropDto?: BuildUserOpOptions + ): Promise<UserOpResponse> { + const userOp = await this.buildUserOp( + Array.isArray(manyOrOneTransactions) + ? manyOrOneTransactions + : [manyOrOneTransactions], + buildUseropDto + ) + return this.sendUserOp(userOp, { + simulationType: buildUseropDto?.simulationType, + ...buildUseropDto?.params + }) + } + + /** + * Builds a user operation + * + * - Docs: https://docs.biconomy.io/Account/transactions/userpaid#build-useroperation + * + * @param transactions Array of {@link Transaction} to be sent. + * @param buildUseropDto {@link BuildUserOpOptions}. + * @returns Promise<Partial{@link UserOperationStruct}>> the built user operation to be sent. + * + * @example + * import { createClient } from "viem" + * import { createSmartAccountClient } from "@biconomy/account" + * import { createWalletClient, http } from "viem"; + * import { polygonAmoy } from "viem/chains"; + * + * const signer = createWalletClient({ + * account, + * chain: polygonAmoy, + * transport: http(), + * }); + * + * const smartAccount = await createSmartAccountClient({ signer, bundlerUrl }); // Retrieve bundler url from dashboard + * const encodedCall = encodeFunctionData({ + * abi: parseAbi(["function safeMint(address to) public"]), + * functionName: "safeMint", + * args: ["0x..."], + * }); + * + * const transaction = { + * to: nftAddress, + * data: encodedCall + * } + * + * const userOp = await smartAccount.buildUserOp([{ to: "0x...", data: encodedCall }]); + * + */ + async buildUserOp( + transactions: Transaction[], + buildUseropDto?: BuildUserOpOptions + ): Promise<Partial<UserOperationStruct>> { + const to = transactions.map((element: Transaction) => element.to as Hex) + const data = transactions.map( + (element: Transaction) => (element.data as Hex) ?? "0x" + ) + const value = transactions.map( + (element: Transaction) => (element.value as bigint) ?? BigInt(0) + ) + + const initCodeFetchPromise = this.getInitCode() + const dummySignatureFetchPromise = this.getDummySignatures( + buildUseropDto?.params + ) + + const [nonceFromFetch, initCode, signature] = await Promise.all([ + this.getBuildUserOpNonce(buildUseropDto?.nonceOptions), + initCodeFetchPromise, + dummySignatureFetchPromise + ]) + + if (transactions.length === 0) { + throw new Error("Transactions array cannot be empty") + } + let callData: Hex = "0x" + if (!buildUseropDto?.useEmptyDeployCallData) { + if (transactions.length > 1 || buildUseropDto?.forceEncodeForBatch) { + callData = await this.encodeExecuteBatch(to, value, data) + } else { + // transactions.length must be 1 + callData = await this.encodeExecute(to[0], value[0], data[0]) + } + } + + let userOp: Partial<UserOperationStruct> = { + sender: (await this.getAccountAddress()) as Hex, + nonce: toHex(nonceFromFetch), + initCode, + callData + } + + // for this Smart Account current validation module dummy signature will be used to estimate gas + userOp.signature = signature + userOp.paymasterAndData = buildUseropDto?.dummyPndOverride ?? "0x" + + if ( + buildUseropDto?.paymasterServiceData && + buildUseropDto?.paymasterServiceData.mode === PaymasterMode.SPONSORED && + this.paymaster instanceof BiconomyPaymaster + ) { + const gasFeeValues = await this.bundler?.getGasFeeValues() + + // populate gasfee values and make a call to paymaster + userOp.maxFeePerGas = gasFeeValues?.maxFeePerGas as Hex + userOp.maxPriorityFeePerGas = gasFeeValues?.maxPriorityFeePerGas as Hex + + userOp = await this.getPaymasterUserOp( + userOp, + buildUseropDto.paymasterServiceData + ) + return userOp + } + userOp = await this.estimateUserOpGas(userOp) + + if (buildUseropDto?.paymasterServiceData) { + userOp = await this.getPaymasterUserOp( + userOp, + buildUseropDto.paymasterServiceData + ) + } + return userOp + } + + private validateUserOpAndPaymasterRequest( + userOp: Partial<UserOperationStruct>, + tokenPaymasterRequest: BiconomyTokenPaymasterRequest + ): void { + if (isNullOrUndefined(userOp.callData)) { + throw new Error("UserOp callData cannot be undefined") + } + + const feeTokenAddress = tokenPaymasterRequest?.feeQuote?.tokenAddress + Logger.warn("Requested fee token is ", feeTokenAddress) + + if (!feeTokenAddress || feeTokenAddress === ADDRESS_ZERO) { + throw new Error( + "Invalid or missing token address. Token address must be part of the feeQuote in tokenPaymasterRequest" + ) + } + + const spender = tokenPaymasterRequest?.spender + Logger.warn("Spender address is ", spender) + + if (!spender || spender === ADDRESS_ZERO) { + throw new Error( + "Invalid or missing spender address. Sepnder address must be part of tokenPaymasterRequest" + ) + } + } + + /** + * + * @param userOp partial user operation without signature and paymasterAndData + * @param tokenPaymasterRequest This dto provides information about fee quote. Fee quote is received from earlier request getFeeQuotesOrData() to the Biconomy paymaster. + * maxFee and token decimals from the quote, along with the spender is required to append approval transaction. + * @notice This method should be called when gas is paid in ERC20 token using TokenPaymaster + * @description Optional method to update the userOp.calldata with batched transaction which approves the paymaster spender with necessary amount(if required) + * @returns updated userOp with new callData, callGasLimit + */ + async buildTokenPaymasterUserOp( + userOp: Partial<UserOperationStruct>, + tokenPaymasterRequest: BiconomyTokenPaymasterRequest + ): Promise<Partial<UserOperationStruct>> { + this.validateUserOpAndPaymasterRequest(userOp, tokenPaymasterRequest) + try { + let batchTo: Array<Hex> = [] + let batchValue: Array<bigint> = [] + let batchData: Array<Hex> = [] + + let newCallData = userOp.callData + Logger.warn( + "Received information about fee token address and quote ", + tokenPaymasterRequest.toString() + ) + + if (this.paymaster && this.paymaster instanceof Paymaster) { + // Make a call to paymaster.buildTokenApprovalTransaction() with necessary details + + // Review: might request this form of an array of Transaction + const approvalRequest: Transaction = await ( + this.paymaster as IHybridPaymaster<SponsorUserOperationDto> + ).buildTokenApprovalTransaction(tokenPaymasterRequest) + Logger.warn("ApprovalRequest is for erc20 token ", approvalRequest.to) + + if ( + approvalRequest.data === "0x" || + approvalRequest.to === ADDRESS_ZERO + ) { + return userOp + } + + if (isNullOrUndefined(userOp.callData)) { + throw new Error("UserOp callData cannot be undefined") + } + + const decodedSmartAccountData = decodeFunctionData({ + abi: BiconomyAccountAbi, + data: userOp.callData as Hex + }) + + if (!decodedSmartAccountData) { + throw new Error( + "Could not parse userOp call data for this smart account" + ) + } + + const smartAccountExecFunctionName = + decodedSmartAccountData.functionName + + Logger.warn( + `Originally an ${smartAccountExecFunctionName} method call for Biconomy Account V2` + ) + if ( + smartAccountExecFunctionName === "execute" || + smartAccountExecFunctionName === "execute_ncC" + ) { + const methodArgsSmartWalletExecuteCall = decodedSmartAccountData.args + const toOriginal = methodArgsSmartWalletExecuteCall[0] + const valueOriginal = methodArgsSmartWalletExecuteCall[1] + const dataOriginal = methodArgsSmartWalletExecuteCall[2] + + batchTo.push(toOriginal) + batchValue.push(valueOriginal) + batchData.push(dataOriginal) + } else if ( + smartAccountExecFunctionName === "executeBatch" || + smartAccountExecFunctionName === "executeBatch_y6U" + ) { + const methodArgsSmartWalletExecuteCall = decodedSmartAccountData.args + batchTo = [...methodArgsSmartWalletExecuteCall[0]] + batchValue = [...methodArgsSmartWalletExecuteCall[1]] + batchData = [...methodArgsSmartWalletExecuteCall[2]] + } + + if ( + approvalRequest.to && + approvalRequest.data && + approvalRequest.value + ) { + batchTo = [approvalRequest.to as Hex, ...batchTo] + batchValue = [ + BigInt(Number(approvalRequest.value.toString())), + ...batchValue + ] + batchData = [approvalRequest.data as Hex, ...batchData] + + newCallData = await this.encodeExecuteBatch( + batchTo, + batchValue, + batchData + ) + } + const finalUserOp: Partial<UserOperationStruct> = { + ...userOp, + callData: newCallData + } + + // Optionally Requesting to update gas limits again (especially callGasLimit needs to be re-calculated) + + return finalUserOp + } + } catch (error) { + Logger.log("Failed to update userOp. Sending back original op") + Logger.error( + "Failed to update callData with error", + JSON.stringify(error) + ) + return userOp + } + return userOp + } + + async signUserOpHash(userOpHash: string, params?: ModuleInfo): Promise<Hex> { + this.isActiveValidationModuleDefined() + const moduleSig = (await this.activeValidationModule.signUserOpHash( + userOpHash, + params + )) as Hex + + const signatureWithModuleAddress = encodeAbiParameters( + parseAbiParameters("bytes, address"), + [moduleSig, this.activeValidationModule.getAddress() as Hex] + ) + + return signatureWithModuleAddress + } + + /** + * Deploys the smart contract + * + * This method will deploy a Smart Account contract. It is useful for deploying in a moment when you know that gas prices are low, + * and you want to deploy the account before sending the first user operation. This step can otherwise be skipped, + * as the deployment will alternatively be bundled with the first user operation. + * + * @param buildUseropDto {@link BuildUserOpOptions}. + * @returns Promise<{@link UserOpResponse}> that you can use to track the user operation. + * @error Throws an error if the account has already been deployed. + * @error Throws an error if the account has not enough native token balance to deploy, if not using a paymaster. + * + * @example + * import { createClient } from "viem" + * import { createSmartAccountClient } from "@biconomy/account" + * import { createWalletClient, http } from "viem"; + * import { polygonAmoy } from "viem/chains"; + * + * const signer = createWalletClient({ + * account, + * chain: polygonAmoy, + * transport: http(), + * }); + * + * const smartAccount = await createSmartAccountClient({ + * signer, + * biconomyPaymasterApiKey, + * bundlerUrl + * }); + * + * // If you want to use a paymaster... + * const { wait } = await smartAccount.deploy({ + * paymasterServiceData: { mode: PaymasterMode.SPONSORED }, + * }); + * + * // Or if you can't use a paymaster send native token to this address: + * const counterfactualAddress = await smartAccount.getAccountAddress(); + * + * // Then deploy the account + * const { wait } = await smartAccount.deploy(); + * + * const { success, receipt } = await wait(); + * + */ + public async deploy( + buildUseropDto?: BuildUserOpOptions + ): Promise<UserOpResponse> { + const accountAddress = + this.accountAddress ?? (await this.getAccountAddress()) + + // Check that the account has not already been deployed + const byteCode = await this.provider?.getBytecode({ + address: accountAddress as Hex + }) + if (byteCode !== undefined) { + throw new Error(ERROR_MESSAGES.ACCOUNT_ALREADY_DEPLOYED) + } + + // Check that the account has enough native token balance to deploy, if not using a paymaster + if (!buildUseropDto?.paymasterServiceData?.mode) { + const nativeTokenBalance = await this.provider?.getBalance({ + address: accountAddress + }) + if (nativeTokenBalance === BigInt(0)) { + throw new Error(ERROR_MESSAGES.NO_NATIVE_TOKEN_BALANCE_DURING_DEPLOY) + } + } + + const useEmptyDeployCallData = true + + return this.sendTransaction( + { + to: accountAddress, + data: "0x" + }, + { ...buildUseropDto, useEmptyDeployCallData } + ) + } + + async getFactoryData() { + if (await this.isAccountDeployed()) return undefined + + this.isDefaultValidationModuleDefined() + + return encodeFunctionData({ + abi: BiconomyFactoryAbi, + functionName: "deployCounterFactualAccount", + args: [ + this.defaultValidationModule.getAddress() as Hex, + (await this.defaultValidationModule.getInitData()) as Hex, + BigInt(this.index) + ] + }) + } + + async signMessage(message: string | Uint8Array): Promise<Hex> { + let signature: any + this.isActiveValidationModuleDefined() + const dataHash = typeof message === "string" ? toBytes(message) : message + signature = await this.activeValidationModule.signMessage(dataHash) + + const potentiallyIncorrectV = Number.parseInt(signature.slice(-2), 16) + if (![27, 28].includes(potentiallyIncorrectV)) { + const correctV = potentiallyIncorrectV + 27 + signature = signature.slice(0, -2) + correctV.toString(16) + } + if (signature.slice(0, 2) !== "0x") { + signature = `0x${signature}` + } + signature = encodeAbiParameters( + [{ type: "bytes" }, { type: "address" }], + [signature as Hex, this.defaultValidationModule.getAddress()] + ) + if (await this.isAccountDeployed()) { + return signature as Hex + } + const abiEncodedMessage = encodeAbiParameters( + [ + { + type: "address", + name: "create2Factory" + }, + { + type: "bytes", + name: "factoryCalldata" + }, + { + type: "bytes", + name: "originalERC1271Signature" + } + ], + [ + this.getFactoryAddress() ?? "0x", + (await this.getFactoryData()) ?? "0x", + signature + ] + ) + return concat([abiEncodedMessage, MAGIC_BYTES]) + } + + async getIsValidSignatureData( + messageHash: Hex, + signature: Hex + ): Promise<Hex> { + return encodeFunctionData({ + abi: BiconomyAccountAbi, + functionName: "isValidSignature", + args: [messageHash, signature] + }) + } + + async enableModule(moduleAddress: Hex): Promise<UserOpResponse> { + const tx: Transaction = await this.getEnableModuleData(moduleAddress) + const partialUserOp = await this.buildUserOp([tx]) + return this.sendUserOp(partialUserOp) + } + + async getEnableModuleData(moduleAddress: Hex): Promise<Transaction> { + const callData = encodeFunctionData({ + abi: BiconomyAccountAbi, + functionName: "enableModule", + args: [moduleAddress] + }) + const tx: Transaction = { + to: await this.getAddress(), + value: "0x00", + data: callData + } + return tx + } + + async getSetupAndEnableModuleData( + moduleAddress: Hex, + moduleSetupData: Hex + ): Promise<Transaction> { + const callData = encodeFunctionData({ + abi: BiconomyAccountAbi, + functionName: "setupAndEnableModule", + args: [moduleAddress, moduleSetupData] + }) + const tx: Transaction = { + to: await this.getAddress(), + value: "0x00", + data: callData + } + return tx + } + + async disableModule( + prevModule: Hex, + moduleAddress: Hex + ): Promise<UserOpResponse> { + const tx: Transaction = await this.getDisableModuleData( + prevModule, + moduleAddress + ) + const partialUserOp = await this.buildUserOp([tx]) + return this.sendUserOp(partialUserOp) + } + + async getDisableModuleData( + prevModule: Hex, + moduleAddress: Hex + ): Promise<Transaction> { + const callData = encodeFunctionData({ + abi: BiconomyAccountAbi, + functionName: "disableModule", + args: [prevModule, moduleAddress] + }) + const tx: Transaction = { + to: await this.getAddress(), + value: "0x00", + data: callData + } + return tx + } + + async isModuleEnabled(moduleAddress: Hex): Promise<boolean> { + const accountContract = await this._getAccountContract() + return accountContract.read.isModuleEnabled([moduleAddress]) + } + + // Review + async getAllModules(pageSize?: number): Promise<Array<string>> { + const _pageSize = pageSize ?? 100 + const accountContract = await this._getAccountContract() + const result = await accountContract.read.getModulesPaginated([ + this.SENTINEL_MODULE as Hex, + BigInt(_pageSize) + ]) + const modules: Array<string> = result[0] as Array<string> + return modules + } +} diff --git a/packages/account/src/abi/Factory.ts b/src/account/Factory.ts similarity index 76% rename from packages/account/src/abi/Factory.ts rename to src/account/Factory.ts index 3498dd958..c7d148bb2 100644 --- a/packages/account/src/abi/Factory.ts +++ b/src/account/Factory.ts @@ -6,23 +6,23 @@ export const BiconomyFactoryAbi = [ indexed: true, internalType: "address", name: "account", - type: "address", + type: "address" }, { indexed: true, internalType: "address", name: "initialAuthModule", - type: "address", + type: "address" }, { indexed: true, internalType: "uint256", name: "index", - type: "uint256", - }, + type: "uint256" + } ], name: "AccountCreation", - type: "event", + type: "event" }, { anonymous: false, @@ -31,17 +31,17 @@ export const BiconomyFactoryAbi = [ indexed: true, internalType: "address", name: "account", - type: "address", + type: "address" }, { indexed: true, internalType: "address", name: "initialAuthModule", - type: "address", - }, + type: "address" + } ], name: "AccountCreationWithoutIndex", - type: "event", + type: "event" }, { inputs: [], @@ -50,92 +50,92 @@ export const BiconomyFactoryAbi = [ { internalType: "bytes", name: "", - type: "bytes", - }, + type: "bytes" + } ], stateMutability: "pure", - type: "function", + type: "function" }, { inputs: [ { internalType: "address", name: "moduleSetupContract", - type: "address", + type: "address" }, { internalType: "bytes", name: "moduleSetupData", - type: "bytes", - }, + type: "bytes" + } ], name: "deployAccount", outputs: [ { internalType: "address", name: "proxy", - type: "address", - }, + type: "address" + } ], stateMutability: "nonpayable", - type: "function", + type: "function" }, { inputs: [ { internalType: "address", name: "moduleSetupContract", - type: "address", + type: "address" }, { internalType: "bytes", name: "moduleSetupData", - type: "bytes", + type: "bytes" }, { internalType: "uint256", name: "index", - type: "uint256", - }, + type: "uint256" + } ], name: "deployCounterFactualAccount", outputs: [ { internalType: "address", name: "proxy", - type: "address", - }, + type: "address" + } ], stateMutability: "nonpayable", - type: "function", + type: "function" }, { inputs: [ { internalType: "address", name: "moduleSetupContract", - type: "address", + type: "address" }, { internalType: "bytes", name: "moduleSetupData", - type: "bytes", + type: "bytes" }, { internalType: "uint256", name: "index", - type: "uint256", - }, + type: "uint256" + } ], name: "getAddressForCounterFactualAccount", outputs: [ { internalType: "address", name: "_account", - type: "address", - }, + type: "address" + } ], stateMutability: "view", - type: "function", - }, -] as const; + type: "function" + } +] as const diff --git a/src/account/SmartAccount.ts b/src/account/SmartAccount.ts new file mode 100644 index 000000000..541267158 --- /dev/null +++ b/src/account/SmartAccount.ts @@ -0,0 +1,636 @@ +export const BiconomyAccountAbi = [ + { + inputs: [ + { + internalType: "contract IEntryPoint", + name: "anEntryPoint", + type: "address" + } + ], + stateMutability: "nonpayable", + type: "constructor" + }, + { inputs: [], name: "AlreadyInitialized", type: "error" }, + { inputs: [], name: "BaseImplementationCannotBeZero", type: "error" }, + { + inputs: [{ internalType: "address", name: "caller", type: "address" }], + name: "CallerIsNotAnEntryPoint", + type: "error" + }, + { + inputs: [{ internalType: "address", name: "caller", type: "address" }], + name: "CallerIsNotEntryPoint", + type: "error" + }, + { + inputs: [{ internalType: "address", name: "caller", type: "address" }], + name: "CallerIsNotEntryPointOrOwner", + type: "error" + }, + { + inputs: [{ internalType: "address", name: "caller", type: "address" }], + name: "CallerIsNotEntryPointOrSelf", + type: "error" + }, + { + inputs: [{ internalType: "address", name: "caller", type: "address" }], + name: "CallerIsNotOwner", + type: "error" + }, + { + inputs: [{ internalType: "address", name: "caller", type: "address" }], + name: "CallerIsNotSelf", + type: "error" + }, + { inputs: [], name: "DelegateCallsOnly", type: "error" }, + { inputs: [], name: "EntryPointCannotBeZero", type: "error" }, + { inputs: [], name: "HandlerCannotBeZero", type: "error" }, + { + inputs: [ + { + internalType: "address", + name: "implementationAddress", + type: "address" + } + ], + name: "InvalidImplementation", + type: "error" + }, + { + inputs: [{ internalType: "address", name: "caller", type: "address" }], + name: "MixedAuthFail", + type: "error" + }, + { + inputs: [{ internalType: "address", name: "module", type: "address" }], + name: "ModuleAlreadyEnabled", + type: "error" + }, + { + inputs: [ + { internalType: "address", name: "expectedModule", type: "address" }, + { internalType: "address", name: "returnedModule", type: "address" }, + { internalType: "address", name: "prevModule", type: "address" } + ], + name: "ModuleAndPrevModuleMismatch", + type: "error" + }, + { + inputs: [{ internalType: "address", name: "module", type: "address" }], + name: "ModuleCannotBeZeroOrSentinel", + type: "error" + }, + { + inputs: [{ internalType: "address", name: "module", type: "address" }], + name: "ModuleNotEnabled", + type: "error" + }, + { inputs: [], name: "ModulesAlreadyInitialized", type: "error" }, + { inputs: [], name: "ModulesSetupExecutionFailed", type: "error" }, + { inputs: [], name: "OwnerCanNotBeSelf", type: "error" }, + { inputs: [], name: "OwnerCannotBeZero", type: "error" }, + { inputs: [], name: "OwnerProvidedIsSame", type: "error" }, + { inputs: [], name: "TransferToZeroAddressAttempt", type: "error" }, + { + inputs: [ + { internalType: "uint256", name: "destLength", type: "uint256" }, + { internalType: "uint256", name: "valueLength", type: "uint256" }, + { internalType: "uint256", name: "funcLength", type: "uint256" }, + { internalType: "uint256", name: "operationLength", type: "uint256" } + ], + name: "WrongBatchProvided", + type: "error" + }, + { + inputs: [ + { internalType: "bytes", name: "contractSignature", type: "bytes" } + ], + name: "WrongContractSignature", + type: "error" + }, + { + inputs: [ + { internalType: "uint256", name: "uintS", type: "uint256" }, + { + internalType: "uint256", + name: "contractSignatureLength", + type: "uint256" + }, + { internalType: "uint256", name: "signatureLength", type: "uint256" } + ], + name: "WrongContractSignatureFormat", + type: "error" + }, + { + inputs: [ + { + internalType: "address", + name: "moduleAddressProvided", + type: "address" + } + ], + name: "WrongValidationModule", + type: "error" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "previousHandler", + type: "address" + }, + { + indexed: true, + internalType: "address", + name: "handler", + type: "address" + } + ], + name: "ChangedFallbackHandler", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "module", + type: "address" + } + ], + name: "DisabledModule", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "module", + type: "address" + } + ], + name: "EnabledModule", + type: "event" + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: "address", name: "to", type: "address" }, + { + indexed: true, + internalType: "uint256", + name: "value", + type: "uint256" + }, + { indexed: true, internalType: "bytes", name: "data", type: "bytes" }, + { + indexed: false, + internalType: "enum Enum.Operation", + name: "operation", + type: "uint8" + }, + { + indexed: false, + internalType: "uint256", + name: "txGas", + type: "uint256" + } + ], + name: "ExecutionFailure", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "module", + type: "address" + } + ], + name: "ExecutionFromModuleFailure", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "module", + type: "address" + } + ], + name: "ExecutionFromModuleSuccess", + type: "event" + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: "address", name: "to", type: "address" }, + { + indexed: true, + internalType: "uint256", + name: "value", + type: "uint256" + }, + { indexed: true, internalType: "bytes", name: "data", type: "bytes" }, + { + indexed: false, + internalType: "enum Enum.Operation", + name: "operation", + type: "uint8" + }, + { + indexed: false, + internalType: "uint256", + name: "txGas", + type: "uint256" + } + ], + name: "ExecutionSuccess", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "oldImplementation", + type: "address" + }, + { + indexed: true, + internalType: "address", + name: "newImplementation", + type: "address" + } + ], + name: "ImplementationUpdated", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "module", + type: "address" + }, + { indexed: false, internalType: "address", name: "to", type: "address" }, + { + indexed: false, + internalType: "uint256", + name: "value", + type: "uint256" + }, + { indexed: false, internalType: "bytes", name: "data", type: "bytes" }, + { + indexed: false, + internalType: "enum Enum.Operation", + name: "operation", + type: "uint8" + } + ], + name: "ModuleTransaction", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "sender", + type: "address" + }, + { indexed: true, internalType: "uint256", name: "value", type: "uint256" } + ], + name: "SmartAccountReceivedNativeToken", + type: "event" + }, + { stateMutability: "nonpayable", type: "fallback" }, + { + inputs: [], + name: "VERSION", + outputs: [{ internalType: "string", name: "", type: "string" }], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "addDeposit", + outputs: [], + stateMutability: "payable", + type: "function" + }, + { + inputs: [ + { internalType: "address", name: "prevModule", type: "address" }, + { internalType: "address", name: "module", type: "address" } + ], + name: "disableModule", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [{ internalType: "address", name: "module", type: "address" }], + name: "enableModule", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [], + name: "entryPoint", + outputs: [ + { internalType: "contract IEntryPoint", name: "", type: "address" } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { internalType: "address[]", name: "to", type: "address[]" }, + { internalType: "uint256[]", name: "value", type: "uint256[]" }, + { internalType: "bytes[]", name: "data", type: "bytes[]" }, + { + internalType: "enum Enum.Operation[]", + name: "operations", + type: "uint8[]" + } + ], + name: "execBatchTransactionFromModule", + outputs: [{ internalType: "bool", name: "success", type: "bool" }], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { internalType: "address", name: "to", type: "address" }, + { internalType: "uint256", name: "value", type: "uint256" }, + { internalType: "bytes", name: "data", type: "bytes" }, + { internalType: "enum Enum.Operation", name: "operation", type: "uint8" }, + { internalType: "uint256", name: "txGas", type: "uint256" } + ], + name: "execTransactionFromModule", + outputs: [{ internalType: "bool", name: "success", type: "bool" }], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { internalType: "address", name: "to", type: "address" }, + { internalType: "uint256", name: "value", type: "uint256" }, + { internalType: "bytes", name: "data", type: "bytes" }, + { internalType: "enum Enum.Operation", name: "operation", type: "uint8" } + ], + name: "execTransactionFromModule", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { internalType: "address", name: "to", type: "address" }, + { internalType: "uint256", name: "value", type: "uint256" }, + { internalType: "bytes", name: "data", type: "bytes" }, + { internalType: "enum Enum.Operation", name: "operation", type: "uint8" } + ], + name: "execTransactionFromModuleReturnData", + outputs: [ + { internalType: "bool", name: "success", type: "bool" }, + { internalType: "bytes", name: "returnData", type: "bytes" } + ], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { internalType: "address", name: "dest", type: "address" }, + { internalType: "uint256", name: "value", type: "uint256" }, + { internalType: "bytes", name: "func", type: "bytes" } + ], + name: "execute", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { internalType: "address[]", name: "dest", type: "address[]" }, + { internalType: "uint256[]", name: "value", type: "uint256[]" }, + { internalType: "bytes[]", name: "func", type: "bytes[]" } + ], + name: "executeBatch", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { internalType: "address[]", name: "dest", type: "address[]" }, + { internalType: "uint256[]", name: "value", type: "uint256[]" }, + { internalType: "bytes[]", name: "func", type: "bytes[]" } + ], + name: "executeBatch_y6U", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { internalType: "address", name: "dest", type: "address" }, + { internalType: "uint256", name: "value", type: "uint256" }, + { internalType: "bytes", name: "func", type: "bytes" } + ], + name: "execute_ncC", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [], + name: "getDeposit", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "getFallbackHandler", + outputs: [{ internalType: "address", name: "_handler", type: "address" }], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "getImplementation", + outputs: [ + { internalType: "address", name: "_implementation", type: "address" } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { internalType: "address", name: "start", type: "address" }, + { internalType: "uint256", name: "pageSize", type: "uint256" } + ], + name: "getModulesPaginated", + outputs: [ + { internalType: "address[]", name: "array", type: "address[]" }, + { internalType: "address", name: "next", type: "address" } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { internalType: "address", name: "handler", type: "address" }, + { internalType: "address", name: "moduleSetupContract", type: "address" }, + { internalType: "bytes", name: "moduleSetupData", type: "bytes" } + ], + name: "init", + outputs: [{ internalType: "address", name: "", type: "address" }], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [{ internalType: "address", name: "module", type: "address" }], + name: "isModuleEnabled", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { internalType: "bytes32", name: "dataHash", type: "bytes32" }, + { internalType: "bytes", name: "signature", type: "bytes" } + ], + name: "isValidSignature", + outputs: [{ internalType: "bytes4", name: "", type: "bytes4" }], + stateMutability: "view", + type: "function" + }, + { + inputs: [{ internalType: "uint192", name: "_key", type: "uint192" }], + name: "nonce", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function" + }, + { + inputs: [{ internalType: "uint256", name: "", type: "uint256" }], + name: "noncesDeprecated", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "ownerDeprecated", + outputs: [{ internalType: "address", name: "", type: "address" }], + stateMutability: "view", + type: "function" + }, + { + inputs: [{ internalType: "address", name: "handler", type: "address" }], + name: "setFallbackHandler", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { internalType: "address", name: "setupContract", type: "address" }, + { internalType: "bytes", name: "setupData", type: "bytes" } + ], + name: "setupAndEnableModule", + outputs: [{ internalType: "address", name: "", type: "address" }], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [{ internalType: "bytes4", name: "_interfaceId", type: "bytes4" }], + name: "supportsInterface", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { internalType: "address", name: "_implementation", type: "address" } + ], + name: "updateImplementation", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + components: [ + { internalType: "address", name: "sender", type: "address" }, + { internalType: "uint256", name: "nonce", type: "uint256" }, + { internalType: "bytes", name: "initCode", type: "bytes" }, + { internalType: "bytes", name: "callData", type: "bytes" }, + { internalType: "uint256", name: "callGasLimit", type: "uint256" }, + { + internalType: "uint256", + name: "verificationGasLimit", + type: "uint256" + }, + { + internalType: "uint256", + name: "preVerificationGas", + type: "uint256" + }, + { internalType: "uint256", name: "maxFeePerGas", type: "uint256" }, + { + internalType: "uint256", + name: "maxPriorityFeePerGas", + type: "uint256" + }, + { internalType: "bytes", name: "paymasterAndData", type: "bytes" }, + { internalType: "bytes", name: "signature", type: "bytes" } + ], + internalType: "struct UserOperation", + name: "userOp", + type: "tuple" + }, + { internalType: "bytes32", name: "userOpHash", type: "bytes32" }, + { internalType: "uint256", name: "missingAccountFunds", type: "uint256" } + ], + name: "validateUserOp", + outputs: [ + { internalType: "uint256", name: "validationData", type: "uint256" } + ], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "address payable", + name: "withdrawAddress", + type: "address" + }, + { internalType: "uint256", name: "amount", type: "uint256" } + ], + name: "withdrawDepositTo", + outputs: [], + stateMutability: "payable", + type: "function" + }, + { stateMutability: "payable", type: "receive" } +] as const diff --git a/packages/account/src/abi/AccountResolver.ts b/src/account/abi/AccountResolver.ts similarity index 81% rename from packages/account/src/abi/AccountResolver.ts rename to src/account/abi/AccountResolver.ts index 0cbffc749..2dfd45303 100644 --- a/packages/account/src/abi/AccountResolver.ts +++ b/src/account/abi/AccountResolver.ts @@ -3,22 +3,22 @@ export const AccountResolverAbi = [ inputs: [ { internalType: "address", name: "_v1Factory", type: "address" }, { internalType: "address", name: "_v2Factory", type: "address" }, - { internalType: "address", name: "_ecdsaModule", type: "address" }, + { internalType: "address", name: "_ecdsaModule", type: "address" } ], stateMutability: "nonpayable", - type: "constructor", + type: "constructor" }, { inputs: [], name: "ecdsaOwnershipModule", outputs: [{ internalType: "address", name: "", type: "address" }], stateMutability: "view", - type: "function", + type: "function" }, { inputs: [ { internalType: "address", name: "_eoa", type: "address" }, - { internalType: "uint8", name: "_maxIndex", type: "uint8" }, + { internalType: "uint8", name: "_maxIndex", type: "uint8" } ], name: "resolveAddresses", outputs: [ @@ -26,25 +26,29 @@ export const AccountResolverAbi = [ components: [ { internalType: "address", name: "accountAddress", type: "address" }, { internalType: "address", name: "factoryAddress", type: "address" }, - { internalType: "address", name: "currentImplementation", type: "address" }, + { + internalType: "address", + name: "currentImplementation", + type: "address" + }, { internalType: "string", name: "currentVersion", type: "string" }, { internalType: "string", name: "factoryVersion", type: "string" }, - { internalType: "uint256", name: "deploymentIndex", type: "uint256" }, + { internalType: "uint256", name: "deploymentIndex", type: "uint256" } ], internalType: "struct IAddressResolver.SmartAccountResult[]", name: "", - type: "tuple[]", - }, + type: "tuple[]" + } ], stateMutability: "view", - type: "function", + type: "function" }, { inputs: [ { internalType: "address", name: "_eoa", type: "address" }, { internalType: "uint8", name: "_maxIndex", type: "uint8" }, { internalType: "address", name: "_moduleAddress", type: "address" }, - { internalType: "bytes", name: "_moduleSetupData", type: "bytes" }, + { internalType: "bytes", name: "_moduleSetupData", type: "bytes" } ], name: "resolveAddressesFlexibleForV2", outputs: [ @@ -52,23 +56,27 @@ export const AccountResolverAbi = [ components: [ { internalType: "address", name: "accountAddress", type: "address" }, { internalType: "address", name: "factoryAddress", type: "address" }, - { internalType: "address", name: "currentImplementation", type: "address" }, + { + internalType: "address", + name: "currentImplementation", + type: "address" + }, { internalType: "string", name: "currentVersion", type: "string" }, { internalType: "string", name: "factoryVersion", type: "string" }, - { internalType: "uint256", name: "deploymentIndex", type: "uint256" }, + { internalType: "uint256", name: "deploymentIndex", type: "uint256" } ], internalType: "struct IAddressResolver.SmartAccountResult[]", name: "", - type: "tuple[]", - }, + type: "tuple[]" + } ], stateMutability: "view", - type: "function", + type: "function" }, { inputs: [ { internalType: "address", name: "_eoa", type: "address" }, - { internalType: "uint8", name: "_maxIndex", type: "uint8" }, + { internalType: "uint8", name: "_maxIndex", type: "uint8" } ], name: "resolveAddressesV1", outputs: [ @@ -76,31 +84,35 @@ export const AccountResolverAbi = [ components: [ { internalType: "address", name: "accountAddress", type: "address" }, { internalType: "address", name: "factoryAddress", type: "address" }, - { internalType: "address", name: "currentImplementation", type: "address" }, + { + internalType: "address", + name: "currentImplementation", + type: "address" + }, { internalType: "string", name: "currentVersion", type: "string" }, { internalType: "string", name: "factoryVersion", type: "string" }, - { internalType: "uint256", name: "deploymentIndex", type: "uint256" }, + { internalType: "uint256", name: "deploymentIndex", type: "uint256" } ], internalType: "struct IAddressResolver.SmartAccountResult[]", name: "", - type: "tuple[]", - }, + type: "tuple[]" + } ], stateMutability: "view", - type: "function", + type: "function" }, { inputs: [], name: "smartAccountFactoryV1", outputs: [{ internalType: "address", name: "", type: "address" }], stateMutability: "view", - type: "function", + type: "function" }, { inputs: [], name: "smartAccountFactoryV2", outputs: [{ internalType: "address", name: "", type: "address" }], stateMutability: "view", - type: "function", - }, -] as const; + type: "function" + } +] as const diff --git a/src/account/abi/EntryPointAbi.ts b/src/account/abi/EntryPointAbi.ts new file mode 100644 index 000000000..695b3e7e7 --- /dev/null +++ b/src/account/abi/EntryPointAbi.ts @@ -0,0 +1,1309 @@ +export const EntryPointAbi = [ + { + inputs: [ + { + internalType: "uint256", + name: "preOpGas", + type: "uint256" + }, + { + internalType: "uint256", + name: "paid", + type: "uint256" + }, + { + internalType: "uint48", + name: "validAfter", + type: "uint48" + }, + { + internalType: "uint48", + name: "validUntil", + type: "uint48" + }, + { + internalType: "bool", + name: "targetSuccess", + type: "bool" + }, + { + internalType: "bytes", + name: "targetResult", + type: "bytes" + } + ], + name: "ExecutionResult", + type: "error" + }, + { + inputs: [ + { + internalType: "uint256", + name: "opIndex", + type: "uint256" + }, + { + internalType: "string", + name: "reason", + type: "string" + } + ], + name: "FailedOp", + type: "error" + }, + { + inputs: [ + { + internalType: "address", + name: "sender", + type: "address" + } + ], + name: "SenderAddressResult", + type: "error" + }, + { + inputs: [ + { + internalType: "address", + name: "aggregator", + type: "address" + } + ], + name: "SignatureValidationFailed", + type: "error" + }, + { + inputs: [ + { + components: [ + { + internalType: "uint256", + name: "preOpGas", + type: "uint256" + }, + { + internalType: "uint256", + name: "prefund", + type: "uint256" + }, + { + internalType: "bool", + name: "sigFailed", + type: "bool" + }, + { + internalType: "uint48", + name: "validAfter", + type: "uint48" + }, + { + internalType: "uint48", + name: "validUntil", + type: "uint48" + }, + { + internalType: "bytes", + name: "paymasterContext", + type: "bytes" + } + ], + internalType: "struct IEntryPoint.ReturnInfo", + name: "returnInfo", + type: "tuple" + }, + { + components: [ + { + internalType: "uint256", + name: "stake", + type: "uint256" + }, + { + internalType: "uint256", + name: "unstakeDelaySec", + type: "uint256" + } + ], + internalType: "struct IStakeManager.StakeInfo", + name: "senderInfo", + type: "tuple" + }, + { + components: [ + { + internalType: "uint256", + name: "stake", + type: "uint256" + }, + { + internalType: "uint256", + name: "unstakeDelaySec", + type: "uint256" + } + ], + internalType: "struct IStakeManager.StakeInfo", + name: "factoryInfo", + type: "tuple" + }, + { + components: [ + { + internalType: "uint256", + name: "stake", + type: "uint256" + }, + { + internalType: "uint256", + name: "unstakeDelaySec", + type: "uint256" + } + ], + internalType: "struct IStakeManager.StakeInfo", + name: "paymasterInfo", + type: "tuple" + } + ], + name: "ValidationResult", + type: "error" + }, + { + inputs: [ + { + components: [ + { + internalType: "uint256", + name: "preOpGas", + type: "uint256" + }, + { + internalType: "uint256", + name: "prefund", + type: "uint256" + }, + { + internalType: "bool", + name: "sigFailed", + type: "bool" + }, + { + internalType: "uint48", + name: "validAfter", + type: "uint48" + }, + { + internalType: "uint48", + name: "validUntil", + type: "uint48" + }, + { + internalType: "bytes", + name: "paymasterContext", + type: "bytes" + } + ], + internalType: "struct IEntryPoint.ReturnInfo", + name: "returnInfo", + type: "tuple" + }, + { + components: [ + { + internalType: "uint256", + name: "stake", + type: "uint256" + }, + { + internalType: "uint256", + name: "unstakeDelaySec", + type: "uint256" + } + ], + internalType: "struct IStakeManager.StakeInfo", + name: "senderInfo", + type: "tuple" + }, + { + components: [ + { + internalType: "uint256", + name: "stake", + type: "uint256" + }, + { + internalType: "uint256", + name: "unstakeDelaySec", + type: "uint256" + } + ], + internalType: "struct IStakeManager.StakeInfo", + name: "factoryInfo", + type: "tuple" + }, + { + components: [ + { + internalType: "uint256", + name: "stake", + type: "uint256" + }, + { + internalType: "uint256", + name: "unstakeDelaySec", + type: "uint256" + } + ], + internalType: "struct IStakeManager.StakeInfo", + name: "paymasterInfo", + type: "tuple" + }, + { + components: [ + { + internalType: "address", + name: "aggregator", + type: "address" + }, + { + components: [ + { + internalType: "uint256", + name: "stake", + type: "uint256" + }, + { + internalType: "uint256", + name: "unstakeDelaySec", + type: "uint256" + } + ], + internalType: "struct IStakeManager.StakeInfo", + name: "stakeInfo", + type: "tuple" + } + ], + internalType: "struct IEntryPoint.AggregatorStakeInfo", + name: "aggregatorInfo", + type: "tuple" + } + ], + name: "ValidationResultWithAggregation", + type: "error" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "userOpHash", + type: "bytes32" + }, + { + indexed: true, + internalType: "address", + name: "sender", + type: "address" + }, + { + indexed: false, + internalType: "address", + name: "factory", + type: "address" + }, + { + indexed: false, + internalType: "address", + name: "paymaster", + type: "address" + } + ], + name: "AccountDeployed", + type: "event" + }, + { + anonymous: false, + inputs: [], + name: "BeforeExecution", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "account", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "totalDeposit", + type: "uint256" + } + ], + name: "Deposited", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "aggregator", + type: "address" + } + ], + name: "SignatureAggregatorChanged", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "account", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "totalStaked", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "unstakeDelaySec", + type: "uint256" + } + ], + name: "StakeLocked", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "account", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "withdrawTime", + type: "uint256" + } + ], + name: "StakeUnlocked", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "account", + type: "address" + }, + { + indexed: false, + internalType: "address", + name: "withdrawAddress", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256" + } + ], + name: "StakeWithdrawn", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "userOpHash", + type: "bytes32" + }, + { + indexed: true, + internalType: "address", + name: "sender", + type: "address" + }, + { + indexed: true, + internalType: "address", + name: "paymaster", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "nonce", + type: "uint256" + }, + { + indexed: false, + internalType: "bool", + name: "success", + type: "bool" + }, + { + indexed: false, + internalType: "uint256", + name: "actualGasCost", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "actualGasUsed", + type: "uint256" + } + ], + name: "UserOperationEvent", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "userOpHash", + type: "bytes32" + }, + { + indexed: true, + internalType: "address", + name: "sender", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "nonce", + type: "uint256" + }, + { + indexed: false, + internalType: "bytes", + name: "revertReason", + type: "bytes" + } + ], + name: "UserOperationRevertReason", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "account", + type: "address" + }, + { + indexed: false, + internalType: "address", + name: "withdrawAddress", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256" + } + ], + name: "Withdrawn", + type: "event" + }, + { + inputs: [], + name: "SIG_VALIDATION_FAILED", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "bytes", + name: "initCode", + type: "bytes" + }, + { + internalType: "address", + name: "sender", + type: "address" + }, + { + internalType: "bytes", + name: "paymasterAndData", + type: "bytes" + } + ], + name: "_validateSenderAndPaymaster", + outputs: [], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "uint32", + name: "unstakeDelaySec", + type: "uint32" + } + ], + name: "addStake", + outputs: [], + stateMutability: "payable", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "account", + type: "address" + } + ], + name: "balanceOf", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "account", + type: "address" + } + ], + name: "depositTo", + outputs: [], + stateMutability: "payable", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "", + type: "address" + } + ], + name: "deposits", + outputs: [ + { + internalType: "uint112", + name: "deposit", + type: "uint112" + }, + { + internalType: "bool", + name: "staked", + type: "bool" + }, + { + internalType: "uint112", + name: "stake", + type: "uint112" + }, + { + internalType: "uint32", + name: "unstakeDelaySec", + type: "uint32" + }, + { + internalType: "uint48", + name: "withdrawTime", + type: "uint48" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "account", + type: "address" + } + ], + name: "getDepositInfo", + outputs: [ + { + components: [ + { + internalType: "uint112", + name: "deposit", + type: "uint112" + }, + { + internalType: "bool", + name: "staked", + type: "bool" + }, + { + internalType: "uint112", + name: "stake", + type: "uint112" + }, + { + internalType: "uint32", + name: "unstakeDelaySec", + type: "uint32" + }, + { + internalType: "uint48", + name: "withdrawTime", + type: "uint48" + } + ], + internalType: "struct IStakeManager.DepositInfo", + name: "info", + type: "tuple" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "sender", + type: "address" + }, + { + internalType: "uint192", + name: "key", + type: "uint192" + } + ], + name: "getNonce", + outputs: [ + { + internalType: "uint256", + name: "nonce", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "bytes", + name: "initCode", + type: "bytes" + } + ], + name: "getSenderAddress", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + components: [ + { + internalType: "address", + name: "sender", + type: "address" + }, + { + internalType: "uint256", + name: "nonce", + type: "uint256" + }, + { + internalType: "bytes", + name: "initCode", + type: "bytes" + }, + { + internalType: "bytes", + name: "callData", + type: "bytes" + }, + { + internalType: "uint256", + name: "callGasLimit", + type: "uint256" + }, + { + internalType: "uint256", + name: "verificationGasLimit", + type: "uint256" + }, + { + internalType: "uint256", + name: "preVerificationGas", + type: "uint256" + }, + { + internalType: "uint256", + name: "maxFeePerGas", + type: "uint256" + }, + { + internalType: "uint256", + name: "maxPriorityFeePerGas", + type: "uint256" + }, + { + internalType: "bytes", + name: "paymasterAndData", + type: "bytes" + }, + { + internalType: "bytes", + name: "signature", + type: "bytes" + } + ], + internalType: "struct UserOperation", + name: "userOp", + type: "tuple" + } + ], + name: "getUserOpHash", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + components: [ + { + components: [ + { + internalType: "address", + name: "sender", + type: "address" + }, + { + internalType: "uint256", + name: "nonce", + type: "uint256" + }, + { + internalType: "bytes", + name: "initCode", + type: "bytes" + }, + { + internalType: "bytes", + name: "callData", + type: "bytes" + }, + { + internalType: "uint256", + name: "callGasLimit", + type: "uint256" + }, + { + internalType: "uint256", + name: "verificationGasLimit", + type: "uint256" + }, + { + internalType: "uint256", + name: "preVerificationGas", + type: "uint256" + }, + { + internalType: "uint256", + name: "maxFeePerGas", + type: "uint256" + }, + { + internalType: "uint256", + name: "maxPriorityFeePerGas", + type: "uint256" + }, + { + internalType: "bytes", + name: "paymasterAndData", + type: "bytes" + }, + { + internalType: "bytes", + name: "signature", + type: "bytes" + } + ], + internalType: "struct UserOperation[]", + name: "userOps", + type: "tuple[]" + }, + { + internalType: "contract IAggregator", + name: "aggregator", + type: "address" + }, + { + internalType: "bytes", + name: "signature", + type: "bytes" + } + ], + internalType: "struct IEntryPoint.UserOpsPerAggregator[]", + name: "opsPerAggregator", + type: "tuple[]" + }, + { + internalType: "address payable", + name: "beneficiary", + type: "address" + } + ], + name: "handleAggregatedOps", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + components: [ + { + internalType: "address", + name: "sender", + type: "address" + }, + { + internalType: "uint256", + name: "nonce", + type: "uint256" + }, + { + internalType: "bytes", + name: "initCode", + type: "bytes" + }, + { + internalType: "bytes", + name: "callData", + type: "bytes" + }, + { + internalType: "uint256", + name: "callGasLimit", + type: "uint256" + }, + { + internalType: "uint256", + name: "verificationGasLimit", + type: "uint256" + }, + { + internalType: "uint256", + name: "preVerificationGas", + type: "uint256" + }, + { + internalType: "uint256", + name: "maxFeePerGas", + type: "uint256" + }, + { + internalType: "uint256", + name: "maxPriorityFeePerGas", + type: "uint256" + }, + { + internalType: "bytes", + name: "paymasterAndData", + type: "bytes" + }, + { + internalType: "bytes", + name: "signature", + type: "bytes" + } + ], + internalType: "struct UserOperation[]", + name: "ops", + type: "tuple[]" + }, + { + internalType: "address payable", + name: "beneficiary", + type: "address" + } + ], + name: "handleOps", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "uint192", + name: "key", + type: "uint192" + } + ], + name: "incrementNonce", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "bytes", + name: "callData", + type: "bytes" + }, + { + components: [ + { + components: [ + { + internalType: "address", + name: "sender", + type: "address" + }, + { + internalType: "uint256", + name: "nonce", + type: "uint256" + }, + { + internalType: "uint256", + name: "callGasLimit", + type: "uint256" + }, + { + internalType: "uint256", + name: "verificationGasLimit", + type: "uint256" + }, + { + internalType: "uint256", + name: "preVerificationGas", + type: "uint256" + }, + { + internalType: "address", + name: "paymaster", + type: "address" + }, + { + internalType: "uint256", + name: "maxFeePerGas", + type: "uint256" + }, + { + internalType: "uint256", + name: "maxPriorityFeePerGas", + type: "uint256" + } + ], + internalType: "struct EntryPoint.MemoryUserOp", + name: "mUserOp", + type: "tuple" + }, + { + internalType: "bytes32", + name: "userOpHash", + type: "bytes32" + }, + { + internalType: "uint256", + name: "prefund", + type: "uint256" + }, + { + internalType: "uint256", + name: "contextOffset", + type: "uint256" + }, + { + internalType: "uint256", + name: "preOpGas", + type: "uint256" + } + ], + internalType: "struct EntryPoint.UserOpInfo", + name: "opInfo", + type: "tuple" + }, + { + internalType: "bytes", + name: "context", + type: "bytes" + } + ], + name: "innerHandleOp", + outputs: [ + { + internalType: "uint256", + name: "actualGasCost", + type: "uint256" + } + ], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "", + type: "address" + }, + { + internalType: "uint192", + name: "", + type: "uint192" + } + ], + name: "nonceSequenceNumber", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + components: [ + { + internalType: "address", + name: "sender", + type: "address" + }, + { + internalType: "uint256", + name: "nonce", + type: "uint256" + }, + { + internalType: "bytes", + name: "initCode", + type: "bytes" + }, + { + internalType: "bytes", + name: "callData", + type: "bytes" + }, + { + internalType: "uint256", + name: "callGasLimit", + type: "uint256" + }, + { + internalType: "uint256", + name: "verificationGasLimit", + type: "uint256" + }, + { + internalType: "uint256", + name: "preVerificationGas", + type: "uint256" + }, + { + internalType: "uint256", + name: "maxFeePerGas", + type: "uint256" + }, + { + internalType: "uint256", + name: "maxPriorityFeePerGas", + type: "uint256" + }, + { + internalType: "bytes", + name: "paymasterAndData", + type: "bytes" + }, + { + internalType: "bytes", + name: "signature", + type: "bytes" + } + ], + internalType: "struct UserOperation", + name: "op", + type: "tuple" + }, + { + internalType: "address", + name: "target", + type: "address" + }, + { + internalType: "bytes", + name: "targetCallData", + type: "bytes" + } + ], + name: "simulateHandleOp", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + components: [ + { + internalType: "address", + name: "sender", + type: "address" + }, + { + internalType: "uint256", + name: "nonce", + type: "uint256" + }, + { + internalType: "bytes", + name: "initCode", + type: "bytes" + }, + { + internalType: "bytes", + name: "callData", + type: "bytes" + }, + { + internalType: "uint256", + name: "callGasLimit", + type: "uint256" + }, + { + internalType: "uint256", + name: "verificationGasLimit", + type: "uint256" + }, + { + internalType: "uint256", + name: "preVerificationGas", + type: "uint256" + }, + { + internalType: "uint256", + name: "maxFeePerGas", + type: "uint256" + }, + { + internalType: "uint256", + name: "maxPriorityFeePerGas", + type: "uint256" + }, + { + internalType: "bytes", + name: "paymasterAndData", + type: "bytes" + }, + { + internalType: "bytes", + name: "signature", + type: "bytes" + } + ], + internalType: "struct UserOperation", + name: "userOp", + type: "tuple" + } + ], + name: "simulateValidation", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [], + name: "unlockStake", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "address payable", + name: "withdrawAddress", + type: "address" + } + ], + name: "withdrawStake", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "address payable", + name: "withdrawAddress", + type: "address" + }, + { + internalType: "uint256", + name: "withdrawAmount", + type: "uint256" + } + ], + name: "withdrawTo", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + stateMutability: "payable", + type: "receive" + } +] as const diff --git a/src/account/abi/Factory.ts b/src/account/abi/Factory.ts new file mode 100644 index 000000000..c7d148bb2 --- /dev/null +++ b/src/account/abi/Factory.ts @@ -0,0 +1,141 @@ +export const BiconomyFactoryAbi = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "account", + type: "address" + }, + { + indexed: true, + internalType: "address", + name: "initialAuthModule", + type: "address" + }, + { + indexed: true, + internalType: "uint256", + name: "index", + type: "uint256" + } + ], + name: "AccountCreation", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "account", + type: "address" + }, + { + indexed: true, + internalType: "address", + name: "initialAuthModule", + type: "address" + } + ], + name: "AccountCreationWithoutIndex", + type: "event" + }, + { + inputs: [], + name: "accountCreationCode", + outputs: [ + { + internalType: "bytes", + name: "", + type: "bytes" + } + ], + stateMutability: "pure", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "moduleSetupContract", + type: "address" + }, + { + internalType: "bytes", + name: "moduleSetupData", + type: "bytes" + } + ], + name: "deployAccount", + outputs: [ + { + internalType: "address", + name: "proxy", + type: "address" + } + ], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "moduleSetupContract", + type: "address" + }, + { + internalType: "bytes", + name: "moduleSetupData", + type: "bytes" + }, + { + internalType: "uint256", + name: "index", + type: "uint256" + } + ], + name: "deployCounterFactualAccount", + outputs: [ + { + internalType: "address", + name: "proxy", + type: "address" + } + ], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "moduleSetupContract", + type: "address" + }, + { + internalType: "bytes", + name: "moduleSetupData", + type: "bytes" + }, + { + internalType: "uint256", + name: "index", + type: "uint256" + } + ], + name: "getAddressForCounterFactualAccount", + outputs: [ + { + internalType: "address", + name: "_account", + type: "address" + } + ], + stateMutability: "view", + type: "function" + } +] as const diff --git a/src/account/abi/SmartAccount.ts b/src/account/abi/SmartAccount.ts new file mode 100644 index 000000000..541267158 --- /dev/null +++ b/src/account/abi/SmartAccount.ts @@ -0,0 +1,636 @@ +export const BiconomyAccountAbi = [ + { + inputs: [ + { + internalType: "contract IEntryPoint", + name: "anEntryPoint", + type: "address" + } + ], + stateMutability: "nonpayable", + type: "constructor" + }, + { inputs: [], name: "AlreadyInitialized", type: "error" }, + { inputs: [], name: "BaseImplementationCannotBeZero", type: "error" }, + { + inputs: [{ internalType: "address", name: "caller", type: "address" }], + name: "CallerIsNotAnEntryPoint", + type: "error" + }, + { + inputs: [{ internalType: "address", name: "caller", type: "address" }], + name: "CallerIsNotEntryPoint", + type: "error" + }, + { + inputs: [{ internalType: "address", name: "caller", type: "address" }], + name: "CallerIsNotEntryPointOrOwner", + type: "error" + }, + { + inputs: [{ internalType: "address", name: "caller", type: "address" }], + name: "CallerIsNotEntryPointOrSelf", + type: "error" + }, + { + inputs: [{ internalType: "address", name: "caller", type: "address" }], + name: "CallerIsNotOwner", + type: "error" + }, + { + inputs: [{ internalType: "address", name: "caller", type: "address" }], + name: "CallerIsNotSelf", + type: "error" + }, + { inputs: [], name: "DelegateCallsOnly", type: "error" }, + { inputs: [], name: "EntryPointCannotBeZero", type: "error" }, + { inputs: [], name: "HandlerCannotBeZero", type: "error" }, + { + inputs: [ + { + internalType: "address", + name: "implementationAddress", + type: "address" + } + ], + name: "InvalidImplementation", + type: "error" + }, + { + inputs: [{ internalType: "address", name: "caller", type: "address" }], + name: "MixedAuthFail", + type: "error" + }, + { + inputs: [{ internalType: "address", name: "module", type: "address" }], + name: "ModuleAlreadyEnabled", + type: "error" + }, + { + inputs: [ + { internalType: "address", name: "expectedModule", type: "address" }, + { internalType: "address", name: "returnedModule", type: "address" }, + { internalType: "address", name: "prevModule", type: "address" } + ], + name: "ModuleAndPrevModuleMismatch", + type: "error" + }, + { + inputs: [{ internalType: "address", name: "module", type: "address" }], + name: "ModuleCannotBeZeroOrSentinel", + type: "error" + }, + { + inputs: [{ internalType: "address", name: "module", type: "address" }], + name: "ModuleNotEnabled", + type: "error" + }, + { inputs: [], name: "ModulesAlreadyInitialized", type: "error" }, + { inputs: [], name: "ModulesSetupExecutionFailed", type: "error" }, + { inputs: [], name: "OwnerCanNotBeSelf", type: "error" }, + { inputs: [], name: "OwnerCannotBeZero", type: "error" }, + { inputs: [], name: "OwnerProvidedIsSame", type: "error" }, + { inputs: [], name: "TransferToZeroAddressAttempt", type: "error" }, + { + inputs: [ + { internalType: "uint256", name: "destLength", type: "uint256" }, + { internalType: "uint256", name: "valueLength", type: "uint256" }, + { internalType: "uint256", name: "funcLength", type: "uint256" }, + { internalType: "uint256", name: "operationLength", type: "uint256" } + ], + name: "WrongBatchProvided", + type: "error" + }, + { + inputs: [ + { internalType: "bytes", name: "contractSignature", type: "bytes" } + ], + name: "WrongContractSignature", + type: "error" + }, + { + inputs: [ + { internalType: "uint256", name: "uintS", type: "uint256" }, + { + internalType: "uint256", + name: "contractSignatureLength", + type: "uint256" + }, + { internalType: "uint256", name: "signatureLength", type: "uint256" } + ], + name: "WrongContractSignatureFormat", + type: "error" + }, + { + inputs: [ + { + internalType: "address", + name: "moduleAddressProvided", + type: "address" + } + ], + name: "WrongValidationModule", + type: "error" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "previousHandler", + type: "address" + }, + { + indexed: true, + internalType: "address", + name: "handler", + type: "address" + } + ], + name: "ChangedFallbackHandler", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "module", + type: "address" + } + ], + name: "DisabledModule", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "module", + type: "address" + } + ], + name: "EnabledModule", + type: "event" + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: "address", name: "to", type: "address" }, + { + indexed: true, + internalType: "uint256", + name: "value", + type: "uint256" + }, + { indexed: true, internalType: "bytes", name: "data", type: "bytes" }, + { + indexed: false, + internalType: "enum Enum.Operation", + name: "operation", + type: "uint8" + }, + { + indexed: false, + internalType: "uint256", + name: "txGas", + type: "uint256" + } + ], + name: "ExecutionFailure", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "module", + type: "address" + } + ], + name: "ExecutionFromModuleFailure", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "module", + type: "address" + } + ], + name: "ExecutionFromModuleSuccess", + type: "event" + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: "address", name: "to", type: "address" }, + { + indexed: true, + internalType: "uint256", + name: "value", + type: "uint256" + }, + { indexed: true, internalType: "bytes", name: "data", type: "bytes" }, + { + indexed: false, + internalType: "enum Enum.Operation", + name: "operation", + type: "uint8" + }, + { + indexed: false, + internalType: "uint256", + name: "txGas", + type: "uint256" + } + ], + name: "ExecutionSuccess", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "oldImplementation", + type: "address" + }, + { + indexed: true, + internalType: "address", + name: "newImplementation", + type: "address" + } + ], + name: "ImplementationUpdated", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "module", + type: "address" + }, + { indexed: false, internalType: "address", name: "to", type: "address" }, + { + indexed: false, + internalType: "uint256", + name: "value", + type: "uint256" + }, + { indexed: false, internalType: "bytes", name: "data", type: "bytes" }, + { + indexed: false, + internalType: "enum Enum.Operation", + name: "operation", + type: "uint8" + } + ], + name: "ModuleTransaction", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "sender", + type: "address" + }, + { indexed: true, internalType: "uint256", name: "value", type: "uint256" } + ], + name: "SmartAccountReceivedNativeToken", + type: "event" + }, + { stateMutability: "nonpayable", type: "fallback" }, + { + inputs: [], + name: "VERSION", + outputs: [{ internalType: "string", name: "", type: "string" }], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "addDeposit", + outputs: [], + stateMutability: "payable", + type: "function" + }, + { + inputs: [ + { internalType: "address", name: "prevModule", type: "address" }, + { internalType: "address", name: "module", type: "address" } + ], + name: "disableModule", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [{ internalType: "address", name: "module", type: "address" }], + name: "enableModule", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [], + name: "entryPoint", + outputs: [ + { internalType: "contract IEntryPoint", name: "", type: "address" } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { internalType: "address[]", name: "to", type: "address[]" }, + { internalType: "uint256[]", name: "value", type: "uint256[]" }, + { internalType: "bytes[]", name: "data", type: "bytes[]" }, + { + internalType: "enum Enum.Operation[]", + name: "operations", + type: "uint8[]" + } + ], + name: "execBatchTransactionFromModule", + outputs: [{ internalType: "bool", name: "success", type: "bool" }], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { internalType: "address", name: "to", type: "address" }, + { internalType: "uint256", name: "value", type: "uint256" }, + { internalType: "bytes", name: "data", type: "bytes" }, + { internalType: "enum Enum.Operation", name: "operation", type: "uint8" }, + { internalType: "uint256", name: "txGas", type: "uint256" } + ], + name: "execTransactionFromModule", + outputs: [{ internalType: "bool", name: "success", type: "bool" }], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { internalType: "address", name: "to", type: "address" }, + { internalType: "uint256", name: "value", type: "uint256" }, + { internalType: "bytes", name: "data", type: "bytes" }, + { internalType: "enum Enum.Operation", name: "operation", type: "uint8" } + ], + name: "execTransactionFromModule", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { internalType: "address", name: "to", type: "address" }, + { internalType: "uint256", name: "value", type: "uint256" }, + { internalType: "bytes", name: "data", type: "bytes" }, + { internalType: "enum Enum.Operation", name: "operation", type: "uint8" } + ], + name: "execTransactionFromModuleReturnData", + outputs: [ + { internalType: "bool", name: "success", type: "bool" }, + { internalType: "bytes", name: "returnData", type: "bytes" } + ], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { internalType: "address", name: "dest", type: "address" }, + { internalType: "uint256", name: "value", type: "uint256" }, + { internalType: "bytes", name: "func", type: "bytes" } + ], + name: "execute", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { internalType: "address[]", name: "dest", type: "address[]" }, + { internalType: "uint256[]", name: "value", type: "uint256[]" }, + { internalType: "bytes[]", name: "func", type: "bytes[]" } + ], + name: "executeBatch", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { internalType: "address[]", name: "dest", type: "address[]" }, + { internalType: "uint256[]", name: "value", type: "uint256[]" }, + { internalType: "bytes[]", name: "func", type: "bytes[]" } + ], + name: "executeBatch_y6U", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { internalType: "address", name: "dest", type: "address" }, + { internalType: "uint256", name: "value", type: "uint256" }, + { internalType: "bytes", name: "func", type: "bytes" } + ], + name: "execute_ncC", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [], + name: "getDeposit", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "getFallbackHandler", + outputs: [{ internalType: "address", name: "_handler", type: "address" }], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "getImplementation", + outputs: [ + { internalType: "address", name: "_implementation", type: "address" } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { internalType: "address", name: "start", type: "address" }, + { internalType: "uint256", name: "pageSize", type: "uint256" } + ], + name: "getModulesPaginated", + outputs: [ + { internalType: "address[]", name: "array", type: "address[]" }, + { internalType: "address", name: "next", type: "address" } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { internalType: "address", name: "handler", type: "address" }, + { internalType: "address", name: "moduleSetupContract", type: "address" }, + { internalType: "bytes", name: "moduleSetupData", type: "bytes" } + ], + name: "init", + outputs: [{ internalType: "address", name: "", type: "address" }], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [{ internalType: "address", name: "module", type: "address" }], + name: "isModuleEnabled", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { internalType: "bytes32", name: "dataHash", type: "bytes32" }, + { internalType: "bytes", name: "signature", type: "bytes" } + ], + name: "isValidSignature", + outputs: [{ internalType: "bytes4", name: "", type: "bytes4" }], + stateMutability: "view", + type: "function" + }, + { + inputs: [{ internalType: "uint192", name: "_key", type: "uint192" }], + name: "nonce", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function" + }, + { + inputs: [{ internalType: "uint256", name: "", type: "uint256" }], + name: "noncesDeprecated", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "ownerDeprecated", + outputs: [{ internalType: "address", name: "", type: "address" }], + stateMutability: "view", + type: "function" + }, + { + inputs: [{ internalType: "address", name: "handler", type: "address" }], + name: "setFallbackHandler", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { internalType: "address", name: "setupContract", type: "address" }, + { internalType: "bytes", name: "setupData", type: "bytes" } + ], + name: "setupAndEnableModule", + outputs: [{ internalType: "address", name: "", type: "address" }], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [{ internalType: "bytes4", name: "_interfaceId", type: "bytes4" }], + name: "supportsInterface", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { internalType: "address", name: "_implementation", type: "address" } + ], + name: "updateImplementation", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + components: [ + { internalType: "address", name: "sender", type: "address" }, + { internalType: "uint256", name: "nonce", type: "uint256" }, + { internalType: "bytes", name: "initCode", type: "bytes" }, + { internalType: "bytes", name: "callData", type: "bytes" }, + { internalType: "uint256", name: "callGasLimit", type: "uint256" }, + { + internalType: "uint256", + name: "verificationGasLimit", + type: "uint256" + }, + { + internalType: "uint256", + name: "preVerificationGas", + type: "uint256" + }, + { internalType: "uint256", name: "maxFeePerGas", type: "uint256" }, + { + internalType: "uint256", + name: "maxPriorityFeePerGas", + type: "uint256" + }, + { internalType: "bytes", name: "paymasterAndData", type: "bytes" }, + { internalType: "bytes", name: "signature", type: "bytes" } + ], + internalType: "struct UserOperation", + name: "userOp", + type: "tuple" + }, + { internalType: "bytes32", name: "userOpHash", type: "bytes32" }, + { internalType: "uint256", name: "missingAccountFunds", type: "uint256" } + ], + name: "validateUserOp", + outputs: [ + { internalType: "uint256", name: "validationData", type: "uint256" } + ], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "address payable", + name: "withdrawAddress", + type: "address" + }, + { internalType: "uint256", name: "amount", type: "uint256" } + ], + name: "withdrawDepositTo", + outputs: [], + stateMutability: "payable", + type: "function" + }, + { stateMutability: "payable", type: "receive" } +] as const diff --git a/src/account/index.ts b/src/account/index.ts new file mode 100644 index 000000000..50364553f --- /dev/null +++ b/src/account/index.ts @@ -0,0 +1,11 @@ +import { BiconomySmartAccountV2 } from "./BiconomySmartAccountV2.js" +import type { BiconomySmartAccountV2Config } from "./utils/Types.js" + +export * from "./utils/index.js" +export * from "./signers/local-account.js" +export * from "./signers/wallet-client.js" +export * from "./BiconomySmartAccountV2.js" + +export const createSmartAccountClient = BiconomySmartAccountV2.create + +export type SmartWalletConfig = BiconomySmartAccountV2Config diff --git a/src/account/signers/local-account.ts b/src/account/signers/local-account.ts new file mode 100644 index 000000000..65bf3c521 --- /dev/null +++ b/src/account/signers/local-account.ts @@ -0,0 +1,55 @@ +import type { + HDAccount, + Hex, + LocalAccount, + PrivateKeyAccount, + SignableMessage, + TypedData, + TypedDataDefinition +} from "viem" +import { mnemonicToAccount, privateKeyToAccount } from "viem/accounts" +import type { SmartAccountSigner } from "../utils/Types.js" + +export class LocalAccountSigner< + T extends HDAccount | PrivateKeyAccount | LocalAccount +> implements SmartAccountSigner<T> +{ + inner: T + signerType: string + + constructor(inner: T) { + this.inner = inner + this.signerType = inner.type // type: "local" + } + + readonly signMessage: (message: SignableMessage) => Promise<`0x${string}`> = ( + message + ) => { + return this.inner.signMessage({ message }) + } + + readonly signTypedData = async < + const TTypedData extends TypedData | { [key: string]: unknown }, + TPrimaryType extends string = string + >( + params: TypedDataDefinition<TTypedData, TPrimaryType> + ): Promise<Hex> => { + return this.inner.signTypedData(params) + } + + readonly getAddress: () => Promise<`0x${string}`> = async () => { + return this.inner.address + } + + static mnemonicToAccountSigner(key: string): LocalAccountSigner<HDAccount> { + const signer = mnemonicToAccount(key) + return new LocalAccountSigner(signer) + } + + static privateKeyToAccountSigner( + key: Hex + ): LocalAccountSigner<PrivateKeyAccount> { + const signer = privateKeyToAccount(key) + return new LocalAccountSigner(signer) + } +} diff --git a/src/account/signers/wallet-client.ts b/src/account/signers/wallet-client.ts new file mode 100644 index 000000000..69c10fe5a --- /dev/null +++ b/src/account/signers/wallet-client.ts @@ -0,0 +1,48 @@ +import { + type Hex, + type SignableMessage, + type TypedData, + type TypedDataDefinition, + type WalletClient, + getAddress +} from "viem" +import type { SmartAccountSigner } from "../utils/Types.js" + +export class WalletClientSigner implements SmartAccountSigner<WalletClient> { + signerType: string + inner: WalletClient + + constructor(client: WalletClient, signerType: string) { + this.inner = client + if (!signerType) { + throw new Error(`InvalidSignerTypeError: ${signerType}`) + } + this.signerType = signerType + } + + getAddress: () => Promise<`0x${string}`> = async () => { + const addresses = await this.inner.getAddresses() + return getAddress(addresses[0]) + } + + readonly signMessage: (message: SignableMessage) => Promise<`0x${string}`> = + async (message) => { + const account = this.inner.account ?? (await this.getAddress()) + + return this.inner.signMessage({ message, account }) + } + + signTypedData = async < + const TTypedData extends TypedData | { [key: string]: unknown }, + TPrimaryType extends string = string + >( + typedData: TypedDataDefinition<TTypedData, TPrimaryType> + ): Promise<Hex> => { + const account = this.inner.account ?? (await this.getAddress()) + + return this.inner.signTypedData({ + account, + ...typedData + }) + } +} diff --git a/packages/account/src/utils/Constants.ts b/src/account/utils/Constants.ts similarity index 56% rename from packages/account/src/utils/Constants.ts rename to src/account/utils/Constants.ts index 7954d0374..320a89ac0 100644 --- a/packages/account/src/utils/Constants.ts +++ b/src/account/utils/Constants.ts @@ -1,77 +1,96 @@ -import { - EntryPointAddresses, +import type { Hex } from "viem" +import type { BiconomyFactories, - BiconomyImplementations, - EntryPointAddressesByVersion, BiconomyFactoriesByVersion, + BiconomyImplementations, BiconomyImplementationsByVersion, -} from "./Types.js"; + EntryPointAddresses, + EntryPointAddressesByVersion +} from "./Types.js" + +export const ADDRESS_ZERO = "0x0000000000000000000000000000000000000000" -export const ADDRESS_ZERO = "0x0000000000000000000000000000000000000000"; +export const MAGIC_BYTES = + "0x6492649264926492649264926492649264926492649264926492649264926492" // will always be latest entrypoint address -export const DEFAULT_ENTRYPOINT_ADDRESS = "0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789"; +export const DEFAULT_ENTRYPOINT_ADDRESS = + "0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789" export const ENTRYPOINT_ADDRESSES: EntryPointAddresses = { "0x27a4db290b89ae3373ce4313cbeae72112ae7da9": "V0_0_5", - "0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789": "V0_0_6", -}; + "0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789": "V0_0_6" +} // will always be latest factory address -export const DEFAULT_BICONOMY_FACTORY_ADDRESS = "0x000000a56Aaca3e9a4C479ea6b6CD0DbcB6634F5"; -export const DEFAULT_FALLBACK_HANDLER_ADDRESS = "0x0bBa6d96BD616BedC6BFaa341742FD43c60b83C1"; +export const DEFAULT_BICONOMY_FACTORY_ADDRESS = + "0x000000a56Aaca3e9a4C479ea6b6CD0DbcB6634F5" +export const DEFAULT_FALLBACK_HANDLER_ADDRESS = + "0x0bBa6d96BD616BedC6BFaa341742FD43c60b83C1" export const BICONOMY_FACTORY_ADDRESSES: BiconomyFactories = { "0x000000f9ee1842bb72f6bbdd75e6d3d4e3e9594c": "V1_0_0", - "0x000000a56Aaca3e9a4C479ea6b6CD0DbcB6634F5": "V2_0_0", -}; + "0x000000a56Aaca3e9a4C479ea6b6CD0DbcB6634F5": "V2_0_0" +} // will always be latest implementation address -export const DEFAULT_BICONOMY_IMPLEMENTATION_ADDRESS = "0x0000002512019Dafb59528B82CB92D3c5D2423aC"; +export const DEFAULT_BICONOMY_IMPLEMENTATION_ADDRESS = + "0x0000002512019Dafb59528B82CB92D3c5D2423aC" export const BICONOMY_IMPLEMENTATION_ADDRESSES: BiconomyImplementations = { "0x00006b7e42e01957da540dc6a8f7c30c4d816af5": "V1_0_0", - "0x0000002512019Dafb59528B82CB92D3c5D2423aC": "V2_0_0", -}; + "0x0000002512019Dafb59528B82CB92D3c5D2423aC": "V2_0_0" +} export const ENTRYPOINT_ADDRESSES_BY_VERSION: EntryPointAddressesByVersion = { V0_0_5: "0x27a4db290b89ae3373ce4313cbeae72112ae7da9", - V0_0_6: "0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789", -}; + V0_0_6: "0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789" +} -export const BICONOMY_FACTORY_ADDRESSES_BY_VERSION: BiconomyFactoriesByVersion = Object.fromEntries( - Object.entries(BICONOMY_FACTORY_ADDRESSES).map(([k, v]) => [v, k]), -); +export const BICONOMY_FACTORY_ADDRESSES_BY_VERSION: BiconomyFactoriesByVersion = + Object.fromEntries( + Object.entries(BICONOMY_FACTORY_ADDRESSES).map(([k, v]) => [v, k]) + ) -export const BICONOMY_IMPLEMENTATION_ADDRESSES_BY_VERSION: BiconomyImplementationsByVersion = Object.fromEntries( - Object.entries(BICONOMY_IMPLEMENTATION_ADDRESSES).map(([k, v]) => [v, k]), -); +export const BICONOMY_IMPLEMENTATION_ADDRESSES_BY_VERSION: BiconomyImplementationsByVersion = + Object.fromEntries( + Object.entries(BICONOMY_IMPLEMENTATION_ADDRESSES).map(([k, v]) => [v, k]) + ) -export const EIP1559_UNSUPPORTED_NETWORKS: Array<number> = [97, 56, 1442, 1101]; +export const EIP1559_UNSUPPORTED_NETWORKS: Array<number> = [97, 56, 1442, 1101] export const PROXY_CREATION_CODE = - "0x6080346100aa57601f61012038819003918201601f19168301916001600160401b038311848410176100af578084926020946040528339810103126100aa57516001600160a01b0381168082036100aa5715610065573055604051605a90816100c68239f35b60405162461bcd60e51b815260206004820152601e60248201527f496e76616c696420696d706c656d656e746174696f6e206164647265737300006044820152606490fd5b600080fd5b634e487b7160e01b600052604160045260246000fdfe608060405230546000808092368280378136915af43d82803e156020573d90f35b3d90fdfea2646970667358221220a03b18dce0be0b4c9afe58a9eb85c35205e2cf087da098bbf1d23945bf89496064736f6c63430008110033"; + "0x6080346100aa57601f61012038819003918201601f19168301916001600160401b038311848410176100af578084926020946040528339810103126100aa57516001600160a01b0381168082036100aa5715610065573055604051605a90816100c68239f35b60405162461bcd60e51b815260206004820152601e60248201527f496e76616c696420696d706c656d656e746174696f6e206164647265737300006044820152606490fd5b600080fd5b634e487b7160e01b600052604160045260246000fdfe608060405230546000808092368280378136915af43d82803e156020573d90f35b3d90fdfea2646970667358221220a03b18dce0be0b4c9afe58a9eb85c35205e2cf087da098bbf1d23945bf89496064736f6c63430008110033" -export const ADDRESS_RESOLVER_ADDRESS = "0x00000E81673606e07fC79CE5F1b3B26957844468"; +export const ADDRESS_RESOLVER_ADDRESS = + "0x00000E81673606e07fC79CE5F1b3B26957844468" export const DefaultGasLimit = { callGasLimit: 800000, verificationGasLimit: 1000000, - preVerificationGas: 100000, -}; + preVerificationGas: 100000 +} export const ERROR_MESSAGES = { ACCOUNT_ALREADY_DEPLOYED: "Account already deployed", - NO_NATIVE_TOKEN_BALANCE_DURING_DEPLOY: "Native token balance is not available during deploy", + NO_NATIVE_TOKEN_BALANCE_DURING_DEPLOY: + "Native token balance is not available during deploy", SPENDER_REQUIRED: "spender is required for ERC20 mode", - NO_FEE_QUOTE: "FeeQuote was not provided, please call smartAccount.getTokenFees() to get feeQuote", + NO_FEE_QUOTE: + "FeeQuote was not provided, please call smartAccount.getTokenFees() to get feeQuote", FAILED_FEE_QUOTE_FETCH: "Failed to fetch fee quote", CHAIN_NOT_FOUND: "Chain not found", -}; + NO_RECIPIENT: "Recipient is required", + NATIVE_TOKEN_WITHDRAWAL_WITHOUT_AMOUNT: + "'Amount' is required for withdrawal of native token without using a paymaster", + MISSING_RPC_URL: + "rpcUrl is required for PrivateKeyAccount signer type, please provide it in the config" +} -export const NATIVE_TOKEN_ALIAS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +export const NATIVE_TOKEN_ALIAS: Hex = + "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE" export const ERC20_ABI = [ "function transfer(address to, uint256 value) external returns (bool)", "function transferFrom(address from, address to, uint256 value) external returns (bool)", "function approve(address spender, uint256 value) external returns (bool)", "function allowance(address owner, address spender) external view returns (uint256)", "function balanceOf(address owner) external view returns (uint256)", - "function decimals() external view returns (uint8)", -]; + "function decimals() external view returns (uint8)" +] diff --git a/src/account/utils/EthersSigner.ts b/src/account/utils/EthersSigner.ts new file mode 100644 index 000000000..8af82cb10 --- /dev/null +++ b/src/account/utils/EthersSigner.ts @@ -0,0 +1,42 @@ +import type { Hex, SignableMessage } from "viem" +import type { LightSigner, SmartAccountSigner } from "../utils/Types.js" + +export class EthersSigner<T extends LightSigner> + implements SmartAccountSigner<T> +{ + signerType = "ethers" + + inner: T + + constructor(inner: T, signerType: string) { + this.inner = inner + this.signerType = signerType + } + + async getAddress() { + return (await this.inner.getAddress()) as Hex + } + + async signMessage(_message: SignableMessage): Promise<Hex> { + const message = typeof _message === "string" ? _message : _message.raw + const signature = await this.inner?.signMessage(message) + return this.#correctSignature(signature as Hex) + } + + // biome-ignore lint/suspicious/noExplicitAny: <explanation> + async signTypedData(_: any): Promise<Hex> { + throw new Error("signTypedData is not supported for Ethers Signer") + } + + #correctSignature = (_signature: Hex): Hex => { + let signature = _signature + const potentiallyIncorrectV = Number.parseInt(signature.slice(-2), 16) + if (![27, 28].includes(potentiallyIncorrectV)) { + const correctV = potentiallyIncorrectV + 27 + signature = signature.slice(0, -2) + correctV.toString(16) + } + return signature as Hex + } +} + +export default EthersSigner diff --git a/src/account/utils/HttpRequests.ts b/src/account/utils/HttpRequests.ts new file mode 100644 index 000000000..cdcbe07f4 --- /dev/null +++ b/src/account/utils/HttpRequests.ts @@ -0,0 +1,76 @@ +import { getAAError } from "../../bundler/utils/getAAError.js" +import { Logger } from "./Logger.js" +import type { Service } from "./Types.js" + +export enum HttpMethod { + Get = "get", + Post = "post", + Delete = "delete" +} + +export interface HttpRequest { + url: string + method: HttpMethod + // biome-ignore lint/suspicious/noExplicitAny: <explanation> + body?: Record<string, any> +} + +export async function sendRequest<T>( + { url, method, body }: HttpRequest, + service: Service +): Promise<T> { + const response = await fetch(url, { + method, + headers: { + Accept: "application/json", + "Content-Type": "application/json" + }, + body: JSON.stringify(body) + }) + + // biome-ignore lint/suspicious/noExplicitAny: <explanation> + let jsonResponse: any + try { + jsonResponse = await response.json() + Logger.log(`${service} RPC Response`, jsonResponse) + } catch (error) { + if (!response.ok) { + throw await getAAError(response.statusText, response.status, service) + } + } + + if (response.ok) { + return jsonResponse as T + } + if (jsonResponse.error) { + throw await getAAError( + `Error coming from ${service}: ${jsonResponse.error.message}` + ) + } + if (jsonResponse.message) { + throw await getAAError(jsonResponse.message, response.status, service) + } + if (jsonResponse.msg) { + throw await getAAError(jsonResponse.msg, response.status, service) + } + if (jsonResponse.data) { + throw await getAAError(jsonResponse.data, response.status, service) + } + if (jsonResponse.detail) { + throw await getAAError(jsonResponse.detail, response.status, service) + } + if (jsonResponse.message) { + throw await getAAError(jsonResponse.message, response.status, service) + } + if (jsonResponse.nonFieldErrors) { + throw await getAAError( + jsonResponse.nonFieldErrors, + response.status, + service + ) + } + if (jsonResponse.delegate) { + throw await getAAError(jsonResponse.delegate, response.status, service) + } + throw await getAAError(response.statusText, response.status, service) +} diff --git a/packages/common/src/utils/Logger.ts b/src/account/utils/Logger.ts similarity index 55% rename from packages/common/src/utils/Logger.ts rename to src/account/utils/Logger.ts index 0bdcae373..c096cc270 100644 --- a/packages/common/src/utils/Logger.ts +++ b/src/account/utils/Logger.ts @@ -4,9 +4,15 @@ * * @param {any} message Message to be logged */ + +// biome-ignore lint/complexity/noStaticOnlyClass: <explanation> class Logger { // By default, the logger is not in debug mode. - static isDebug: boolean = process.env.BICONOMY_SDK_DEBUG === "true" ? true : process.env.REACT_APP_BICONOMY_SDK_DEBUG === "true" ? true : false; + static isDebug: boolean = [ + "BICONOMY_SDK_DEBUG", + "REACT_APP_BICONOMY_SDK_DEBUG", + "NEXT_PUBLIC_BICONOMY_SDK_DEBUG" + ].some((key) => process.env[key]?.toString() === "true") /** * \x1b[0m is an escape sequence to reset the color of the text @@ -15,35 +21,32 @@ class Logger { * warn - Magenta[time] Yellow[WARN]: Cyan[message]: [value] * error - Magenta[time] Red[ERROR]: Cyan[message]: [value] */ - /* eslint-disable @typescript-eslint/no-explicit-any */ - static log(message: string, value?: any): void { - const timestamp = new Date().toISOString(); - const logMessage = `\x1b[35m[${timestamp}]\x1b[0m \x1b[36m${message}\x1b[0m:`; + static log(message: string, value = ""): void { + const timestamp = new Date().toISOString() + const logMessage = `\x1b[35m[${timestamp}]\x1b[0m \x1b[36m${message}\x1b[0m:` if (Logger.isDebug) { - console.log(logMessage, value === undefined ? "" : value); + console.log(logMessage, value === undefined ? "" : value) } } - /* eslint-disable @typescript-eslint/no-explicit-any */ - static warn(message: string, value?: any): void { - const timestamp = new Date().toISOString(); - const warnMessage = `\x1b[35m[${timestamp}]\x1b[0m \x1b[33mWARN\x1b[0m: \x1b[36m${message}\x1b[0m`; + static warn(message: string, value = ""): void { + const timestamp = new Date().toISOString() + const warnMessage = `\x1b[35m[${timestamp}]\x1b[0m \x1b[33mWARN\x1b[0m: \x1b[36m${message}\x1b[0m` if (Logger.isDebug) { - console.warn(warnMessage, value === undefined ? "" : value); + console.warn(warnMessage, value === undefined ? "" : value) } } - /* eslint-disable @typescript-eslint/no-explicit-any */ - static error(message: string, value?: any): void { - const timestamp = new Date().toISOString(); - const errorMessage = `\x1b[35m[${timestamp}]\x1b[0m \x1b[31mERROR\x1b[0m: \x1b[36m${message}\x1b[0m`; + static error(message: string, value = ""): void { + const timestamp = new Date().toISOString() + const errorMessage = `\x1b[35m[${timestamp}]\x1b[0m \x1b[31mERROR\x1b[0m: \x1b[36m${message}\x1b[0m` if (Logger.isDebug) { - console.error(errorMessage, value === undefined ? "" : value); + console.error(errorMessage, value === undefined ? "" : value) } } } -export { Logger }; +export { Logger } diff --git a/src/account/utils/Types.ts b/src/account/utils/Types.ts new file mode 100644 index 000000000..1fb265ac3 --- /dev/null +++ b/src/account/utils/Types.ts @@ -0,0 +1,602 @@ +import type { + Address, + Chain, + Hash, + Hex, + PrivateKeyAccount, + PublicClient, + SignTypedDataParameters, + SignableMessage, + TypedData, + TypedDataDefinition, + WalletClient +} from "viem" +import type { IBundler } from "../../bundler" +import type { BaseValidationModule, ModuleInfo } from "../../modules" +import type { + FeeQuotesOrDataDto, + IPaymaster, + PaymasterFeeQuote, + PaymasterMode, + SmartAccountData, + SponsorUserOperationDto +} from "../../paymaster" + +export type EntryPointAddresses = Record<string, string> +export type BiconomyFactories = Record<string, string> +export type BiconomyImplementations = Record<string, string> +export type EntryPointAddressesByVersion = Record<string, string> +export type BiconomyFactoriesByVersion = Record<string, string> +export type BiconomyImplementationsByVersion = Record<string, string> + +export type SmartAccountConfig = { + /** entryPointAddress: address of the entry point */ + entryPointAddress: string + /** factoryAddress: address of the smart account factory */ + bundler?: IBundler +} + +export interface BalancePayload { + /** address: The address of the account */ + address: string + /** chainId: The chainId of the network */ + chainId: number + /** amount: The amount of the balance */ + amount: bigint + /** decimals: The number of decimals */ + decimals: number + /** formattedAmount: The amount of the balance formatted */ + formattedAmount: string +} + +export interface WithdrawalRequest { + /** The address of the asset */ + address: Hex + /** The amount to withdraw. Expects unformatted amount. Will use max amount if unset */ + amount?: bigint + /** The destination address of the funds. The second argument from the `withdraw(...)` function will be used as the default if left unset. */ + recipient?: Hex +} + +export interface GasOverheads { + /** fixed: fixed gas overhead */ + fixed: number + /** perUserOp: per user operation gas overhead */ + perUserOp: number + /** perUserOpWord: per user operation word gas overhead */ + perUserOpWord: number + /** zeroByte: per byte gas overhead */ + zeroByte: number + /** nonZeroByte: per non zero byte gas overhead */ + nonZeroByte: number + /** bundleSize: per signature bundleSize */ + bundleSize: number + /** sigSize: sigSize gas overhead */ + sigSize: number +} + +export type BaseSmartAccountConfig = { + /** index: helps to not conflict with other smart account instances */ + index?: number + /** provider: WalletClientSigner from viem */ + provider?: WalletClient + /** entryPointAddress: address of the smart account entry point */ + entryPointAddress?: string + /** accountAddress: address of the smart account, potentially counterfactual */ + accountAddress?: string + /** overheads: {@link GasOverheads} */ + overheads?: Partial<GasOverheads> + /** paymaster: {@link IPaymaster} interface */ + paymaster?: IPaymaster + /** chainId: chainId of the network */ + chainId?: number +} + +export type BiconomyTokenPaymasterRequest = { + /** feeQuote: {@link PaymasterFeeQuote} */ + feeQuote: PaymasterFeeQuote + /** spender: The address of the spender who is paying for the transaction, this can usually be set to feeQuotesResponse.tokenPaymasterAddress */ + spender: Hex + /** maxApproval: If set to true, the paymaster will approve the maximum amount of tokens required for the transaction. Not recommended */ + maxApproval?: boolean + /* skip option to patch callData if approval is already given to the paymaster */ + skipPatchCallData?: boolean +} + +export type RequireAtLeastOne<T, Keys extends keyof T = keyof T> = Pick< + T, + Exclude<keyof T, Keys> +> & + { + [K in Keys]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<Keys, K>>> + }[Keys] + +export type ConditionalBundlerProps = RequireAtLeastOne< + { + bundler: IBundler + bundlerUrl: string + }, + "bundler" | "bundlerUrl" +> +export type ResolvedBundlerProps = { + bundler: IBundler +} +export type ConditionalValidationProps = RequireAtLeastOne< + { + defaultValidationModule: BaseValidationModule + signer: SupportedSigner + }, + "defaultValidationModule" | "signer" +> + +export type ResolvedValidationProps = { + /** defaultValidationModule: {@link BaseValidationModule} */ + defaultValidationModule: BaseValidationModule + /** activeValidationModule: {@link BaseValidationModule}. The active validation module. Will default to the defaultValidationModule */ + activeValidationModule: BaseValidationModule + /** signer: ethers Wallet, viemWallet or alchemys SmartAccountSigner */ + signer: SmartAccountSigner + /** chainId: chainId of the network */ + chainId: number +} + +export type BiconomySmartAccountV2ConfigBaseProps = { + /** Factory address of biconomy factory contract or some other contract you have deployed on chain */ + factoryAddress?: Hex + /** Sender address: If you want to override the Signer address with some other address and get counterfactual address can use this to pass the EOA and get SA address */ + senderAddress?: Hex + /** implementation of smart contract address or some other contract you have deployed and want to override */ + implementationAddress?: Hex + /** defaultFallbackHandler: override the default fallback contract address */ + defaultFallbackHandler?: Hex + /** rpcUrl: Rpc url, optional, we set default rpc url if not passed. */ + rpcUrl?: string // as good as Provider + /** paymasterUrl: The Paymaster URL retrieved from the Biconomy dashboard */ + paymasterUrl?: string + /** biconomyPaymasterApiKey: The API key retrieved from the Biconomy dashboard */ + biconomyPaymasterApiKey?: string + /** activeValidationModule: The active validation module. Will default to the defaultValidationModule */ + activeValidationModule?: BaseValidationModule + /** scanForUpgradedAccountsFromV1: set to true if you you want the userwho was using biconomy SA v1 to upgrade to biconomy SA v2 */ + scanForUpgradedAccountsFromV1?: boolean + /** the index of SA the EOA have generated and till which indexes the upgraded SA should scan */ + maxIndexForScan?: number + /** Can be used to optionally override the chain with a custom chain if it doesn't already exist in viems list of supported chains */ + viemChain?: Chain + /** The initial code to be used for the smart account */ + initCode?: Hex +} +export type BiconomySmartAccountV2Config = + BiconomySmartAccountV2ConfigBaseProps & + BaseSmartAccountConfig & + ConditionalBundlerProps & + ConditionalValidationProps + +export type BiconomySmartAccountV2ConfigConstructorProps = + BiconomySmartAccountV2ConfigBaseProps & + BaseSmartAccountConfig & + ResolvedBundlerProps & + ResolvedValidationProps + +export type BuildUserOpOptions = { + /** overrides: Explicitly set gas values */ + // overrides?: Overrides; + /** Not currently in use */ + // skipBundlerGasEstimation?: boolean; + /** params relevant to the module, mostly relevant to sessions */ + params?: ModuleInfo + /** nonceOptions: For overriding the nonce */ + nonceOptions?: NonceOptions + /** forceEncodeForBatch: For encoding the user operation for batch */ + forceEncodeForBatch?: boolean + /** paymasterServiceData: Options specific to transactions that involve a paymaster */ + paymasterServiceData?: PaymasterUserOperationDto + /** simulationType: Determine which parts of the tx a bundler will simulate: "validation" | "validation_and_execution". */ + simulationType?: SimulationType + /** dummy pnd override */ + dummyPndOverride?: BytesLike + /** stateOverrideSet: For overriding the state */ + stateOverrideSet?: StateOverrideSet + /** set to true if the tx is being used *only* to deploy the smartContract, so "0x" is set as the userOp.callData */ + useEmptyDeployCallData?: boolean +} + +export type NonceOptions = { + /** nonceKey: The key to use for nonce */ + nonceKey?: number + /** nonceOverride: The nonce to use for the transaction */ + nonceOverride?: number +} + +export type SimulationType = "validation" | "validation_and_execution" + +export type Overrides = { + /* Value used by inner account execution */ + callGasLimit?: Hex + /* Actual gas used by the validation of this UserOperation */ + verificationGasLimit?: Hex + /* Gas overhead of this UserOperation */ + preVerificationGas?: Hex + /* Maximum fee per gas (similar to EIP-1559 max_fee_per_gas) */ + maxFeePerGas?: Hex + /* Maximum priority fee per gas (similar to EIP-1559 max_priority_fee_per_gas) */ + maxPriorityFeePerGas?: Hex + /* Address of paymaster sponsoring the transaction, followed by extra data to send to the paymaster ("0x" for self-sponsored transaction) */ + paymasterData?: Hex + /* Data passed into the account along with the nonce during the verification step */ + signature?: Hex +} + +export type InitilizationData = { + accountIndex?: number + signerAddress?: string +} + +export type PaymasterUserOperationDto = SponsorUserOperationDto & + FeeQuotesOrDataDto & { + /** mode: sponsored or erc20 */ + mode: PaymasterMode + /** Always recommended, especially when using token paymaster */ + calculateGasLimits?: boolean + /** Expiry duration in seconds */ + expiryDuration?: number + /** Webhooks to be fired after user op is sent */ + // biome-ignore lint/suspicious/noExplicitAny: <explanation> + webhookData?: Record<string, any> + /** Smart account meta data */ + smartAccountInfo?: SmartAccountData + /** the fee-paying token address */ + feeTokenAddress?: string + /** The fee quote */ + feeQuote?: PaymasterFeeQuote + /** The address of the spender. This is usually set to FeeQuotesOrDataResponse.tokenPaymasterAddress */ + spender?: Hex + /** Not recommended */ + maxApproval?: boolean + /* skip option to patch callData if approval is already given to the paymaster */ + skipPatchCallData?: boolean + } + +export type InitializeV2Data = { + accountIndex?: number +} + +export type EstimateUserOpGasParams = { + userOp: Partial<UserOperationStruct> + // overrides?: Overrides; + /** Currrently has no effect */ + // skipBundlerGasEstimation?: boolean; + /** paymasterServiceData: Options specific to transactions that involve a paymaster */ + paymasterServiceData?: SponsorUserOperationDto +} + +export interface TransactionDetailsForUserOp { + /** target: The address of the contract to call */ + target: string + /** data: The data to send to the contract */ + data: string + /** value: The value to send to the contract */ + value?: BigNumberish + /** gasLimit: The gas limit to use for the transaction */ + gasLimit?: BigNumberish + /** maxFeePerGas: The maximum fee per gas to use for the transaction */ + maxFeePerGas?: BigNumberish + /** maxPriorityFeePerGas: The maximum priority fee per gas to use for the transaction */ + maxPriorityFeePerGas?: BigNumberish + /** nonce: The nonce to use for the transaction */ + nonce?: BigNumberish +} + +export type CounterFactualAddressParam = { + index?: number + validationModule?: BaseValidationModule + /** scanForUpgradedAccountsFromV1: set to true if you you want the userwho was using biconomy SA v1 to upgrade to biconomy SA v2 */ + scanForUpgradedAccountsFromV1?: boolean + /** the index of SA the EOA have generated and till which indexes the upgraded SA should scan */ + maxIndexForScan?: number +} + +export type QueryParamsForAddressResolver = { + eoaAddress: Hex + index: number + moduleAddress: Hex + moduleSetupData: Hex + maxIndexForScan?: number +} + +export type SmartAccountInfo = { + /** accountAddress: The address of the smart account */ + accountAddress: Hex + /** factoryAddress: The address of the smart account factory */ + factoryAddress: Hex + /** currentImplementation: The address of the current implementation */ + currentImplementation: string + /** currentVersion: The version of the smart account */ + currentVersion: string + /** factoryVersion: The version of the factory */ + factoryVersion: string + /** deploymentIndex: The index of the deployment */ + deploymentIndex: BigNumberish +} + +export type ValueOrData = RequireAtLeastOne< + { + value: BigNumberish | string + data: string + }, + "value" | "data" +> +export type Transaction = { + to: string +} & ValueOrData + +export type SupportedToken = Omit< + PaymasterFeeQuote, + "maxGasFeeUSD" | "usdPayment" | "maxGasFee" | "validUntil" +> & { balance: BalancePayload } + +export type Signer = LightSigner & { + // biome-ignore lint/suspicious/noExplicitAny: any is used here to allow for the ethers provider + provider: any +} +export type SupportedSignerName = "alchemy" | "ethers" | "viem" +export type SupportedSigner = + | SmartAccountSigner + | WalletClient + | Signer + | LightSigner + | PrivateKeyAccount +export type Service = "Bundler" | "Paymaster" + +export interface LightSigner { + getAddress(): Promise<string> + signMessage(message: string | Uint8Array): Promise<string> +} + +export type StateOverrideSet = { + [key: string]: { + balance?: string + nonce?: string + code?: string + state?: object + stateDiff?: object + } +} + +export type BigNumberish = Hex | number | bigint +export type BytesLike = Uint8Array | Hex + +//#region UserOperationStruct +// based on @account-abstraction/common +// this is used for building requests +export interface UserOperationStruct { + /* the origin of the request */ + sender: string + /* nonce of the transaction, returned from the entry point for this Address */ + nonce: BigNumberish + /* the initCode for creating the sender if it does not exist yet, otherwise "0x" */ + initCode: BytesLike | "0x" + /* the callData passed to the target */ + callData: BytesLike + /* Value used by inner account execution */ + callGasLimit?: BigNumberish + /* Actual gas used by the validation of this UserOperation */ + verificationGasLimit?: BigNumberish + /* Gas overhead of this UserOperation */ + preVerificationGas?: BigNumberish + /* Maximum fee per gas (similar to EIP-1559 max_fee_per_gas) */ + maxFeePerGas?: BigNumberish + /* Maximum priority fee per gas (similar to EIP-1559 max_priority_fee_per_gas) */ + maxPriorityFeePerGas?: BigNumberish + /* Address of paymaster sponsoring the transaction, followed by extra data to send to the paymaster ("0x" for self-sponsored transaction) */ + paymasterAndData: BytesLike | "0x" + /* Data passed into the account along with the nonce during the verification step */ + signature: BytesLike +} +//#endregion UserOperationStruct + +//#region SmartAccountSigner +/** + * A signer that can sign messages and typed data. + * + * @template Inner - the generic type of the inner client that the signer wraps to provide functionality such as signing, etc. + * + * @var signerType - the type of the signer (e.g. local, hardware, etc.) + * @var inner - the inner client of @type {Inner} + * + * @method getAddress - get the address of the signer + * @method signMessage - sign a message + * @method signTypedData - sign typed data + */ + +// biome-ignore lint/suspicious/noExplicitAny: <explanation> +export interface SmartAccountSigner<Inner = any> { + signerType: string + inner: Inner + + getAddress: () => Promise<Address> + + signMessage: (message: SignableMessage) => Promise<Hex> + + signTypedData: < + const TTypedData extends TypedData | { [key: string]: unknown }, + TPrimaryType extends string = string + >( + params: TypedDataDefinition<TTypedData, TPrimaryType> + ) => Promise<Hex> +} +//#endregion SmartAccountSigner + +//#region UserOperationCallData +export type UserOperationCallData = + | { + /* the target of the call */ + target: Address + /* the data passed to the target */ + data: Hex + /* the amount of native token to send to the target (default: 0) */ + value?: bigint + } + | Hex +//#endregion UserOperationCallData + +//#region BatchUserOperationCallData +export type BatchUserOperationCallData = Exclude<UserOperationCallData, Hex>[] +//#endregion BatchUserOperationCallData + +export type SignTypedDataParams = Omit<SignTypedDataParameters, "privateKey"> + +export type BasSmartContractAccountProps = + BiconomySmartAccountV2ConfigConstructorProps & { + /** chain: The chain from viem */ + chain: Chain + /** rpcClient: The rpc url string */ + rpcClient: string + /** factoryAddress: The address of the factory */ + factoryAddress: Hex + /** entryPointAddress: The address of the entry point */ + entryPointAddress: Hex + /** accountAddress: The address of the account */ + accountAddress?: Address + } + +export interface ISmartContractAccount< + TSigner extends SmartAccountSigner = SmartAccountSigner +> { + /** + * The RPC provider the account uses to make RPC calls + */ + readonly rpcProvider: PublicClient + + /** + * @returns the init code for the account + */ + getInitCode(): Promise<Hex> + + /** + * This is useful for estimating gas costs. It should return a signature that doesn't cause the account to revert + * when validation is run during estimation. + * + * @returns a dummy signature that doesn't cause the account to revert during estimation + */ + getDummySignature(): Hex + + /** + * Encodes a call to the account's execute function. + * + * @param target - the address receiving the call data + * @param value - optionally the amount of native token to send + * @param data - the call data or "0x" if empty + */ + encodeExecute(target: string, value: bigint, data: string): Promise<Hex> + + /** + * Encodes a batch of transactions to the account's batch execute function. + * NOTE: not all accounts support batching. + * @param txs - An Array of objects containing the target, value, and data for each transaction + * @returns the encoded callData for a UserOperation + */ + encodeBatchExecute(txs: BatchUserOperationCallData): Promise<Hex> + + /** + * @returns the nonce of the account + */ + getNonce(): Promise<bigint> + + /** + * If your account handles 1271 signatures of personal_sign differently + * than it does UserOperations, you can implement two different approaches to signing + * + * @param uoHash -- The hash of the UserOperation to sign + * @returns the signature of the UserOperation + */ + signUserOperationHash(uoHash: Hash): Promise<Hash> + + /** + * Returns a signed and prefixed message. + * + * @param msg - the message to sign + * @returns the signature of the message + */ + signMessage(msg: string | Uint8Array | Hex): Promise<Hex> + + /** + * Signs a typed data object as per ERC-712 + * + * @param params - {@link SignTypedDataParams} + * @returns the signed hash for the message passed + */ + signTypedData(params: SignTypedDataParams): Promise<Hash> + + /** + * If the account is not deployed, it will sign the message and then wrap it in 6492 format + * + * @param msg - the message to sign + * @returns ths signature wrapped in 6492 format + */ + signMessageWith6492(msg: string | Uint8Array | Hex): Promise<Hex> + + /** + * If the account is not deployed, it will sign the typed data blob and then wrap it in 6492 format + * + * @param params - {@link SignTypedDataParams} + * @returns the signed hash for the params passed in wrapped in 6492 format + */ + signTypedDataWith6492(params: SignTypedDataParams): Promise<Hash> + + /** + * @returns the address of the account + */ + getAddress(): Promise<Address> + + /** + * @returns the current account signer instance that the smart account client + * operations are being signed with. + * + * The signer is expected to be the owner or one of the owners of the account + * for the signatures to be valid for the acting account. + */ + getSigner(): TSigner + + /** + * @returns the address of the factory contract for the smart account + */ + getFactoryAddress(): Address + + /** + * @returns the address of the entry point contract for the smart account + */ + getEntryPointAddress(): Address + + /** + * Allows you to add additional functionality and utility methods to this account + * via a decorator pattern. + * + * NOTE: this method does not allow you to override existing methods on the account. + * + * @example + * ```ts + * const account = new BaseSmartCobntractAccount(...).extend((account) => ({ + * readAccountState: async (...args) => { + * return this.rpcProvider.readContract({ + * address: await this.getAddress(), + * abi: ThisContractsAbi + * args: args + * }); + * } + * })); + * + * account.debugSendUserOperation(...); + * ``` + * + * @param extendFn -- this function gives you access to the created account instance and returns an object + * with the extension methods + * @returns -- the account with the extension methods added + */ + extend: <R>(extendFn: (self: this) => R) => this & R + + encodeUpgradeToAndCall: ( + upgradeToImplAddress: Address, + upgradeToInitData: Hex + ) => Promise<Hex> +} diff --git a/src/account/utils/Utils.ts b/src/account/utils/Utils.ts new file mode 100644 index 000000000..aa6c54845 --- /dev/null +++ b/src/account/utils/Utils.ts @@ -0,0 +1,161 @@ +import { + type Address, + type Hash, + type Hex, + concat, + encodeAbiParameters, + keccak256, + parseAbiParameters +} from "viem" +import type { UserOperationStruct } from "../../account" +import { type SupportedSigner, convertSigner } from "../../account" +import { extractChainIdFromBundlerUrl } from "../../bundler" +import { extractChainIdFromPaymasterUrl } from "../../bundler" +import type { BiconomySmartAccountV2Config } from "./Types.js" + +/** + * pack the userOperation + * @param op + * @param forSignature "true" if the hash is needed to calculate the getUserOpHash() + * "false" to pack entire UserOp, for calculating the calldata cost of putting it on-chain. + */ +export function packUserOp( + op: Partial<UserOperationStruct>, + forSignature = true +): string { + if (!op.initCode || !op.callData || !op.paymasterAndData) + throw new Error("Missing userOp properties") + if (forSignature) { + return encodeAbiParameters( + parseAbiParameters( + "address, uint256, bytes32, bytes32, uint256, uint256, uint256, uint256, uint256, bytes32" + ), + [ + op.sender as Hex, + BigInt(op.nonce as Hex), + keccak256(op.initCode as Hex), + keccak256(op.callData as Hex), + BigInt(op.callGasLimit as Hex), + BigInt(op.verificationGasLimit as Hex), + BigInt(op.preVerificationGas as Hex), + BigInt(op.maxFeePerGas as Hex), + BigInt(op.maxPriorityFeePerGas as Hex), + keccak256(op.paymasterAndData as Hex) + ] + ) + } + // for the purpose of calculating gas cost encode also signature (and no keccak of bytes) + return encodeAbiParameters( + parseAbiParameters( + "address, uint256, bytes, bytes, uint256, uint256, uint256, uint256, uint256, bytes, bytes" + ), + [ + op.sender as Hex, + BigInt(op.nonce as Hex), + op.initCode as Hex, + op.callData as Hex, + BigInt(op.callGasLimit as Hex), + BigInt(op.verificationGasLimit as Hex), + BigInt(op.preVerificationGas as Hex), + BigInt(op.maxFeePerGas as Hex), + BigInt(op.maxPriorityFeePerGas as Hex), + op.paymasterAndData as Hex, + op.signature as Hex + ] + ) +} + +// biome-ignore lint/suspicious/noExplicitAny: <explanation> +export const isNullOrUndefined = (value: any): value is undefined => { + return value === null || value === undefined +} + +export const compareChainIds = async ( + signer: SupportedSigner, + biconomySmartAccountConfig: BiconomySmartAccountV2Config, + skipChainIdCalls: boolean + // biome-ignore lint/suspicious/noConfusingVoidType: <explanation> +): Promise<Error | void> => { + const signerResult = await convertSigner( + signer, + skipChainIdCalls, + biconomySmartAccountConfig.rpcUrl + ) + + const chainIdFromBundler = biconomySmartAccountConfig.bundlerUrl + ? extractChainIdFromBundlerUrl(biconomySmartAccountConfig.bundlerUrl) + : biconomySmartAccountConfig.bundler + ? extractChainIdFromBundlerUrl( + biconomySmartAccountConfig.bundler.getBundlerUrl() + ) + : undefined + + const chainIdFromPaymasterUrl = biconomySmartAccountConfig.paymasterUrl + ? extractChainIdFromPaymasterUrl(biconomySmartAccountConfig.paymasterUrl) + : undefined + + if (!isNullOrUndefined(signerResult.chainId)) { + if ( + chainIdFromBundler !== undefined && + signerResult.chainId !== chainIdFromBundler + ) { + throw new Error( + `Chain IDs from signer (${signerResult.chainId}) and bundler (${chainIdFromBundler}) do not match.` + ) + } + if ( + chainIdFromPaymasterUrl !== undefined && + signerResult.chainId !== chainIdFromPaymasterUrl + ) { + throw new Error( + `Chain IDs from signer (${signerResult.chainId}) and paymaster (${chainIdFromPaymasterUrl}) do not match.` + ) + } + } else { + if ( + chainIdFromBundler !== undefined && + chainIdFromPaymasterUrl !== undefined && + chainIdFromBundler !== chainIdFromPaymasterUrl + ) { + throw new Error( + `Chain IDs from bundler (${chainIdFromBundler}) and paymaster (${chainIdFromPaymasterUrl}) do not match.` + ) + } + } +} + +export const isValidRpcUrl = (url: string): boolean => { + const regex = /^(https:\/\/|wss:\/\/).*/ + return regex.test(url) +} + +export const addressEquals = (a?: string, b?: string): boolean => + !!a && !!b && a?.toLowerCase() === b.toLowerCase() + +export type SignWith6492Params = { + factoryAddress: Address + factoryCalldata: Hex + signature: Hash +} + +export const wrapSignatureWith6492 = ({ + factoryAddress, + factoryCalldata, + signature +}: SignWith6492Params): Hash => { + // wrap the signature as follows: https://eips.ethereum.org/EIPS/eip-6492 + // concat( + // abi.encode( + // (create2Factory, factoryCalldata, originalERC1271Signature), + // (address, bytes, bytes)), + // magicBytes + // ) + return concat([ + encodeAbiParameters(parseAbiParameters("address, bytes, bytes"), [ + factoryAddress, + factoryCalldata, + signature + ]), + "0x6492649264926492649264926492649264926492649264926492649264926492" + ]) +} diff --git a/src/account/utils/convertSigner.ts b/src/account/utils/convertSigner.ts new file mode 100644 index 000000000..440d82ede --- /dev/null +++ b/src/account/utils/convertSigner.ts @@ -0,0 +1,101 @@ +import { + http, + type PrivateKeyAccount, + type WalletClient, + createWalletClient +} from "viem" +import { WalletClientSigner } from "../../account" +import type { Signer, SmartAccountSigner, SupportedSigner } from "../../account" +import { EthersSigner } from "./EthersSigner.js" + +interface SmartAccountResult { + signer: SmartAccountSigner + chainId: number | null + rpcUrl: string | undefined +} + +function isPrivateKeyAccount( + signer: SupportedSigner +): signer is PrivateKeyAccount { + return (signer as PrivateKeyAccount).type === "local" +} + +function isWalletClient(signer: SupportedSigner): signer is WalletClient { + return (signer as WalletClient).transport !== undefined +} + +function isEthersSigner(signer: SupportedSigner): signer is Signer { + return (signer as Signer).provider !== undefined +} + +function isAlchemySigner( + signer: SupportedSigner +): signer is SmartAccountSigner { + return (signer as SmartAccountSigner).signerType !== undefined +} + +export const convertSigner = async ( + signer: SupportedSigner, + skipChainIdCalls = false, + _rpcUrl?: string +): Promise<SmartAccountResult> => { + let resolvedSmartAccountSigner: SmartAccountSigner + let rpcUrl: string | undefined = _rpcUrl + let chainId: number | null = null + + if (!isAlchemySigner(signer)) { + if (isEthersSigner(signer)) { + const ethersSigner = signer as Signer + if (!skipChainIdCalls) { + // If chainId not provided, get it from walletClient + if (!ethersSigner.provider) { + throw new Error("Cannot consume an ethers Wallet without a provider") + } + const chainIdFromProvider = await ethersSigner.provider.getNetwork() + if (!chainIdFromProvider?.chainId) { + throw new Error("Cannot consume an ethers Wallet without a chainId") + } + chainId = Number(chainIdFromProvider.chainId) + } + // convert ethers Wallet to alchemy's SmartAccountSigner under the hood + resolvedSmartAccountSigner = new EthersSigner(ethersSigner, "ethers") + // @ts-ignore + rpcUrl = ethersSigner.provider?.connection?.url ?? undefined + } else if (isWalletClient(signer)) { + const walletClient = signer as WalletClient + if (!walletClient.account) { + throw new Error("Cannot consume a viem wallet without an account") + } + if (!skipChainIdCalls) { + // If chainId not provided, get it from walletClient + if (!walletClient.chain) { + throw new Error("Cannot consume a viem wallet without a chainId") + } + chainId = walletClient.chain.id + } + // convert viems walletClient to alchemy's SmartAccountSigner under the hood + resolvedSmartAccountSigner = new WalletClientSigner(walletClient, "viem") + rpcUrl = walletClient?.transport?.url ?? undefined + } else if (isPrivateKeyAccount(signer)) { + if (rpcUrl !== null && rpcUrl !== undefined) { + const walletClient = createWalletClient({ + account: signer as PrivateKeyAccount, + transport: http(rpcUrl) + }) + resolvedSmartAccountSigner = new WalletClientSigner( + walletClient, + "viem" + ) + } else { + throw new Error( + "rpcUrl is required for PrivateKeyAccount signer type, please provide it in the config" + ) + } + } else { + throw new Error("Unsupported signer") + } + } else { + resolvedSmartAccountSigner = signer as SmartAccountSigner + } + return { signer: resolvedSmartAccountSigner, rpcUrl, chainId } +} diff --git a/src/account/utils/getChain.ts b/src/account/utils/getChain.ts new file mode 100644 index 000000000..63bb51401 --- /dev/null +++ b/src/account/utils/getChain.ts @@ -0,0 +1,18 @@ +import * as chains from "viem/chains" +import type { Chain } from "viem/chains" + +/** + * Utility method for converting a chainId to a {@link Chain} object + * + * @param chainId + * @returns a {@link Chain} object for the given chainId + * @throws if the chainId is not found + */ +export const getChain = (chainId: number): Chain => { + for (const chain of Object.values(chains)) { + if (chain.id === chainId) { + return chain + } + } + throw new Error("Chain not found") +} diff --git a/src/account/utils/index.ts b/src/account/utils/index.ts new file mode 100644 index 000000000..b1f3d8378 --- /dev/null +++ b/src/account/utils/index.ts @@ -0,0 +1,8 @@ +export * from "./Types.js" +export * from "./Utils.js" +export * from "./Constants.js" +export * from "./convertSigner.js" +export * from "./getChain.js" +export * from "./Logger.js" +export * from "./HttpRequests.js" +export * from "./EthersSigner.js" diff --git a/packages/bundler/src/Bundler.ts b/src/bundler/Bundler.ts similarity index 55% rename from packages/bundler/src/Bundler.ts rename to src/bundler/Bundler.ts index 3782d7066..6772b131f 100644 --- a/packages/bundler/src/Bundler.ts +++ b/src/bundler/Bundler.ts @@ -1,33 +1,36 @@ -import { getChain, type UserOperationStruct } from "@alchemy/aa-core"; -import { createPublicClient, http, PublicClient } from "viem"; -import { IBundler } from "./interfaces/IBundler.js"; +import { http, type PublicClient, createPublicClient } from "viem" +import type { StateOverrideSet, UserOperationStruct } from "../account" +import type { SimulationType } from "../account" +import { HttpMethod, getChain, sendRequest } from "../account" +import type { IBundler } from "./interfaces/IBundler.js" import { - GetUserOperationReceiptResponse, - GetUserOpByHashResponse, + DEFAULT_ENTRYPOINT_ADDRESS, + UserOpReceiptIntervals, + UserOpReceiptMaxDurationIntervals, + UserOpWaitForTxHashIntervals, + UserOpWaitForTxHashMaxDurationIntervals +} from "./utils/Constants.js" +import { + getTimestampInSeconds, + transformUserOP +} from "./utils/HelperFunction.js" +import type { + BundlerConfigWithChainId, Bundlerconfig, - UserOpResponse, EstimateUserOpGasResponse, - UserOpReceipt, - SendUserOpResponse, - UserOpGasResponse, - UserOpByHashResponse, - GetGasFeeValuesResponse, GasFeeValues, - UserOpStatus, + GetGasFeeValuesResponse, + GetUserOpByHashResponse, + GetUserOperationReceiptResponse, GetUserOperationStatusResponse, - SimulationType, - BundlerConfigWithChainId, -} from "./utils/Types.js"; -import { transformUserOP, getTimestampInSeconds } from "./utils/HelperFunction.js"; -import { - UserOpReceiptIntervals, - UserOpWaitForTxHashIntervals, - UserOpWaitForTxHashMaxDurationIntervals, - UserOpReceiptMaxDurationIntervals, - DEFAULT_ENTRYPOINT_ADDRESS, -} from "./utils/Constants.js"; -import { extractChainIdFromBundlerUrl } from "./utils/Utils.js"; -import { sendRequest, HttpMethod, StateOverrideSet } from "@biconomy/common"; + SendUserOpResponse, + UserOpByHashResponse, + UserOpGasResponse, + UserOpReceipt, + UserOpResponse, + UserOpStatus +} from "./utils/Types.js" +import { extractChainIdFromBundlerUrl } from "./utils/Utils.js" /** * This class implements IBundler interface. @@ -35,53 +38,59 @@ import { sendRequest, HttpMethod, StateOverrideSet } from "@biconomy/common"; * Checkout the proposal for more details on Bundlers. */ export class Bundler implements IBundler { - private bundlerConfig: BundlerConfigWithChainId; + private bundlerConfig: BundlerConfigWithChainId // eslint-disable-next-line no-unused-vars - UserOpReceiptIntervals!: { [key in number]?: number }; + UserOpReceiptIntervals!: { [key in number]?: number } - UserOpWaitForTxHashIntervals!: { [key in number]?: number }; + UserOpWaitForTxHashIntervals!: { [key in number]?: number } - UserOpReceiptMaxDurationIntervals!: { [key in number]?: number }; + UserOpReceiptMaxDurationIntervals!: { [key in number]?: number } - UserOpWaitForTxHashMaxDurationIntervals!: { [key in number]?: number }; + UserOpWaitForTxHashMaxDurationIntervals!: { [key in number]?: number } - private provider: PublicClient; + private provider: PublicClient constructor(bundlerConfig: Bundlerconfig) { - const parsedChainId: number = bundlerConfig?.chainId || extractChainIdFromBundlerUrl(bundlerConfig.bundlerUrl); - this.bundlerConfig = { ...bundlerConfig, chainId: parsedChainId }; + const parsedChainId: number = + bundlerConfig?.chainId || + extractChainIdFromBundlerUrl(bundlerConfig.bundlerUrl) + this.bundlerConfig = { ...bundlerConfig, chainId: parsedChainId } this.provider = createPublicClient({ chain: bundlerConfig.viemChain ?? getChain(parsedChainId), - transport: http((bundlerConfig.viemChain || getChain(parsedChainId)).rpcUrls.default.http[0]), - }); + transport: http( + (bundlerConfig.viemChain || getChain(parsedChainId)).rpcUrls.default + .http[0] + ) + }) this.UserOpReceiptIntervals = { ...UserOpReceiptIntervals, - ...bundlerConfig.userOpReceiptIntervals, - }; + ...bundlerConfig.userOpReceiptIntervals + } this.UserOpWaitForTxHashIntervals = { ...UserOpWaitForTxHashIntervals, - ...bundlerConfig.userOpWaitForTxHashIntervals, - }; + ...bundlerConfig.userOpWaitForTxHashIntervals + } this.UserOpReceiptMaxDurationIntervals = { ...UserOpReceiptMaxDurationIntervals, - ...bundlerConfig.userOpReceiptMaxDurationIntervals, - }; + ...bundlerConfig.userOpReceiptMaxDurationIntervals + } this.UserOpWaitForTxHashMaxDurationIntervals = { ...UserOpWaitForTxHashMaxDurationIntervals, - ...bundlerConfig.userOpWaitForTxHashMaxDurationIntervals, - }; + ...bundlerConfig.userOpWaitForTxHashMaxDurationIntervals + } - this.bundlerConfig.entryPointAddress = bundlerConfig.entryPointAddress || DEFAULT_ENTRYPOINT_ADDRESS; + this.bundlerConfig.entryPointAddress = + bundlerConfig.entryPointAddress || DEFAULT_ENTRYPOINT_ADDRESS } public getBundlerUrl(): string { - return `${this.bundlerConfig.bundlerUrl}`; + return `${this.bundlerConfig.bundlerUrl}` } /** @@ -89,11 +98,14 @@ export class Bundler implements IBundler { * @description This function will fetch gasPrices from bundler * @returns Promise<UserOpGasPricesResponse> */ - async estimateUserOpGas(userOp: UserOperationStruct, stateOverrideSet?: StateOverrideSet): Promise<UserOpGasResponse> { + async estimateUserOpGas( + _userOp: UserOperationStruct, + stateOverrideSet?: StateOverrideSet + ): Promise<UserOpGasResponse> { // expected dummySig and possibly dummmy paymasterAndData should be provided by the caller // bundler doesn't know account and paymaster implementation - userOp = transformUserOP(userOp); - const bundlerUrl = this.getBundlerUrl(); + const userOp = transformUserOP(_userOp) + const bundlerUrl = this.getBundlerUrl() const response: EstimateUserOpGasResponse = await sendRequest( { @@ -105,20 +117,23 @@ export class Bundler implements IBundler { ? [userOp, this.bundlerConfig.entryPointAddress, stateOverrideSet] : [userOp, this.bundlerConfig.entryPointAddress], id: getTimestampInSeconds(), - jsonrpc: "2.0", - }, + jsonrpc: "2.0" + } }, - "Bundler", - ); + "Bundler" + ) - const userOpGasResponse = response.result; + const userOpGasResponse = response.result for (const key in userOpGasResponse) { - if (key === "maxFeePerGas" || key === "maxPriorityFeePerGas") continue; - if (userOpGasResponse[key as keyof UserOpGasResponse] === undefined || userOpGasResponse[key as keyof UserOpGasResponse] === null) { - throw new Error(`Got undefined ${key} from bundler`); + if (key === "maxFeePerGas" || key === "maxPriorityFeePerGas") continue + if ( + userOpGasResponse[key as keyof UserOpGasResponse] === undefined || + userOpGasResponse[key as keyof UserOpGasResponse] === null + ) { + throw new Error(`Got undefined ${key} from bundler`) } } - return userOpGasResponse; + return userOpGasResponse } /** @@ -127,15 +142,18 @@ export class Bundler implements IBundler { * @description This function will send signed userOp to bundler to get mined on chain * @returns Promise<UserOpResponse> */ - async sendUserOp(userOp: UserOperationStruct, simulationParam?: SimulationType): Promise<UserOpResponse> { - const chainId = this.bundlerConfig.chainId; + async sendUserOp( + _userOp: UserOperationStruct, + simulationParam?: SimulationType + ): Promise<UserOpResponse> { + const chainId = this.bundlerConfig.chainId // transformUserOP will convert all bigNumber values to string - userOp = transformUserOP(userOp); + const userOp = transformUserOP(_userOp) const simType = { - simulation_type: simulationParam || "validation", - }; - const params = [userOp, this.bundlerConfig.entryPointAddress, simType]; - const bundlerUrl = this.getBundlerUrl(); + simulation_type: simulationParam || "validation" + } + const params = [userOp, this.bundlerConfig.entryPointAddress, simType] + const bundlerUrl = this.getBundlerUrl() const sendUserOperationResponse: SendUserOpResponse = await sendRequest( { url: bundlerUrl, @@ -144,94 +162,106 @@ export class Bundler implements IBundler { method: "eth_sendUserOperation", params: params, id: getTimestampInSeconds(), - jsonrpc: "2.0", - }, + jsonrpc: "2.0" + } }, - "Bundler", - ); + "Bundler" + ) const response: UserOpResponse = { userOpHash: sendUserOperationResponse.result, wait: (confirmations?: number): Promise<UserOpReceipt> => { // Note: maxDuration can be defined per chainId - const maxDuration = this.UserOpReceiptMaxDurationIntervals[chainId] || 30000; // default 30 seconds - let totalDuration = 0; + const maxDuration = + this.UserOpReceiptMaxDurationIntervals[chainId] || 30000 // default 30 seconds + let totalDuration = 0 return new Promise<UserOpReceipt>((resolve, reject) => { - const intervalValue = this.UserOpReceiptIntervals[chainId] || 5000; // default 5 seconds + const intervalValue = this.UserOpReceiptIntervals[chainId] || 5000 // default 5 seconds const intervalId = setInterval(async () => { try { - const userOpResponse = await this.getUserOpReceipt(sendUserOperationResponse.result); - if (userOpResponse && userOpResponse.receipt && userOpResponse.receipt.blockNumber) { + const userOpResponse = await this.getUserOpReceipt( + sendUserOperationResponse.result + ) + if (userOpResponse?.receipt?.blockNumber) { if (confirmations) { - const latestBlock = await this.provider.getBlockNumber(); - const confirmedBlocks = Number(latestBlock) - userOpResponse.receipt.blockNumber; + const latestBlock = await this.provider.getBlockNumber() + const confirmedBlocks = + Number(latestBlock) - userOpResponse.receipt.blockNumber if (confirmations >= confirmedBlocks) { - clearInterval(intervalId); - resolve(userOpResponse); - return; + clearInterval(intervalId) + resolve(userOpResponse) + return } } else { - clearInterval(intervalId); - resolve(userOpResponse); - return; + clearInterval(intervalId) + resolve(userOpResponse) + return } } } catch (error) { - clearInterval(intervalId); - reject(error); - return; + clearInterval(intervalId) + reject(error) + return } - totalDuration += intervalValue; + totalDuration += intervalValue if (totalDuration >= maxDuration) { - clearInterval(intervalId); + clearInterval(intervalId) reject( new Error( - `Exceeded maximum duration (${maxDuration / 1000} sec) waiting to get receipt for userOpHash ${ + `Exceeded maximum duration (${ + maxDuration / 1000 + } sec) waiting to get receipt for userOpHash ${ sendUserOperationResponse.result - }. Try getting the receipt manually using eth_getUserOperationReceipt rpc method on bundler`, - ), - ); + }. Try getting the receipt manually using eth_getUserOperationReceipt rpc method on bundler` + ) + ) } - }, intervalValue); - }); + }, intervalValue) + }) }, waitForTxHash: (): Promise<UserOpStatus> => { - const maxDuration = this.UserOpWaitForTxHashMaxDurationIntervals[chainId] || 20000; // default 20 seconds - let totalDuration = 0; + const maxDuration = + this.UserOpWaitForTxHashMaxDurationIntervals[chainId] || 20000 // default 20 seconds + let totalDuration = 0 return new Promise<UserOpStatus>((resolve, reject) => { - const intervalValue = this.UserOpWaitForTxHashIntervals[chainId] || 500; // default 0.5 seconds + const intervalValue = + this.UserOpWaitForTxHashIntervals[chainId] || 500 // default 0.5 seconds const intervalId = setInterval(async () => { try { - const userOpStatus = await this.getUserOpStatus(sendUserOperationResponse.result); - if (userOpStatus && userOpStatus.state && userOpStatus.transactionHash) { - clearInterval(intervalId); - resolve(userOpStatus); - return; + const userOpStatus = await this.getUserOpStatus( + sendUserOperationResponse.result + ) + if (userOpStatus?.state && userOpStatus.transactionHash) { + clearInterval(intervalId) + resolve(userOpStatus) + return } } catch (error) { - clearInterval(intervalId); - reject(error); - return; + clearInterval(intervalId) + reject(error) + return } - totalDuration += intervalValue; + totalDuration += intervalValue if (totalDuration >= maxDuration) { - clearInterval(intervalId); + clearInterval(intervalId) reject( new Error( - `Exceeded maximum duration (${maxDuration / 1000} sec) waiting to get receipt for userOpHash ${ + `Exceeded maximum duration (${ + maxDuration / 1000 + } sec) waiting to get receipt for userOpHash ${ sendUserOperationResponse.result - }. Try getting the receipt manually using eth_getUserOperationReceipt rpc method on bundler`, - ), - ); + }. Try getting the receipt manually using eth_getUserOperationReceipt rpc method on bundler` + ) + ) } - }, intervalValue); - }); - }, - }; - return response; + }, intervalValue) + }) + } + } + return response } /** @@ -241,7 +271,7 @@ export class Bundler implements IBundler { * @returns Promise<UserOpReceipt> */ async getUserOpReceipt(userOpHash: string): Promise<UserOpReceipt> { - const bundlerUrl = this.getBundlerUrl(); + const bundlerUrl = this.getBundlerUrl() const response: GetUserOperationReceiptResponse = await sendRequest( { url: bundlerUrl, @@ -250,13 +280,13 @@ export class Bundler implements IBundler { method: "eth_getUserOperationReceipt", params: [userOpHash], id: getTimestampInSeconds(), - jsonrpc: "2.0", - }, + jsonrpc: "2.0" + } }, - "Bundler", - ); - const userOpReceipt: UserOpReceipt = response.result; - return userOpReceipt; + "Bundler" + ) + const userOpReceipt: UserOpReceipt = response.result + return userOpReceipt } /** @@ -266,7 +296,7 @@ export class Bundler implements IBundler { * @returns Promise<UserOpReceipt> */ async getUserOpStatus(userOpHash: string): Promise<UserOpStatus> { - const bundlerUrl = this.getBundlerUrl(); + const bundlerUrl = this.getBundlerUrl() const response: GetUserOperationStatusResponse = await sendRequest( { url: bundlerUrl, @@ -275,13 +305,13 @@ export class Bundler implements IBundler { method: "biconomy_getUserOperationStatus", params: [userOpHash], id: getTimestampInSeconds(), - jsonrpc: "2.0", - }, + jsonrpc: "2.0" + } }, - "Bundler", - ); - const userOpStatus: UserOpStatus = response.result; - return userOpStatus; + "Bundler" + ) + const userOpStatus: UserOpStatus = response.result + return userOpStatus } /** @@ -291,7 +321,7 @@ export class Bundler implements IBundler { * @returns Promise<UserOpByHashResponse> */ async getUserOpByHash(userOpHash: string): Promise<UserOpByHashResponse> { - const bundlerUrl = this.getBundlerUrl(); + const bundlerUrl = this.getBundlerUrl() const response: GetUserOpByHashResponse = await sendRequest( { url: bundlerUrl, @@ -300,20 +330,20 @@ export class Bundler implements IBundler { method: "eth_getUserOperationByHash", params: [userOpHash], id: getTimestampInSeconds(), - jsonrpc: "2.0", - }, + jsonrpc: "2.0" + } }, - "Bundler", - ); - const userOpByHashResponse: UserOpByHashResponse = response.result; - return userOpByHashResponse; + "Bundler" + ) + const userOpByHashResponse: UserOpByHashResponse = response.result + return userOpByHashResponse } /** * @description This function will return the gas fee values */ async getGasFeeValues(): Promise<GasFeeValues> { - const bundlerUrl = this.getBundlerUrl(); + const bundlerUrl = this.getBundlerUrl() const response: GetGasFeeValuesResponse = await sendRequest( { url: bundlerUrl, @@ -322,15 +352,15 @@ export class Bundler implements IBundler { method: "biconomy_getGasFeeValues", params: [], id: getTimestampInSeconds(), - jsonrpc: "2.0", - }, + jsonrpc: "2.0" + } }, - "Bundler", - ); - return response.result; + "Bundler" + ) + return response.result } public static async create(config: Bundlerconfig): Promise<Bundler> { - return new Bundler(config); + return new Bundler(config) } } diff --git a/src/bundler/IBundler.ts b/src/bundler/IBundler.ts new file mode 100644 index 000000000..1e15c7c19 --- /dev/null +++ b/src/bundler/IBundler.ts @@ -0,0 +1,26 @@ +import type { SimulationType } from "../account" +import type { StateOverrideSet, UserOperationStruct } from "../account" +import type { + GasFeeValues, + UserOpByHashResponse, + UserOpGasResponse, + UserOpReceipt, + UserOpResponse, + UserOpStatus +} from "./utils/Types.js" + +export interface IBundler { + estimateUserOpGas( + _userOp: Partial<UserOperationStruct>, + stateOverrideSet?: StateOverrideSet + ): Promise<UserOpGasResponse> + sendUserOp( + _userOp: UserOperationStruct, + _simulationType?: SimulationType + ): Promise<UserOpResponse> + getUserOpReceipt(_userOpHash: string): Promise<UserOpReceipt> + getUserOpByHash(_userOpHash: string): Promise<UserOpByHashResponse> + getGasFeeValues(): Promise<GasFeeValues> + getUserOpStatus(_userOpHash: string): Promise<UserOpStatus> + getBundlerUrl(): string +} diff --git a/src/bundler/index.ts b/src/bundler/index.ts new file mode 100644 index 000000000..5986083f4 --- /dev/null +++ b/src/bundler/index.ts @@ -0,0 +1,8 @@ +import { Bundler } from "./Bundler.js" + +export * from "./interfaces/IBundler.js" +export * from "./Bundler.js" +export * from "./utils/Utils.js" +export * from "./utils/Types.js" + +export const createBundler = Bundler.create diff --git a/src/bundler/interfaces/IBundler.ts b/src/bundler/interfaces/IBundler.ts new file mode 100644 index 000000000..aa7f551fe --- /dev/null +++ b/src/bundler/interfaces/IBundler.ts @@ -0,0 +1,29 @@ +import type { + SimulationType, + StateOverrideSet, + UserOperationStruct +} from "../../account" +import type { + GasFeeValues, + UserOpByHashResponse, + UserOpGasResponse, + UserOpReceipt, + UserOpResponse, + UserOpStatus +} from "../utils/Types.js" + +export interface IBundler { + estimateUserOpGas( + _userOp: Partial<UserOperationStruct>, + stateOverrideSet?: StateOverrideSet + ): Promise<UserOpGasResponse> + sendUserOp( + _userOp: UserOperationStruct, + _simulationType?: SimulationType + ): Promise<UserOpResponse> + getUserOpReceipt(_userOpHash: string): Promise<UserOpReceipt> + getUserOpByHash(_userOpHash: string): Promise<UserOpByHashResponse> + getGasFeeValues(): Promise<GasFeeValues> + getUserOpStatus(_userOpHash: string): Promise<UserOpStatus> + getBundlerUrl(): string +} diff --git a/packages/bundler/src/utils/Constants.ts b/src/bundler/utils/Constants.ts similarity index 58% rename from packages/bundler/src/utils/Constants.ts rename to src/bundler/utils/Constants.ts index 8ffd436a5..297fff8f7 100644 --- a/packages/bundler/src/utils/Constants.ts +++ b/src/bundler/utils/Constants.ts @@ -1,27 +1,32 @@ export const UserOpReceiptIntervals: { [key in number]?: number } = { - [1]: 10000, -}; + [1]: 10000 +} // Note: Default value is 500(0.5sec) export const UserOpWaitForTxHashIntervals: { [key in number]?: number } = { - [1]: 1000, -}; + [1]: 1000 +} // Note: Default value is 30000 (30sec) export const UserOpReceiptMaxDurationIntervals: { [key in number]?: number } = { [1]: 300000, - [80001]: 50000, + [80002]: 50000, [137]: 60000, [56]: 50000, [97]: 50000, [421613]: 50000, [42161]: 50000, - [59140]: 50000, // linea testnet -}; + [59140]: 50000 // linea testnet +} // Note: Default value is 20000 (20sec) -export const UserOpWaitForTxHashMaxDurationIntervals: { [key in number]?: number } = { - [1]: 20000, -}; +export const UserOpWaitForTxHashMaxDurationIntervals: { + [key in number]?: number +} = { + [1]: 20000 +} -export const DEFAULT_ENTRYPOINT_ADDRESS = "0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789"; +export const DEFAULT_ENTRYPOINT_ADDRESS = + "0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789" + +export const SDK_VERSION = "4.2.0" diff --git a/packages/bundler/src/utils/HelperFunction.ts b/src/bundler/utils/HelperFunction.ts similarity index 52% rename from packages/bundler/src/utils/HelperFunction.ts rename to src/bundler/utils/HelperFunction.ts index 670e04d31..ecdaf688d 100644 --- a/packages/bundler/src/utils/HelperFunction.ts +++ b/src/bundler/utils/HelperFunction.ts @@ -1,32 +1,36 @@ -import type { BigNumberish, UserOperationStruct } from "@alchemy/aa-core"; +import type { BigNumberish, UserOperationStruct } from "../../account" // Will convert the userOp hex, bigInt and number values to hex strings -export const transformUserOP = (userOp: UserOperationStruct): UserOperationStruct => { +export const transformUserOP = ( + userOp: UserOperationStruct +): UserOperationStruct => { try { - const userOperation = { ...userOp }; + const userOperation = { ...userOp } const keys: (keyof UserOperationStruct)[] = [ "nonce", "callGasLimit", "verificationGasLimit", "preVerificationGas", "maxFeePerGas", - "maxPriorityFeePerGas", - ]; + "maxPriorityFeePerGas" + ] for (const key of keys) { if (userOperation[key] && userOperation[key] !== "0x") { - userOperation[key] = ("0x" + BigInt(userOp[key] as BigNumberish).toString(16)) as `0x${string}`; + userOperation[key] = `0x${BigInt(userOp[key] as BigNumberish).toString( + 16 + )}` as `0x${string}` } } - return userOperation; + return userOperation } catch (error) { - throw `Failed to transform user operation: ${error}`; + throw `Failed to transform user operation: ${error}` } -}; +} /** * @description this function will return current timestamp in seconds * @returns Number */ export const getTimestampInSeconds = (): number => { - return Math.floor(Date.now() / 1000); -}; + return Math.floor(Date.now() / 1000) +} diff --git a/packages/bundler/src/utils/Types.ts b/src/bundler/utils/Types.ts similarity index 51% rename from packages/bundler/src/utils/Types.ts rename to src/bundler/utils/Types.ts index 1da57281f..d04b4505d 100644 --- a/packages/bundler/src/utils/Types.ts +++ b/src/bundler/utils/Types.ts @@ -1,124 +1,122 @@ -import { UserOperationStruct } from "@alchemy/aa-core"; -import { Chain, Hex } from "viem"; +import type { Chain, Hex } from "viem" +import type { UserOperationStruct } from "../../account" export type Bundlerconfig = { - bundlerUrl: string; - entryPointAddress?: string; - chainId?: number; + bundlerUrl: string + entryPointAddress?: string + chainId?: number // eslint-disable-next-line no-unused-vars - userOpReceiptIntervals?: { [key in number]?: number }; - userOpWaitForTxHashIntervals?: { [key in number]?: number }; - userOpReceiptMaxDurationIntervals?: { [key in number]?: number }; - userOpWaitForTxHashMaxDurationIntervals?: { [key in number]?: number }; + userOpReceiptIntervals?: { [key in number]?: number } + userOpWaitForTxHashIntervals?: { [key in number]?: number } + userOpReceiptMaxDurationIntervals?: { [key in number]?: number } + userOpWaitForTxHashMaxDurationIntervals?: { [key in number]?: number } /** Can be used to optionally override the chain with a custom chain if it doesn't already exist in viems list of supported chains */ - viemChain?: Chain; -}; -export type BundlerConfigWithChainId = Bundlerconfig & { chainId: number }; + viemChain?: Chain +} +export type BundlerConfigWithChainId = Bundlerconfig & { chainId: number } export type UserOpReceipt = { /* The request hash of the UserOperation. */ - userOpHash: string; + userOpHash: string /* The entry point address used for the UserOperation. */ - entryPoint: string; + entryPoint: string /* The paymaster used for this UserOperation (or empty). */ - paymaster: string; + paymaster: string /* The actual amount paid (by account or paymaster) for this UserOperation. */ - actualGasCost: Hex; + actualGasCost: Hex /* The total gas used by this UserOperation (including preVerification, creation, validation, and execution). */ - actualGasUsed: Hex; + actualGasUsed: Hex /* Indicates whether the execution completed without reverting. */ - success: "true" | "false"; + success: "true" | "false" /* In case of revert, this is the revert reason. */ - reason: string; + reason: string /* The logs generated by this UserOperation (not including logs of other UserOperations in the same bundle). */ - logs: Array<any>; // The logs generated by this UserOperation (not including logs of other UserOperations in the same bundle) + logs: Array<any> // The logs generated by this UserOperation (not including logs of other UserOperations in the same bundle) /* The TransactionReceipt object for the entire bundle, not only for this UserOperation. */ - receipt: any; -}; + receipt: any +} // review export type UserOpStatus = { - state: string; // for now // could be an enum - transactionHash?: string; - userOperationReceipt?: UserOpReceipt; -}; - -export type SimulationType = "validation" | "validation_and_execution"; + state: string // for now // could be an enum + transactionHash?: string + userOperationReceipt?: UserOpReceipt +} // Converted to JsonRpcResponse with strict type export type GetUserOperationReceiptResponse = { - jsonrpc: string; - id: number; - result: UserOpReceipt; - error?: JsonRpcError; -}; + jsonrpc: string + id: number + result: UserOpReceipt + error?: JsonRpcError +} export type GetUserOperationStatusResponse = { - jsonrpc: string; - id: number; - result: UserOpStatus; - error?: JsonRpcError; -}; + jsonrpc: string + id: number + result: UserOpStatus + error?: JsonRpcError +} // Converted to JsonRpcResponse with strict type export type SendUserOpResponse = { - jsonrpc: string; - id: number; - result: string; - error?: JsonRpcError; -}; + jsonrpc: string + id: number + result: string + error?: JsonRpcError +} export type UserOpResponse = { - userOpHash: string; - wait(_confirmations?: number): Promise<UserOpReceipt>; + userOpHash: string + wait(_confirmations?: number): Promise<UserOpReceipt> // Review: waitForTxHash(): vs waitForTxHash?(): - waitForTxHash(): Promise<UserOpStatus>; -}; + waitForTxHash(): Promise<UserOpStatus> +} // Converted to JsonRpcResponse with strict type export type EstimateUserOpGasResponse = { - jsonrpc: string; - id: number; - result: UserOpGasResponse; - error?: JsonRpcError; -}; + jsonrpc: string + id: number + result: UserOpGasResponse + error?: JsonRpcError +} export type UserOpGasResponse = { - preVerificationGas: string; - verificationGasLimit: string; - callGasLimit: string; - maxPriorityFeePerGas: string; - maxFeePerGas: string; -}; + preVerificationGas: string + verificationGasLimit: string + callGasLimit: string + maxPriorityFeePerGas: string + maxFeePerGas: string +} // Converted to JsonRpcResponse with strict type export type GetUserOpByHashResponse = { - jsonrpc: string; - id: number; - result: UserOpByHashResponse; - error?: JsonRpcError; -}; + jsonrpc: string + id: number + result: UserOpByHashResponse + error?: JsonRpcError +} export type UserOpByHashResponse = UserOperationStruct & { - transactionHash: string; - blockNumber: number; - blockHash: string; - entryPoint: string; -}; + transactionHash: string + blockNumber: number + blockHash: string + entryPoint: string +} /* eslint-disable @typescript-eslint/no-explicit-any */ export type JsonRpcError = { - code: string; - message: string; - data: any; -}; + code: string + message: string + data: any +} export type GetGasFeeValuesResponse = { - jsonrpc: string; - id: number; - result: GasFeeValues; - error?: JsonRpcError; -}; + jsonrpc: string + id: number + result: GasFeeValues + error?: JsonRpcError +} export type GasFeeValues = { - maxPriorityFeePerGas: string; - maxFeePerGas: string; -}; + maxPriorityFeePerGas: string + maxFeePerGas: string +} diff --git a/src/bundler/utils/Utils.ts b/src/bundler/utils/Utils.ts new file mode 100644 index 000000000..700a2bb59 --- /dev/null +++ b/src/bundler/utils/Utils.ts @@ -0,0 +1,23 @@ +export const extractChainIdFromBundlerUrl = (url: string): number => { + try { + const regex = /\/api\/v2\/(\d+)\/[a-zA-Z0-9.-]+$/ + // biome-ignore lint/style/noNonNullAssertion: <explanation> + const match = regex.exec(url)! + return Number.parseInt(match[1]) + } catch (error) { + throw new Error("Invalid chain id") + } +} + +export const extractChainIdFromPaymasterUrl = (url: string): number => { + try { + const regex = /\/api\/v\d+\/(\d+)\// + const match = regex.exec(url) + if (!match) { + throw new Error("Invalid URL format") + } + return Number.parseInt(match[1]) + } catch (error) { + throw new Error("Invalid chain id") + } +} diff --git a/src/bundler/utils/getAAError.ts b/src/bundler/utils/getAAError.ts new file mode 100644 index 000000000..7a04be10f --- /dev/null +++ b/src/bundler/utils/getAAError.ts @@ -0,0 +1,85 @@ +import { BaseError } from "viem" +import type { Service } from "../../account" +import { SDK_VERSION } from "./Constants" +export type KnownError = { + name: string + regex: string + description: string + causes: string[] + solutions: string[] + docsUrl?: string +} + +export const ERRORS_URL = "https://bcnmy.github.io/aa-errors/errors.json" +export const DOCS_URL = "https://docs.biconomy.io/troubleshooting/commonerrors" +const UNKOWN_ERROR_CODE = "520" + +const knownErrors: KnownError[] = [] + +const matchError = (message: string): null | KnownError => + knownErrors.find( + (knownError: KnownError) => + message.toLowerCase().indexOf(knownError.regex) > -1 + ) ?? null + +const buildErrorStrings = ( + error: KnownError, + status: string, + service?: Service +): string[] => + [ + `${status}: ${error.description}\n`, + error.causes?.length + ? ["Potential cause(s): \n", ...error.causes, ""].join("\n") + : "", + error.solutions?.length + ? ["Potential solution(s): \n", ...error.solutions].join("\n") + : "", + service ? `\nSent via: ${service}` : "" + ].filter(Boolean) + +type AccountAbstractionErrorParams = { + docsSlug?: string + metaMessages?: string[] + details?: string +} + +class AccountAbstractionError extends BaseError { + override name = "AccountAbstractionError" + override version = `@biconomy/account@${SDK_VERSION}` + + constructor(title: string, params: AccountAbstractionErrorParams = {}) { + super(title, params) + } +} + +export const getAAError = async ( + message: string, + httpStatus?: number, + service?: Service +) => { + if (!knownErrors.length) { + const errors = (await (await fetch(ERRORS_URL)).json()) as KnownError[] + knownErrors.push(...errors) + } + + const details: string = + `${service} - ${typeof message}` === "string" + ? message + : JSON.stringify(message) + const matchedError = matchError(details) + const status = + matchedError?.regex ?? (httpStatus ?? UNKOWN_ERROR_CODE).toString() + + const metaMessages = matchedError + ? buildErrorStrings(matchedError, status, service) + : [] + const title = matchedError ? matchedError.name : "Unknown Error" + const docsSlug = matchedError?.docsUrl ?? DOCS_URL + + return new AccountAbstractionError(title, { + docsSlug, + metaMessages, + details + }) +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 000000000..b7976357d --- /dev/null +++ b/src/index.ts @@ -0,0 +1,4 @@ +export * from "./account" +export * from "./bundler" +export * from "./paymaster" +export * from "./modules" diff --git a/src/modules/BaseValidationModule.ts b/src/modules/BaseValidationModule.ts new file mode 100644 index 000000000..265a4f9cf --- /dev/null +++ b/src/modules/BaseValidationModule.ts @@ -0,0 +1,51 @@ +import type { Hex } from "viem" +import { DEFAULT_ENTRYPOINT_ADDRESS, type SmartAccountSigner } from "../account" +import type { IValidationModule } from "./interfaces/IValidationModule.js" +import type { BaseValidationModuleConfig, ModuleInfo } from "./utils/Types.js" + +export abstract class BaseValidationModule implements IValidationModule { + entryPointAddress: Hex + + constructor(moduleConfig: BaseValidationModuleConfig) { + const { entryPointAddress } = moduleConfig + + this.entryPointAddress = entryPointAddress || DEFAULT_ENTRYPOINT_ADDRESS + } + + abstract getAddress(): Hex + + setEntryPointAddress(entryPointAddress: Hex): void { + this.entryPointAddress = entryPointAddress + } + + abstract getInitData(): Promise<Hex> + + // Anything required to get dummy signature can be passed as params + abstract getDummySignature(_params?: ModuleInfo): Promise<Hex> + + abstract getSigner(): Promise<SmartAccountSigner> + + // Signer specific or any other additional information can be passed as params + abstract signUserOpHash( + _userOpHash: string, + _params?: ModuleInfo + ): Promise<Hex> + + abstract signMessage(_message: Uint8Array | string): Promise<string> + + async signMessageSmartAccountSigner( + _message: string | Uint8Array, + signer: SmartAccountSigner + ): Promise<string> { + const message = typeof _message === "string" ? _message : { raw: _message } + let signature: `0x${string}` = await signer.signMessage(message) + + const potentiallyIncorrectV = Number.parseInt(signature.slice(-2), 16) + if (![27, 28].includes(potentiallyIncorrectV)) { + const correctV = potentiallyIncorrectV + 27 + signature = `0x${signature.slice(0, -2) + correctV.toString(16)}` + } + + return signature + } +} diff --git a/src/modules/BatchedSessionRouterModule.ts b/src/modules/BatchedSessionRouterModule.ts new file mode 100644 index 000000000..42f607d80 --- /dev/null +++ b/src/modules/BatchedSessionRouterModule.ts @@ -0,0 +1,363 @@ +import { + type Hex, + concat, + encodeAbiParameters, + keccak256, + pad, + parseAbiParameters, + toBytes, + toHex +} from "viem" +import { type SmartAccountSigner, convertSigner } from "../account" +import { BaseValidationModule } from "./BaseValidationModule.js" +import { SessionKeyManagerModule } from "./SessionKeyManagerModule.js" +import type { + SessionSearchParam, + SessionStatus +} from "./interfaces/ISessionStorage.js" +import { + BATCHED_SESSION_ROUTER_MODULE_ADDRESSES_BY_VERSION, + DEFAULT_BATCHED_SESSION_ROUTER_MODULE, + DEFAULT_SESSION_KEY_MANAGER_MODULE +} from "./utils/Constants.js" +// @ts-nocheck +import type { + BatchedSessionRouterModuleConfig, + CreateSessionDataParams, + CreateSessionDataResponse, + ModuleInfo, + ModuleVersion, + SessionDataTuple +} from "./utils/Types.js" + +export class BatchedSessionRouterModule extends BaseValidationModule { + version: ModuleVersion = "V1_0_0" + + moduleAddress!: Hex + + sessionManagerModuleAddress!: Hex + + sessionKeyManagerModule!: SessionKeyManagerModule + + readonly mockEcdsaSessionKeySig: Hex = + "0x73c3ac716c487ca34bb858247b5ccf1dc354fbaabdd089af3b2ac8e78ba85a4959a2d76250325bd67c11771c31fccda87c33ceec17cc0de912690521bb95ffcb1b" + + /** + * This constructor is private. Use the static create method to instantiate SessionKeyManagerModule + * @param moduleConfig The configuration for the module + * @returns An instance of SessionKeyManagerModule + */ + private constructor(moduleConfig: BatchedSessionRouterModuleConfig) { + super(moduleConfig) + } + + /** + * Asynchronously creates and initializes an instance of SessionKeyManagerModule + * @param moduleConfig The configuration for the module + * @returns A Promise that resolves to an instance of SessionKeyManagerModule + */ + public static async create( + moduleConfig: BatchedSessionRouterModuleConfig + ): Promise<BatchedSessionRouterModule> { + const instance = new BatchedSessionRouterModule(moduleConfig) + + if (moduleConfig.moduleAddress) { + instance.moduleAddress = moduleConfig.moduleAddress + } else if (moduleConfig.version) { + const moduleAddr = BATCHED_SESSION_ROUTER_MODULE_ADDRESSES_BY_VERSION[ + moduleConfig.version + ] as Hex + if (!moduleAddr) { + throw new Error(`Invalid version ${moduleConfig.version}`) + } + instance.moduleAddress = moduleAddr + instance.version = moduleConfig.version as ModuleVersion + } else { + instance.moduleAddress = DEFAULT_BATCHED_SESSION_ROUTER_MODULE + // Note: in this case Version remains the default one + } + + instance.sessionManagerModuleAddress = + moduleConfig.sessionManagerModuleAddress ?? + DEFAULT_SESSION_KEY_MANAGER_MODULE + + if (!moduleConfig.sessionKeyManagerModule) { + // generate sessionModule + const sessionModule = await SessionKeyManagerModule.create({ + moduleAddress: instance.sessionManagerModuleAddress, + smartAccountAddress: moduleConfig.smartAccountAddress, + storageType: moduleConfig.storageType + }) + + instance.sessionKeyManagerModule = sessionModule + } else { + instance.sessionKeyManagerModule = moduleConfig.sessionKeyManagerModule + instance.sessionManagerModuleAddress = + moduleConfig.sessionKeyManagerModule.getAddress() + } + + return instance + } + + /** + * Method to create session data for any module. The session data is used to create a leaf in the merkle tree + * @param leavesData The data of one or more leaves to be used to create session data + * @returns The session data + */ + createSessionData = async ( + leavesData: CreateSessionDataParams[] + ): Promise<CreateSessionDataResponse> => { + return this.sessionKeyManagerModule.createSessionData(leavesData) + } + + /** + * This method is used to sign the user operation using the session signer + * @param userOp The user operation to be signed + * @param sessionParams Information about all the sessions to be used to sign the user operation which has a batch execution + * @returns The signature of the user operation + */ + async signUserOpHash(userOpHash: string, params?: ModuleInfo): Promise<Hex> { + const sessionParams = params?.batchSessionParams + if (!sessionParams || sessionParams.length === 0) { + throw new Error("Session parameters are not provided") + } + + const sessionDataTupleArray: SessionDataTuple[] = [] + + // signer must be the same for all the sessions + const { signer: sessionSigner } = await convertSigner( + sessionParams[0].sessionSigner, + false + ) + + const signature = await sessionSigner.signMessage({ + raw: toBytes(userOpHash) + }) + + for (const sessionParam of sessionParams) { + if (!sessionParam.sessionSigner) { + throw new Error("Session signer is not provided.") + } + if (!sessionParam.sessionID && !sessionParam.sessionValidationModule) { + throw new Error( + "sessionID or sessionValidationModule should be provided." + ) + } + + const sessionSignerData = + await this.sessionKeyManagerModule.sessionStorageClient.getSessionData( + sessionParam.sessionID + ? { + sessionID: sessionParam.sessionID + } + : { + sessionValidationModule: sessionParam.sessionValidationModule, + sessionPublicKey: await sessionSigner.getAddress() + } + ) + + const leafDataHex = concat([ + pad(toHex(sessionSignerData.validUntil), { size: 6 }), + pad(toHex(sessionSignerData.validAfter), { size: 6 }), + pad(sessionSignerData.sessionValidationModule, { size: 20 }), + sessionSignerData.sessionKeyData + ]) + + const proof = this.sessionKeyManagerModule.merkleTree.getHexProof( + keccak256(leafDataHex) + ) + + const sessionDataTuple: SessionDataTuple = [ + sessionSignerData.validUntil, + sessionSignerData.validAfter, + sessionSignerData.sessionValidationModule, + sessionSignerData.sessionKeyData, + proof, + sessionParam.additionalSessionData ?? "0x" + ] + + sessionDataTupleArray.push(sessionDataTuple) + } + + // Generate the padded signature + const abiParameters = [ + { type: "address" }, + { + type: "tuple[]", + components: [ + { type: "uint48" }, + { type: "uint48" }, + { type: "address" }, + { type: "bytes" }, + { type: "bytes32[]" }, + { type: "bytes" } + ] + }, + { type: "bytes" } + ] + + const paddedSignature = encodeAbiParameters(abiParameters, [ + this.getSessionKeyManagerAddress(), + sessionDataTupleArray, + signature + ]) + + return paddedSignature as Hex + } + + /** + * Update the session data pending state to active + * @param param The search param to find the session data + * @param status The status to be updated + * @returns + */ + async updateSessionStatus( + param: SessionSearchParam, + status: SessionStatus + ): Promise<void> { + this.sessionKeyManagerModule.sessionStorageClient.updateSessionStatus( + param, + status + ) + } + + /** + * @remarks This method is used to clear all the pending sessions + * @returns + */ + async clearPendingSessions(): Promise<void> { + this.sessionKeyManagerModule.sessionStorageClient.clearPendingSessions() + } + + /** + * @returns SessionKeyManagerModule address + */ + getAddress(): Hex { + return this.moduleAddress + } + + /** + * @returns SessionKeyManagerModule address + */ + getSessionKeyManagerAddress(): Hex { + return this.sessionManagerModuleAddress + } + + /** + * @remarks This is the version of the module contract + */ + async getSigner(): Promise<SmartAccountSigner> { + throw new Error("Method not implemented.") + } + + /** + * @remarks This is the dummy signature for the module, used in buildUserOp for bundler estimation + * @returns Dummy signature + */ + async getDummySignature(params?: ModuleInfo): Promise<Hex> { + const sessionParams = params?.batchSessionParams + if (!sessionParams || sessionParams.length === 0) { + throw new Error("Session parameters are not provided") + } + + const sessionDataTupleArray: SessionDataTuple[] = [] + + // if needed we could do mock signature over userOpHashAndModuleAddress + + // signer must be the same for all the sessions + const { signer: sessionSigner } = await convertSigner( + sessionParams[0].sessionSigner, + false + ) + + for (const sessionParam of sessionParams) { + if (!sessionParam.sessionSigner) { + throw new Error("Session signer is not provided.") + } + + if (!sessionParam.sessionID && !sessionParam.sessionValidationModule) { + throw new Error( + "sessionID or sessionValidationModule should be provided." + ) + } + + const sessionSignerData = + await this.sessionKeyManagerModule.sessionStorageClient.getSessionData( + sessionParam.sessionID + ? { + sessionID: sessionParam.sessionID + } + : { + sessionValidationModule: sessionParam.sessionValidationModule, + sessionPublicKey: await sessionSigner.getAddress() + } + ) + + const leafDataHex = concat([ + pad(toHex(sessionSignerData.validUntil), { size: 6 }), + pad(toHex(sessionSignerData.validAfter), { size: 6 }), + pad(sessionSignerData.sessionValidationModule, { size: 20 }), + sessionSignerData.sessionKeyData + ]) + + const proof = this.sessionKeyManagerModule.merkleTree.getHexProof( + keccak256(leafDataHex) + ) + + const sessionDataTuple: SessionDataTuple = [ + BigInt(sessionSignerData.validUntil), + BigInt(sessionSignerData.validAfter), + sessionSignerData.sessionValidationModule, + sessionSignerData.sessionKeyData, + proof, + sessionParam.additionalSessionData ?? "0x" + ] + + sessionDataTupleArray.push(sessionDataTuple) + } + + // Generate the padded signature + + const abiParameters = [ + { type: "address" }, + { + type: "tuple[]", + components: [ + { type: "uint48" }, + { type: "uint48" }, + { type: "address" }, + { type: "bytes" }, + { type: "bytes32[]" }, + { type: "bytes" } + ] + }, + { type: "bytes" } + ] + + const paddedSignature = encodeAbiParameters(abiParameters, [ + this.getSessionKeyManagerAddress(), + sessionDataTupleArray, + this.mockEcdsaSessionKeySig + ]) + + const dummySig = encodeAbiParameters(parseAbiParameters("bytes, address"), [ + paddedSignature as Hex, + this.getAddress() + ]) + return dummySig + } + + /** + * @remarks Other modules may need additional attributes to build init data + */ + async getInitData(): Promise<Hex> { + throw new Error("Method not implemented.") + } + + /** + * @remarks This Module dont have knowledge of signer. So, this method is not implemented + */ + async signMessage(_message: Uint8Array | string): Promise<string> { + throw new Error("Method not implemented.") + } +} diff --git a/packages/modules/src/ECDSAOwnershipValidationModule.ts b/src/modules/ECDSAOwnershipValidationModule.ts similarity index 55% rename from packages/modules/src/ECDSAOwnershipValidationModule.ts rename to src/modules/ECDSAOwnershipValidationModule.ts index 32cfc9af2..0d472c3e6 100644 --- a/packages/modules/src/ECDSAOwnershipValidationModule.ts +++ b/src/modules/ECDSAOwnershipValidationModule.ts @@ -1,75 +1,96 @@ -import { Hex, encodeFunctionData, getAddress, parseAbi, toBytes } from "viem"; -import { SmartAccountSigner } from "@alchemy/aa-core"; -import { ECDSAOwnershipValidationModuleConfig, ECDSAOwnershipValidationModuleConfigConstructorProps, ModuleVersion } from "./utils/Types.js"; -import { DEFAULT_ECDSA_OWNERSHIP_MODULE, ECDSA_OWNERSHIP_MODULE_ADDRESSES_BY_VERSION } from "./utils/Constants.js"; -import { convertSigner } from "@biconomy/common"; -import { BaseValidationModule } from "./BaseValidationModule.js"; +import { + type Hex, + encodeFunctionData, + getAddress, + parseAbi, + toBytes +} from "viem" +import { type SmartAccountSigner, convertSigner } from "../account" +import { BaseValidationModule } from "./BaseValidationModule.js" +import { + DEFAULT_ECDSA_OWNERSHIP_MODULE, + ECDSA_OWNERSHIP_MODULE_ADDRESSES_BY_VERSION +} from "./utils/Constants.js" +import type { + ECDSAOwnershipValidationModuleConfig, + ECDSAOwnershipValidationModuleConfigConstructorProps, + ModuleVersion +} from "./utils/Types.js" // Could be renamed with suffix API export class ECDSAOwnershipValidationModule extends BaseValidationModule { - signer: SmartAccountSigner; + signer: SmartAccountSigner - moduleAddress!: Hex; + moduleAddress!: Hex - version: ModuleVersion = "V1_0_0"; + version: ModuleVersion = "V1_0_0" - private constructor(moduleConfig: ECDSAOwnershipValidationModuleConfigConstructorProps) { - super(moduleConfig); - this.signer = moduleConfig.signer; + private constructor( + moduleConfig: ECDSAOwnershipValidationModuleConfigConstructorProps + ) { + super(moduleConfig) + this.signer = moduleConfig.signer } - public static async create(moduleConfig: ECDSAOwnershipValidationModuleConfig): Promise<ECDSAOwnershipValidationModule> { + public static async create( + moduleConfig: ECDSAOwnershipValidationModuleConfig + ): Promise<ECDSAOwnershipValidationModule> { // Signer needs to be initialised here before defaultValidationModule is set - const { signer } = await convertSigner(moduleConfig.signer, false); - const configForConstructor: ECDSAOwnershipValidationModuleConfigConstructorProps = { ...moduleConfig, signer }; + const { signer } = await convertSigner(moduleConfig.signer, false) + const configForConstructor: ECDSAOwnershipValidationModuleConfigConstructorProps = + { ...moduleConfig, signer } // TODO: (Joe) stop doing things in a 'create' call after the instance has been created - const instance = new ECDSAOwnershipValidationModule(configForConstructor); + const instance = new ECDSAOwnershipValidationModule(configForConstructor) if (moduleConfig.moduleAddress) { - instance.moduleAddress = moduleConfig.moduleAddress; + instance.moduleAddress = moduleConfig.moduleAddress } else if (moduleConfig.version) { - const moduleAddr = ECDSA_OWNERSHIP_MODULE_ADDRESSES_BY_VERSION[moduleConfig.version] as Hex; + const moduleAddr = ECDSA_OWNERSHIP_MODULE_ADDRESSES_BY_VERSION[ + moduleConfig.version + ] as Hex if (!moduleAddr) { - throw new Error(`Invalid version ${moduleConfig.version}`); + throw new Error(`Invalid version ${moduleConfig.version}`) } - instance.moduleAddress = moduleAddr; - instance.version = moduleConfig.version as ModuleVersion; + instance.moduleAddress = moduleAddr + instance.version = moduleConfig.version as ModuleVersion } else { - instance.moduleAddress = DEFAULT_ECDSA_OWNERSHIP_MODULE; + instance.moduleAddress = DEFAULT_ECDSA_OWNERSHIP_MODULE // Note: in this case Version remains the default one } - return instance; + return instance } getAddress(): Hex { - return this.moduleAddress; + return this.moduleAddress } async getSigner(): Promise<SmartAccountSigner> { - return Promise.resolve(this.signer); + return Promise.resolve(this.signer) } async getDummySignature(): Promise<Hex> { - const moduleAddress = getAddress(this.getAddress()); - const dynamicPart = moduleAddress.substring(2).padEnd(40, "0"); - return `0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000${dynamicPart}000000000000000000000000000000000000000000000000000000000000004181d4b4981670cb18f99f0b4a66446df1bf5b204d24cfcb659bf38ba27a4359b5711649ec2423c5e1247245eba2964679b6a1dbb85c992ae40b9b00c6935b02ff1b00000000000000000000000000000000000000000000000000000000000000`; + const moduleAddress = getAddress(this.getAddress()) + const dynamicPart = moduleAddress.substring(2).padEnd(40, "0") + return `0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000${dynamicPart}000000000000000000000000000000000000000000000000000000000000004181d4b4981670cb18f99f0b4a66446df1bf5b204d24cfcb659bf38ba27a4359b5711649ec2423c5e1247245eba2964679b6a1dbb85c992ae40b9b00c6935b02ff1b00000000000000000000000000000000000000000000000000000000000000` } // Note: other modules may need additional attributes to build init data async getInitData(): Promise<Hex> { - const ecdsaOwnerAddress = await this.signer.getAddress(); - const moduleRegistryParsedAbi = parseAbi(["function initForSmartAccount(address owner)"]); + const ecdsaOwnerAddress = await this.signer.getAddress() + const moduleRegistryParsedAbi = parseAbi([ + "function initForSmartAccount(address owner)" + ]) const ecdsaOwnershipInitData = encodeFunctionData({ abi: moduleRegistryParsedAbi, functionName: "initForSmartAccount", - args: [ecdsaOwnerAddress], - }); - return ecdsaOwnershipInitData; + args: [ecdsaOwnerAddress] + }) + return ecdsaOwnershipInitData } async signUserOpHash(userOpHash: string): Promise<Hex> { - const sig = await this.signer.signMessage({ raw: toBytes(userOpHash) }); - return sig; + const sig = await this.signer.signMessage({ raw: toBytes(userOpHash) }) + return sig } /** @@ -80,14 +101,14 @@ export class ECDSAOwnershipValidationModule extends BaseValidationModule { * @throws {Error} If the signer type is invalid or unsupported. */ async signMessage(_message: Uint8Array | string): Promise<string> { - const message = typeof _message === "string" ? _message : { raw: _message }; - let signature = await this.signer.signMessage(message); + const message = typeof _message === "string" ? _message : { raw: _message } + let signature = await this.signer.signMessage(message) - const potentiallyIncorrectV = parseInt(signature.slice(-2), 16); + const potentiallyIncorrectV = Number.parseInt(signature.slice(-2), 16) if (![27, 28].includes(potentiallyIncorrectV)) { - const correctV = potentiallyIncorrectV + 27; - signature = signature.slice(0, -2) + correctV.toString(16); + const correctV = potentiallyIncorrectV + 27 + signature = signature.slice(0, -2) + correctV.toString(16) } - return signature; + return signature } } diff --git a/src/modules/MultichainValidationModule.ts b/src/modules/MultichainValidationModule.ts new file mode 100644 index 000000000..1affc9c6f --- /dev/null +++ b/src/modules/MultichainValidationModule.ts @@ -0,0 +1,212 @@ +import { MerkleTree } from "merkletreejs" +import { + type Hex, + concat, + encodeAbiParameters, + encodeFunctionData, + getAddress, + keccak256, + pad, + parseAbi, + parseAbiParameters, + toBytes, + toHex +} from "viem" +import { + Logger, + type SmartAccountSigner, + type UserOperationStruct, + convertSigner +} from "../account" +import { BaseValidationModule } from "./BaseValidationModule.js" +import { + DEFAULT_MULTICHAIN_MODULE, + MULTICHAIN_VALIDATION_MODULE_ADDRESSES_BY_VERSION +} from "./utils/Constants.js" +import { getUserOpHash } from "./utils/Helper.js" +import type { + ModuleVersion, + MultiChainUserOpDto, + MultiChainValidationModuleConfig, + MultiChainValidationModuleConfigConstructorProps +} from "./utils/Types.js" + +export class MultiChainValidationModule extends BaseValidationModule { + signer: SmartAccountSigner + + moduleAddress!: Hex + + version: ModuleVersion = "V1_0_0" + + private constructor( + moduleConfig: MultiChainValidationModuleConfigConstructorProps + ) { + super(moduleConfig) + this.signer = moduleConfig.signer + } + + public static async create( + moduleConfig: MultiChainValidationModuleConfig + ): Promise<MultiChainValidationModule> { + // Signer needs to be initialised here before defaultValidationModule is set + const { signer } = await convertSigner(moduleConfig.signer, false) + const configForConstructor: MultiChainValidationModuleConfigConstructorProps = + { ...moduleConfig, signer } + + // TODO: (Joe) stop doing things in a 'create' call after the instance has been created + const instance = new MultiChainValidationModule(configForConstructor) + if (moduleConfig.moduleAddress) { + instance.moduleAddress = moduleConfig.moduleAddress + } else if (moduleConfig.version) { + const moduleAddr = MULTICHAIN_VALIDATION_MODULE_ADDRESSES_BY_VERSION[ + moduleConfig.version + ] as Hex + if (!moduleAddr) { + throw new Error(`Invalid version ${moduleConfig.version}`) + } + instance.moduleAddress = moduleAddr + instance.version = moduleConfig.version as ModuleVersion + } else { + instance.moduleAddress = DEFAULT_MULTICHAIN_MODULE + // Note: in this case Version remains the default one + } + return instance + } + + getAddress(): Hex { + return this.moduleAddress + } + + async getSigner(): Promise<SmartAccountSigner> { + return Promise.resolve(this.signer) + } + + async getDummySignature(): Promise<Hex> { + const moduleAddress = getAddress(this.getAddress()) + const dynamicPart = moduleAddress.substring(2).padEnd(40, "0") + return `0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000${dynamicPart}000000000000000000000000000000000000000000000000000000000000004181d4b4981670cb18f99f0b4a66446df1bf5b204d24cfcb659bf38ba27a4359b5711649ec2423c5e1247245eba2964679b6a1dbb85c992ae40b9b00c6935b02ff1b00000000000000000000000000000000000000000000000000000000000000` + } + + // Note: other modules may need additional attributes to build init data + async getInitData(): Promise<Hex> { + const ecdsaOwnerAddress = await this.signer.getAddress() + const moduleRegistryParsedAbi = parseAbi([ + "function initForSmartAccount(address owner)" + ]) + const ecdsaOwnershipInitData = encodeFunctionData({ + abi: moduleRegistryParsedAbi, + functionName: "initForSmartAccount", + args: [ecdsaOwnerAddress] + }) + return ecdsaOwnershipInitData + } + + async signUserOpHash(userOpHash: string): Promise<Hex> { + const sig = await this.signer.signMessage({ raw: toBytes(userOpHash) }) + return sig + } + + /** + * Signs a message using the appropriate method based on the type of signer. + * + * @param {Uint8Array | string} message - The message to be signed. + * @returns {Promise<string>} A promise resolving to the signature or error message. + * @throws {Error} If the signer type is invalid or unsupported. + */ + async signMessage(_message: Uint8Array | string): Promise<string> { + const message = typeof _message === "string" ? _message : { raw: _message } + let signature = await this.signer.signMessage(message) + + const potentiallyIncorrectV = Number.parseInt(signature.slice(-2), 16) + if (![27, 28].includes(potentiallyIncorrectV)) { + const correctV = potentiallyIncorrectV + 27 + signature = signature.slice(0, -2) + correctV.toString(16) + } + return signature + } + + async signUserOps( + multiChainUserOps: MultiChainUserOpDto[] + ): Promise<UserOperationStruct[]> { + try { + const leaves: string[] = [] + + // Iterate over each userOp and process them + for (const multiChainOp of multiChainUserOps) { + const validUntil = multiChainOp.validUntil ?? 0 + const validAfter = multiChainOp.validAfter ?? 0 + const leaf = concat([ + pad(toHex(validUntil), { size: 6 }), + pad(toHex(validAfter), { size: 6 }), + pad( + getUserOpHash( + multiChainOp.userOp, + this.entryPointAddress, + multiChainOp.chainId + ), + { size: 32 } + ) + ]) + + leaves.push(keccak256(leaf)) + } + + // Create a new Merkle tree using the leaves array + const merkleTree = new MerkleTree(leaves, keccak256, { sortPairs: true }) + + let multichainSignature = await this.signer.signMessage({ + raw: toBytes(merkleTree.getHexRoot()) + }) + + const potentiallyIncorrectV = Number.parseInt( + multichainSignature.slice(-2), + 16 + ) + if (![27, 28].includes(potentiallyIncorrectV)) { + const correctV = potentiallyIncorrectV + 27 + multichainSignature = + multichainSignature.slice(0, -2) + correctV.toString(16) + } + + // Create an array to store updated userOps + const updatedUserOps: UserOperationStruct[] = [] + + for (let i = 0; i < leaves.length; i++) { + const merkleProof = merkleTree.getHexProof(leaves[i]) + + const validUntil = multiChainUserOps[i].validUntil ?? 0 + const validAfter = multiChainUserOps[i].validAfter ?? 0 + + // Create the moduleSignature + const moduleSignature = encodeAbiParameters( + parseAbiParameters(["uint48, uint48, bytes32, bytes32[], bytes"]), + [ + validUntil, + validAfter, + merkleTree.getHexRoot() as Hex, + merkleProof as Hex[], + multichainSignature as Hex + ] + ) + + // Note: Because accountV2 does not directly call this method. hence we need to add validation module address to the signature + const signatureWithModuleAddress = encodeAbiParameters( + parseAbiParameters(["bytes, address"]), + [moduleSignature, this.getAddress()] + ) + + // Update userOp with the final signature + const updatedUserOp: UserOperationStruct = { + ...(multiChainUserOps[i].userOp as UserOperationStruct), + signature: signatureWithModuleAddress as `0x${string}` + } + + updatedUserOps.push(updatedUserOp) + } + return updatedUserOps + } catch (error) { + Logger.error("Error in signing multi chain userops") + throw new Error(JSON.stringify(error)) + } + } +} diff --git a/packages/modules/src/PasskeyValidationModule.ts b/src/modules/PasskeyValidationModule.ts similarity index 100% rename from packages/modules/src/PasskeyValidationModule.ts rename to src/modules/PasskeyValidationModule.ts diff --git a/packages/modules/src/SessionKeyManagerModule.ts b/src/modules/SessionKeyManagerModule.ts similarity index 54% rename from packages/modules/src/SessionKeyManagerModule.ts rename to src/modules/SessionKeyManagerModule.ts index 560c9ac60..c325c4dd5 100644 --- a/packages/modules/src/SessionKeyManagerModule.ts +++ b/src/modules/SessionKeyManagerModule.ts @@ -1,32 +1,50 @@ -import { Hex, concat, encodeAbiParameters, encodeFunctionData, keccak256, pad, parseAbi, parseAbiParameters, toBytes, toHex } from "viem"; -import { MerkleTree } from "merkletreejs"; -import { SmartAccountSigner } from "@alchemy/aa-core"; +import { MerkleTree } from "merkletreejs" import { - SessionKeyManagerModuleConfig, - ModuleVersion, - CreateSessionDataParams, - ModuleInfo, - CreateSessionDataResponse, - StorageType, -} from "./utils/Types.js"; -import { SESSION_MANAGER_MODULE_ADDRESSES_BY_VERSION, DEFAULT_SESSION_KEY_MANAGER_MODULE } from "./utils/Constants.js"; -import { generateRandomHex } from "./utils/Uid.js"; -import { BaseValidationModule } from "./BaseValidationModule.js"; -import { SessionLocalStorage } from "./session-storage/SessionLocalStorage.js"; -import { ISessionStorage, SessionLeafNode, SessionSearchParam, SessionStatus } from "./interfaces/ISessionStorage.js"; -import { convertSigner } from "@biconomy/common"; + type Hex, + concat, + encodeAbiParameters, + encodeFunctionData, + keccak256, + pad, + parseAbi, + parseAbiParameters, + toBytes, + toHex +} from "viem" +import { type SmartAccountSigner, convertSigner } from "../account" +import { BaseValidationModule } from "./BaseValidationModule.js" +import type { + ISessionStorage, + SessionLeafNode, + SessionSearchParam, + SessionStatus +} from "./interfaces/ISessionStorage.js" +import { SessionLocalStorage } from "./session-storage/SessionLocalStorage.js" +import { + DEFAULT_SESSION_KEY_MANAGER_MODULE, + SESSION_MANAGER_MODULE_ADDRESSES_BY_VERSION +} from "./utils/Constants.js" +import { + type CreateSessionDataParams, + type CreateSessionDataResponse, + type ModuleInfo, + type ModuleVersion, + type SessionKeyManagerModuleConfig, + StorageType +} from "./utils/Types.js" +import { generateRandomHex } from "./utils/Uid.js" export class SessionKeyManagerModule extends BaseValidationModule { - version: ModuleVersion = "V1_0_0"; + version: ModuleVersion = "V1_0_0" - moduleAddress!: Hex; + moduleAddress!: Hex - merkleTree!: MerkleTree; + merkleTree!: MerkleTree - sessionStorageClient!: ISessionStorage; + sessionStorageClient!: ISessionStorage readonly mockEcdsaSessionKeySig: Hex = - "0x73c3ac716c487ca34bb858247b5ccf1dc354fbaabdd089af3b2ac8e78ba85a4959a2d76250325bd67c11771c31fccda87c33ceec17cc0de912690521bb95ffcb1b"; + "0x73c3ac716c487ca34bb858247b5ccf1dc354fbaabdd089af3b2ac8e78ba85a4959a2d76250325bd67c11771c31fccda87c33ceec17cc0de912690521bb95ffcb1b" /** * This constructor is private. Use the static create method to instantiate SessionKeyManagerModule @@ -34,7 +52,7 @@ export class SessionKeyManagerModule extends BaseValidationModule { * @returns An instance of SessionKeyManagerModule */ private constructor(moduleConfig: SessionKeyManagerModuleConfig) { - super(moduleConfig); + super(moduleConfig) } /** @@ -42,53 +60,62 @@ export class SessionKeyManagerModule extends BaseValidationModule { * @param moduleConfig The configuration for the module * @returns A Promise that resolves to an instance of SessionKeyManagerModule */ - public static async create(moduleConfig: SessionKeyManagerModuleConfig): Promise<SessionKeyManagerModule> { + public static async create( + moduleConfig: SessionKeyManagerModuleConfig + ): Promise<SessionKeyManagerModule> { // TODO: (Joe) stop doing things in a 'create' call after the instance has been created - const instance = new SessionKeyManagerModule(moduleConfig); + const instance = new SessionKeyManagerModule(moduleConfig) if (moduleConfig.moduleAddress) { - instance.moduleAddress = moduleConfig.moduleAddress; + instance.moduleAddress = moduleConfig.moduleAddress } else if (moduleConfig.version) { - const moduleAddr = SESSION_MANAGER_MODULE_ADDRESSES_BY_VERSION[moduleConfig.version] as Hex; + const moduleAddr = SESSION_MANAGER_MODULE_ADDRESSES_BY_VERSION[ + moduleConfig.version + ] as Hex if (!moduleAddr) { - throw new Error(`Invalid version ${moduleConfig.version}`); + throw new Error(`Invalid version ${moduleConfig.version}`) } - instance.moduleAddress = moduleAddr; - instance.version = moduleConfig.version as ModuleVersion; + instance.moduleAddress = moduleAddr + instance.version = moduleConfig.version as ModuleVersion } else { - instance.moduleAddress = DEFAULT_SESSION_KEY_MANAGER_MODULE; + instance.moduleAddress = DEFAULT_SESSION_KEY_MANAGER_MODULE // Note: in this case Version remains the default one } if (moduleConfig.sessionStorageClient) { - instance.sessionStorageClient = moduleConfig.sessionStorageClient; + instance.sessionStorageClient = moduleConfig.sessionStorageClient } else { switch (moduleConfig.storageType) { case StorageType.LOCAL_STORAGE: - instance.sessionStorageClient = new SessionLocalStorage(moduleConfig.smartAccountAddress); - break; + instance.sessionStorageClient = new SessionLocalStorage( + moduleConfig.smartAccountAddress + ) + break default: - instance.sessionStorageClient = new SessionLocalStorage(moduleConfig.smartAccountAddress); + instance.sessionStorageClient = new SessionLocalStorage( + moduleConfig.smartAccountAddress + ) } } - const existingSessionData = await instance.sessionStorageClient.getAllSessionData(); + const existingSessionData = + await instance.sessionStorageClient.getAllSessionData() const existingSessionDataLeafs = existingSessionData.map((sessionData) => { const leafDataHex = concat([ pad(toHex(sessionData.validUntil), { size: 6 }), pad(toHex(sessionData.validAfter), { size: 6 }), pad(sessionData.sessionValidationModule, { size: 20 }), - sessionData.sessionKeyData, - ]); - return keccak256(leafDataHex); - }); + sessionData.sessionKeyData + ]) + return keccak256(leafDataHex) + }) instance.merkleTree = new MerkleTree(existingSessionDataLeafs, keccak256, { sortPairs: true, - hashLeaves: false, - }); + hashLeaves: false + }) - return instance; + return instance } /** @@ -96,58 +123,63 @@ export class SessionKeyManagerModule extends BaseValidationModule { * @param leavesData The data of one or more leaves to be used to create session data * @returns The session data */ - createSessionData = async (leavesData: CreateSessionDataParams[]): Promise<CreateSessionDataResponse> => { - const sessionKeyManagerModuleABI = parseAbi(["function setMerkleRoot(bytes32 _merkleRoot)"]); + createSessionData = async ( + leavesData: CreateSessionDataParams[] + ): Promise<CreateSessionDataResponse> => { + const sessionKeyManagerModuleABI = parseAbi([ + "function setMerkleRoot(bytes32 _merkleRoot)" + ]) - const leavesToAdd: Buffer[] = []; - const sessionIDInfo: string[] = []; + const leavesToAdd: Buffer[] = [] + const sessionIDInfo: string[] = [] for (const leafData of leavesData) { const leafDataHex = concat([ pad(toHex(leafData.validUntil), { size: 6 }), pad(toHex(leafData.validAfter), { size: 6 }), pad(leafData.sessionValidationModule, { size: 20 }), - leafData.sessionKeyData, - ]); + leafData.sessionKeyData + ]) - const generatedSessionId = leafData.preferredSessionId ?? generateRandomHex(); + const generatedSessionId = + leafData.preferredSessionId ?? generateRandomHex() // TODO: verify this, might not be buffer - leavesToAdd.push(keccak256(leafDataHex) as unknown as Buffer); - sessionIDInfo.push(generatedSessionId); + leavesToAdd.push(keccak256(leafDataHex) as unknown as Buffer) + sessionIDInfo.push(generatedSessionId) const sessionLeafNode = { ...leafData, sessionID: generatedSessionId, - status: "PENDING" as SessionStatus, - }; + status: "PENDING" as SessionStatus + } - await this.sessionStorageClient.addSessionData(sessionLeafNode); + await this.sessionStorageClient.addSessionData(sessionLeafNode) } - this.merkleTree.addLeaves(leavesToAdd); + this.merkleTree.addLeaves(leavesToAdd) - const leaves = this.merkleTree.getLeaves(); + const leaves = this.merkleTree.getLeaves() const newMerkleTree = new MerkleTree(leaves, keccak256, { sortPairs: true, - hashLeaves: false, - }); + hashLeaves: false + }) - this.merkleTree = newMerkleTree; + this.merkleTree = newMerkleTree const setMerkleRootData = encodeFunctionData({ abi: sessionKeyManagerModuleABI, functionName: "setMerkleRoot", - args: [this.merkleTree.getHexRoot() as Hex], - }); + args: [this.merkleTree.getHexRoot() as Hex] + }) - await this.sessionStorageClient.setMerkleRoot(this.merkleTree.getHexRoot()); + await this.sessionStorageClient.setMerkleRoot(this.merkleTree.getHexRoot()) return { data: setMerkleRootData, - sessionIDInfo: sessionIDInfo, - }; - }; + sessionIDInfo: sessionIDInfo + } + } /** * This method is used to sign the user operation using the session signer @@ -156,60 +188,74 @@ export class SessionKeyManagerModule extends BaseValidationModule { * @returns The signature of the user operation */ async signUserOpHash(userOpHash: string, params?: ModuleInfo): Promise<Hex> { - if (!(params && params.sessionSigner)) { - throw new Error("Session signer is not provided."); + if (!params?.sessionSigner) { + throw new Error("Session signer is not provided.") } - const { signer: sessionSigner } = await convertSigner(params.sessionSigner, false); + const { signer: sessionSigner } = await convertSigner( + params.sessionSigner, + false + ) // Use the sessionSigner to sign the user operation - const signature = await sessionSigner.signMessage({ raw: toBytes(userOpHash) }); + const signature = await sessionSigner.signMessage({ + raw: toBytes(userOpHash) + }) - const sessionSignerData = await this.getLeafInfo(params); + const sessionSignerData = await this.getLeafInfo(params) const leafDataHex = concat([ pad(toHex(sessionSignerData.validUntil), { size: 6 }), pad(toHex(sessionSignerData.validAfter), { size: 6 }), pad(sessionSignerData.sessionValidationModule, { size: 20 }), - sessionSignerData.sessionKeyData, - ]); + sessionSignerData.sessionKeyData + ]) // Generate the padded signature with (validUntil,validAfter,sessionVerificationModuleAddress,validationData,merkleProof,signature) - let paddedSignature: Hex = encodeAbiParameters(parseAbiParameters("uint48, uint48, address, bytes, bytes32[], bytes"), [ - sessionSignerData.validUntil, - sessionSignerData.validAfter, - sessionSignerData.sessionValidationModule, - sessionSignerData.sessionKeyData, - this.merkleTree.getHexProof(keccak256(leafDataHex)) as Hex[], - signature, - ]); + let paddedSignature: Hex = encodeAbiParameters( + parseAbiParameters("uint48, uint48, address, bytes, bytes32[], bytes"), + [ + sessionSignerData.validUntil, + sessionSignerData.validAfter, + sessionSignerData.sessionValidationModule, + sessionSignerData.sessionKeyData, + this.merkleTree.getHexProof(keccak256(leafDataHex)) as Hex[], + signature + ] + ) if (params?.additionalSessionData) { - paddedSignature += params.additionalSessionData; + paddedSignature += params.additionalSessionData } - return paddedSignature as Hex; + return paddedSignature as Hex } private async getLeafInfo(params: ModuleInfo): Promise<SessionLeafNode> { - if (!(params && params.sessionSigner)) { - throw new Error("Session signer is not provided."); + if (!params?.sessionSigner) { + throw new Error("Session signer is not provided.") } - const { signer: sessionSigner } = await convertSigner(params.sessionSigner, false); - let sessionSignerData; + const { signer: sessionSigner } = await convertSigner( + params.sessionSigner, + false + ) + // biome-ignore lint/suspicious/noImplicitAnyLet: <explanation> + let sessionSignerData if (params?.sessionID) { sessionSignerData = await this.sessionStorageClient.getSessionData({ - sessionID: params.sessionID, - }); + sessionID: params.sessionID + }) } else if (params?.sessionValidationModule) { sessionSignerData = await this.sessionStorageClient.getSessionData({ sessionValidationModule: params.sessionValidationModule, - sessionPublicKey: await sessionSigner.getAddress(), - }); + sessionPublicKey: await sessionSigner.getAddress() + }) } else { - throw new Error("sessionID or sessionValidationModule should be provided."); + throw new Error( + "sessionID or sessionValidationModule should be provided." + ) } - return sessionSignerData; + return sessionSignerData } /** @@ -218,8 +264,11 @@ export class SessionKeyManagerModule extends BaseValidationModule { * @param status The status to be updated * @returns */ - async updateSessionStatus(param: SessionSearchParam, status: SessionStatus): Promise<void> { - this.sessionStorageClient.updateSessionStatus(param, status); + async updateSessionStatus( + param: SessionSearchParam, + status: SessionStatus + ): Promise<void> { + this.sessionStorageClient.updateSessionStatus(param, status) } /** @@ -227,21 +276,21 @@ export class SessionKeyManagerModule extends BaseValidationModule { * @returns */ async clearPendingSessions(): Promise<void> { - this.sessionStorageClient.clearPendingSessions(); + this.sessionStorageClient.clearPendingSessions() } /** * @returns SessionKeyManagerModule address */ getAddress(): Hex { - return this.moduleAddress; + return this.moduleAddress } /** * @remarks This is the version of the module contract */ async getSigner(): Promise<SmartAccountSigner> { - throw new Error("Method not implemented."); + throw new Error("Method not implemented.") } /** @@ -250,45 +299,51 @@ export class SessionKeyManagerModule extends BaseValidationModule { */ async getDummySignature(params?: ModuleInfo): Promise<Hex> { if (!params) { - throw new Error("Session signer is not provided."); + throw new Error("Session signer is not provided.") } - const sessionSignerData = await this.getLeafInfo(params); + const sessionSignerData = await this.getLeafInfo(params) const leafDataHex = concat([ pad(toHex(sessionSignerData.validUntil), { size: 6 }), pad(toHex(sessionSignerData.validAfter), { size: 6 }), pad(sessionSignerData.sessionValidationModule, { size: 20 }), - sessionSignerData.sessionKeyData, - ]); + sessionSignerData.sessionKeyData + ]) // Generate the padded signature with (validUntil,validAfter,sessionVerificationModuleAddress,validationData,merkleProof,signature) - let paddedSignature: Hex = encodeAbiParameters(parseAbiParameters("uint48, uint48, address, bytes, bytes32[], bytes"), [ - sessionSignerData.validUntil, - sessionSignerData.validAfter, - sessionSignerData.sessionValidationModule, - sessionSignerData.sessionKeyData, - this.merkleTree.getHexProof(keccak256(leafDataHex)) as Hex[], - this.mockEcdsaSessionKeySig, - ]); + let paddedSignature: Hex = encodeAbiParameters( + parseAbiParameters("uint48, uint48, address, bytes, bytes32[], bytes"), + [ + sessionSignerData.validUntil, + sessionSignerData.validAfter, + sessionSignerData.sessionValidationModule, + sessionSignerData.sessionKeyData, + this.merkleTree.getHexProof(keccak256(leafDataHex)) as Hex[], + this.mockEcdsaSessionKeySig + ] + ) if (params?.additionalSessionData) { - paddedSignature += params.additionalSessionData; + paddedSignature += params.additionalSessionData } - const dummySig = encodeAbiParameters(parseAbiParameters(["bytes, address"]), [paddedSignature as Hex, this.getAddress()]); + const dummySig = encodeAbiParameters( + parseAbiParameters(["bytes, address"]), + [paddedSignature as Hex, this.getAddress()] + ) - return dummySig; + return dummySig } /** * @remarks Other modules may need additional attributes to build init data */ async getInitData(): Promise<Hex> { - throw new Error("Method not implemented."); + throw new Error("Method not implemented.") } /** * @remarks This Module dont have knowledge of signer. So, this method is not implemented */ async signMessage(_message: Uint8Array | string): Promise<string> { - throw new Error("Method not implemented."); + throw new Error("Method not implemented.") } } diff --git a/src/modules/index.ts b/src/modules/index.ts new file mode 100644 index 000000000..bf655585f --- /dev/null +++ b/src/modules/index.ts @@ -0,0 +1,31 @@ +export * from "./utils/Types.js" +export * from "./utils/Constants.js" +export * from "./utils/Helper.js" +export * from "./interfaces/IValidationModule.js" +export * from "./interfaces/ISessionValidationModule.js" +export * from "./BaseValidationModule.js" +export * from "./ECDSAOwnershipValidationModule.js" +export * from "./MultichainValidationModule.js" +export * from "./SessionKeyManagerModule.js" +export * from "./BatchedSessionRouterModule.js" +export * from "./session-validation-modules/ERC20SessionValidationModule.js" + +import { + BatchedSessionRouterModule, + ECDSAOwnershipValidationModule, + ERC20SessionValidationModule, + MultiChainValidationModule, + SessionKeyManagerModule +} from "./index.js" + +export const createBatchedSessionRouterModule = + BatchedSessionRouterModule.create +export const createMultiChainValidationModule = + MultiChainValidationModule.create +export const createECDSAOwnershipValidationModule = + ECDSAOwnershipValidationModule.create +export const createSessionKeyManagerModule = SessionKeyManagerModule.create +export const createERC20SessionValidationModule = + ERC20SessionValidationModule.create + +// export * from './PasskeyValidationModule' diff --git a/packages/modules/src/interfaces/ISessionStorage.ts b/src/modules/interfaces/ISessionStorage.ts similarity index 71% rename from packages/modules/src/interfaces/ISessionStorage.ts rename to src/modules/interfaces/ISessionStorage.ts index 41505fb1d..6372b77e3 100644 --- a/packages/modules/src/interfaces/ISessionStorage.ts +++ b/src/modules/interfaces/ISessionStorage.ts @@ -1,85 +1,88 @@ -import { Hex } from "viem"; -import { SmartAccountSigner } from "@alchemy/aa-core"; -import { SignerData } from "../utils/Types.js"; +import type { Hex } from "viem" +import type { SmartAccountSigner } from "../../account" +import type { SignerData } from "../utils/Types.js" -export type SessionStatus = "PENDING" | "ACTIVE" | "INACTIVE" | "EXPIRED"; +export type SessionStatus = "PENDING" | "ACTIVE" | "INACTIVE" | "EXPIRED" export type SessionLeafNode = { - validUntil: number; - validAfter: number; - sessionValidationModule: Hex; - sessionKeyData: Hex; - sessionPublicKey: Hex; - sessionID?: string; - status: SessionStatus; -}; + validUntil: number + validAfter: number + sessionValidationModule: Hex + sessionKeyData: Hex + sessionPublicKey: Hex + sessionID?: string + status: SessionStatus +} export type SessionSearchParam = { - sessionID?: string; - sessionPublicKey?: Hex; - sessionValidationModule?: Hex; - status?: SessionStatus; -}; + sessionID?: string + sessionPublicKey?: Hex + sessionValidationModule?: Hex + status?: SessionStatus +} export interface ISessionStorage { /** * Adds a session leaf node to the session storage * @param leaf SessionLeafNode to be added to the session storage */ - addSessionData(_leaf: SessionLeafNode): Promise<void>; + addSessionData(_leaf: SessionLeafNode): Promise<void> /** * Fetch a session leaf node from the session storage * @param param SessionSearchParam to be used to fetch the session leaf node */ - getSessionData(_param: SessionSearchParam): Promise<SessionLeafNode>; + getSessionData(_param: SessionSearchParam): Promise<SessionLeafNode> /** * Updates the session status of a session leaf node in the session storage * @param param SessionSearchParam to be used to fetch the session leaf node * @param status New session status to be updated */ - updateSessionStatus(_param: SessionSearchParam, _status: SessionStatus): Promise<void>; + updateSessionStatus( + _param: SessionSearchParam, + _status: SessionStatus + ): Promise<void> /** * Clears all the pending sessions from the session storage */ - clearPendingSessions(): Promise<void>; + clearPendingSessions(): Promise<void> /** * If a signer object is passed, it will be added to the session storage * If no signer object is passed, it'll create a random signer and add it to the session storage * @param signer Optional signer to be added to the session storage */ - addSigner(_signer?: SignerData): Promise<SmartAccountSigner>; + addSigner(_signer?: SignerData): Promise<SmartAccountSigner> /** * Fetch a signer from the session storage * @param signerPublicKey Public key of the signer to be fetched */ - getSignerByKey(_signerPublicKey: string): Promise<SmartAccountSigner>; + getSignerByKey(_signerPublicKey: string): Promise<SmartAccountSigner> /** * Fetch a signer from the session storage based on the session search param * @param param SessionSearchParam to be used to fetch the signer */ - getSignerBySession(_param: SessionSearchParam): Promise<SmartAccountSigner>; + getSignerBySession(_param: SessionSearchParam): Promise<SmartAccountSigner> /** * Fetch all the session leaf nodes from the session storage based on the session search param. * If no param is passed, it'll fetch all the session leaf nodes from the session storage * @param param SessionSearchParam to be used to fetch the session leaf nodes */ - getAllSessionData(_param?: SessionSearchParam): Promise<SessionLeafNode[]>; + getAllSessionData(_param?: SessionSearchParam): Promise<SessionLeafNode[]> /** * Fetch merkle root from the session storage */ - getMerkleRoot(): Promise<string>; + getMerkleRoot(): Promise<string> /** * Set merkle root in the session storage * @param merkleRoot Merkle root to be set in the session storage */ - setMerkleRoot(_merkleRoot: string): Promise<void>; + setMerkleRoot(_merkleRoot: string): Promise<void> } diff --git a/packages/modules/src/interfaces/ISessionValidationModule.ts b/src/modules/interfaces/ISessionValidationModule.ts similarity index 84% rename from packages/modules/src/interfaces/ISessionValidationModule.ts rename to src/modules/interfaces/ISessionValidationModule.ts index ee1c3abef..d0e8f5be8 100644 --- a/packages/modules/src/interfaces/ISessionValidationModule.ts +++ b/src/modules/interfaces/ISessionValidationModule.ts @@ -9,6 +9,6 @@ * @author Sachin Tomar <sachin.tomar@biconomy.io> */ export interface ISessionValidationModule<T> { - getSessionKeyData(_sessionData: T): Promise<string>; - getAddress(): string; + getSessionKeyData(_sessionData: T): Promise<string> + getAddress(): string } diff --git a/src/modules/interfaces/IValidationModule.ts b/src/modules/interfaces/IValidationModule.ts new file mode 100644 index 000000000..a6bedc379 --- /dev/null +++ b/src/modules/interfaces/IValidationModule.ts @@ -0,0 +1,11 @@ +import type { Hex } from "viem" +import type { SmartAccountSigner } from "../../account" + +export interface IValidationModule { + getAddress(): Hex + getInitData(): Promise<Hex> + getSigner(): Promise<SmartAccountSigner> + signUserOpHash(_userOpHash: string): Promise<Hex> + signMessage(_message: string | Uint8Array): Promise<string> + getDummySignature(): Promise<Hex> +} diff --git a/src/modules/session-storage/SessionFileStorage.ts b/src/modules/session-storage/SessionFileStorage.ts new file mode 100644 index 000000000..9dafc67ef --- /dev/null +++ b/src/modules/session-storage/SessionFileStorage.ts @@ -0,0 +1,273 @@ +import { http, type Hex, createWalletClient } from "viem" +import { generatePrivateKey, privateKeyToAccount } from "viem/accounts" +import { polygonMumbai } from "viem/chains" +import { + Logger, + type SmartAccountSigner, + WalletClientSigner, + getChain +} from "../../account" +import type { + ISessionStorage, + SessionLeafNode, + SessionSearchParam, + SessionStatus +} from "../interfaces/ISessionStorage" +import type { SignerData } from "../utils/Types" + +export class SessionFileStorage implements ISessionStorage { + private smartAccountAddress: string + + constructor(smartAccountAddress: string) { + this.smartAccountAddress = smartAccountAddress.toLowerCase() + } + + // This method reads data from the file and returns it in the JSON format + // biome-ignore lint/suspicious/noExplicitAny: <explanation> + private async readDataFromFile(type: "sessions" | "signers"): Promise<any> { + return new Promise((resolve) => { + // @ts-ignore + fs.readFile(this.getStorageFilePath(type), "utf8", (err, data) => { + if (err) { + // Handle errors appropriately + resolve(undefined) + } else { + if (!data) { + resolve(null) + } else { + resolve(JSON.parse(data)) + } + // resolve(JSON.parse(data)); + } + }) + }) + } + + private getStorageFilePath(type: "sessions" | "signers"): string { + return `${__dirname}/sessionStorageData/${this.smartAccountAddress}_${type}.json` + } + + private async writeDataToFile( + // biome-ignore lint/suspicious/noExplicitAny: <explanation> + data: any, + type: "sessions" | "signers" + ): Promise<void> { + console.log("") + return new Promise((resolve, reject) => { + const filePath = this.getStorageFilePath(type) + // @ts-ignore + fs.writeFile(filePath, JSON.stringify(data), "utf8", (err) => { + if (err) { + // Handle errors appropriately + console.log({ err }, JSON.stringify(data)) + reject(err) + } else { + resolve() + } + }) + }) + } + + private validateSearchParam(param: SessionSearchParam): void { + if (param.sessionID) { + return + } + if ( + !param.sessionID && + param.sessionPublicKey && + param.sessionValidationModule + ) { + return + } + throw new Error( + "Either pass sessionId or a combination of sessionPublicKey and sessionValidationModule address." + ) + } + + // Session store is in the form of mekrleRoot and leafnodes, each object will have a root and an array of leafNodes. + private async getSessionStore() { + try { + const data = await this.readDataFromFile("sessions") + return data || { merkleRoot: "", leafNodes: [] } + } catch (error) { + // Handle errors appropriately + console.log({ error }) + } + } + + private async getSignerStore() { + try { + const data = await this.readDataFromFile("signers") + return data || {} + } catch (error) { + console.log({ error }) + // Handle errors appropriately + } + } + + // private getStorageKey(type: "sessions" | "signers"): string { + // return `${this.smartAccountAddress}_${type}` + // } + + private toLowercaseAddress(address: string): Hex { + return address.toLowerCase() as Hex + } + + async getSessionData(param: SessionSearchParam): Promise<SessionLeafNode> { + const sessions = (await this.getSessionStore()).leafNodes + const session = sessions.find((s: SessionLeafNode) => { + if (param.sessionID) { + return ( + s.sessionID === param.sessionID && + (!param.status || s.status === param.status) + ) + } + if (param.sessionPublicKey && param.sessionValidationModule) { + return ( + s.sessionPublicKey === + this.toLowercaseAddress(param.sessionPublicKey) && + s.sessionValidationModule === + this.toLowercaseAddress(param.sessionValidationModule) && + (!param.status || s.status === param.status) + ) + } + return undefined + }) + + if (!session) { + throw new Error("Session not found.") + } + return session + } + + async addSessionData(leaf: SessionLeafNode): Promise<void> { + Logger.log("Add session Data") + const data = await this.getSessionStore() + leaf.sessionValidationModule = this.toLowercaseAddress( + leaf.sessionValidationModule + ) + leaf.sessionPublicKey = this.toLowercaseAddress(leaf.sessionPublicKey) + data.leafNodes.push(leaf) + await this.writeDataToFile(data, "sessions") // Use 'sessions' as the type + } + + async updateSessionStatus( + param: SessionSearchParam, + status: SessionStatus + ): Promise<void> { + this.validateSearchParam(param) + + const data = await this.getSessionStore() + const session = data.leafNodes.find((s: SessionLeafNode) => { + if (param.sessionID) { + return s.sessionID === param.sessionID + } + if (param.sessionPublicKey && param.sessionValidationModule) { + return ( + s.sessionPublicKey === + this.toLowercaseAddress(param.sessionPublicKey) && + s.sessionValidationModule === + this.toLowercaseAddress(param.sessionValidationModule) + ) + } + return undefined + }) + + if (!session) { + throw new Error("Session not found.") + } + + session.status = status + await this.writeDataToFile(data, "sessions") // Use 'sessions' as the type + } + + async clearPendingSessions(): Promise<void> { + const data = await this.getSessionStore() + data.leafNodes = data.leafNodes.filter( + (s: SessionLeafNode) => s.status !== "PENDING" + ) + await this.writeDataToFile(data, "sessions") // Use 'sessions' as the type + } + + async addSigner(signerData: SignerData): Promise<WalletClientSigner> { + const signers = await this.getSignerStore() + let signer: SignerData + if (!signerData) { + const pkey = generatePrivateKey() + signer = { + pvKey: pkey, + pbKey: privateKeyToAccount(pkey).publicKey + } + } else { + signer = signerData + } + const accountSigner = privateKeyToAccount(signer.pvKey) + const viemChain = getChain(signerData?.chainId?.id || 1) + const client = createWalletClient({ + account: accountSigner, + chain: signerData.chainId, + transport: http(viemChain.rpcUrls.default.http[0]) + }) + const walletClientSigner: SmartAccountSigner = new WalletClientSigner( + client, + "json-rpc" // signerType + ) + signers[this.toLowercaseAddress(accountSigner.address)] = { + pvKey: signer.pvKey, + pbKey: signer.pbKey + } + await this.writeDataToFile(signers, "signers") // Use 'signers' as the type + return walletClientSigner + } + + async getSignerByKey(sessionPublicKey: string): Promise<WalletClientSigner> { + const signers = await this.getSignerStore() + Logger.log("Got signers", signers) + + const signerData: SignerData = + signers[this.toLowercaseAddress(sessionPublicKey)] + + if (!signerData) { + throw new Error("Signer not found.") + } + Logger.log(signerData.pvKey, "PVKEY") + + const signer = privateKeyToAccount(signerData.pvKey) + const walletClient = createWalletClient({ + account: signer, + transport: http(polygonMumbai.rpcUrls.default.http[0]) + }) + return new WalletClientSigner(walletClient, "json-rpc") + } + + async getSignerBySession( + param: SessionSearchParam + ): Promise<WalletClientSigner> { + const session = await this.getSessionData(param) + Logger.log("got session") + const walletClientSinger = await this.getSignerByKey( + session.sessionPublicKey + ) + return walletClientSinger + } + + async getAllSessionData( + param?: SessionSearchParam + ): Promise<SessionLeafNode[]> { + const sessions = (await this.getSessionStore()).leafNodes + if (!param || !param.status) { + return sessions + } + return sessions.filter((s: SessionLeafNode) => s.status === param.status) + } + + async getMerkleRoot(): Promise<string> { + return (await this.getSessionStore()).merkleRoot + } + + async setMerkleRoot(merkleRoot: string): Promise<void> { + const data = await this.getSessionStore() + data.merkleRoot = merkleRoot + await this.writeDataToFile(data, "sessions") // Use 'sessions' as the type + } +} diff --git a/src/modules/session-storage/SessionLocalStorage.ts b/src/modules/session-storage/SessionLocalStorage.ts new file mode 100644 index 000000000..8501c2112 --- /dev/null +++ b/src/modules/session-storage/SessionLocalStorage.ts @@ -0,0 +1,207 @@ +import { http, type Hex, createWalletClient, toHex } from "viem" +import { generatePrivateKey, privateKeyToAccount } from "viem/accounts" +import { mainnet } from "viem/chains" +import { type SmartAccountSigner, WalletClientSigner } from "../../account" +import type { + ISessionStorage, + SessionLeafNode, + SessionSearchParam, + SessionStatus +} from "../interfaces/ISessionStorage.js" +import type { SignerData } from "../utils/Types.js" + +export class SessionLocalStorage implements ISessionStorage { + private smartAccountAddress: string + + constructor(smartAccountAddress: string) { + this.smartAccountAddress = smartAccountAddress.toLowerCase() + } + + private validateSearchParam(param: SessionSearchParam): void { + if ( + param.sessionID || + (!param.sessionID && + param.sessionPublicKey && + param.sessionValidationModule) + ) { + return + } + throw new Error( + "Either pass sessionId or a combination of sessionPublicKey and sessionValidationModule address." + ) + } + private getSessionStore() { + // @ts-ignore: LocalStorage is not available in node + const data = localStorage.getItem(this.getStorageKey("sessions")) + return data ? JSON.parse(data) : { merkleRoot: "", leafNodes: [] } + } + + private getSignerStore() { + // @ts-ignore: LocalStorage is not available in node + const data = localStorage.getItem(this.getStorageKey("signers")) + return data ? JSON.parse(data) : {} + } + + private getStorageKey(type: "sessions" | "signers"): string { + return `${this.smartAccountAddress}_${type}` + } + + private toLowercaseAddress(address: string): string { + return address.toLowerCase() + } + + async addSessionData(leaf: SessionLeafNode): Promise<void> { + const data = this.getSessionStore() + leaf.sessionValidationModule = this.toLowercaseAddress( + leaf.sessionValidationModule + ) as Hex + leaf.sessionPublicKey = this.toLowercaseAddress( + leaf.sessionPublicKey + ) as Hex + data.leafNodes.push(leaf) + // @ts-ignore: LocalStorage is not available in node + localStorage.setItem(this.getStorageKey("sessions"), JSON.stringify(data)) + } + + async getSessionData(param: SessionSearchParam): Promise<SessionLeafNode> { + this.validateSearchParam(param) + + const sessions = this.getSessionStore().leafNodes + const session = sessions.find((s: SessionLeafNode) => { + if (param.sessionID) { + return ( + s.sessionID === param.sessionID && + (!param.status || s.status === param.status) + ) + } + if (param.sessionPublicKey && param.sessionValidationModule) { + return ( + s.sessionPublicKey === + this.toLowercaseAddress(param.sessionPublicKey) && + s.sessionValidationModule === + this.toLowercaseAddress(param.sessionValidationModule) && + (!param.status || s.status === param.status) + ) + } + return undefined + }) + + if (!session) { + throw new Error("Session not found.") + } + return session + } + + async updateSessionStatus( + param: SessionSearchParam, + status: SessionStatus + ): Promise<void> { + this.validateSearchParam(param) + + const data = this.getSessionStore() + const session = data.leafNodes.find((s: SessionLeafNode) => { + if (param.sessionID) { + return s.sessionID === param.sessionID + } + if (param.sessionPublicKey && param.sessionValidationModule) { + return ( + s.sessionPublicKey === + this.toLowercaseAddress(param.sessionPublicKey) && + s.sessionValidationModule === + this.toLowercaseAddress(param.sessionValidationModule) + ) + } + return undefined + }) + + if (!session) { + throw new Error("Session not found.") + } + + session.status = status + // @ts-ignore: LocalStorage is not available in node + localStorage.setItem(this.getStorageKey("sessions"), JSON.stringify(data)) + } + + async clearPendingSessions(): Promise<void> { + const data = this.getSessionStore() + data.leafNodes = data.leafNodes.filter( + (s: SessionLeafNode) => s.status !== "PENDING" + ) + // @ts-ignore: LocalStorage is not available in node + localStorage.setItem(this.getStorageKey("sessions"), JSON.stringify(data)) + } + + async addSigner(signerData: SignerData): Promise<SmartAccountSigner> { + const signers = this.getSignerStore() + let signer: SignerData + if (!signerData) { + const pkey = generatePrivateKey() + signer = { + pvKey: pkey, + pbKey: privateKeyToAccount(pkey).publicKey + } + } else { + signer = signerData + } + const accountSigner = privateKeyToAccount(toHex(signer.pvKey)) + const client = createWalletClient({ + account: accountSigner, + chain: signerData.chainId, + transport: http() + }) + const walletClientSigner = new WalletClientSigner( + client, + "json-rpc" // signerType + ) + signers[this.toLowercaseAddress(accountSigner.address)] = signerData + // @ts-ignore: LocalStorage is not available in node + localStorage.setItem(this.getStorageKey("signers"), JSON.stringify(signers)) + return walletClientSigner + } + + async getSignerByKey(sessionPublicKey: string): Promise<SmartAccountSigner> { + const signers = this.getSignerStore() + const signerData = signers[this.toLowercaseAddress(sessionPublicKey)] + if (!signerData) { + throw new Error("Signer not found.") + } + const account = privateKeyToAccount(signerData.privateKey) + const client = createWalletClient({ + account, + chain: mainnet, + transport: http() + }) + const signer = new WalletClientSigner(client, "viem") + return signer + } + + async getSignerBySession( + param: SessionSearchParam + ): Promise<SmartAccountSigner> { + const session = await this.getSessionData(param) + return this.getSignerByKey(session.sessionPublicKey) + } + + async getAllSessionData( + param?: SessionSearchParam + ): Promise<SessionLeafNode[]> { + const sessions = this.getSessionStore().leafNodes + if (!param || !param.status) { + return sessions + } + return sessions.filter((s: SessionLeafNode) => s.status === param.status) + } + + async getMerkleRoot(): Promise<string> { + return this.getSessionStore().merkleRoot + } + + setMerkleRoot(merkleRoot: string): Promise<void> { + const data = this.getSessionStore() + data.merkleRoot = merkleRoot + // @ts-ignore: LocalStorage is not available in node + localStorage.setItem(this.getStorageKey("sessions"), JSON.stringify(data)) + return Promise.resolve() + } +} diff --git a/src/modules/session-storage/SessionMemoryStorage.ts b/src/modules/session-storage/SessionMemoryStorage.ts new file mode 100644 index 000000000..b046ee4fb --- /dev/null +++ b/src/modules/session-storage/SessionMemoryStorage.ts @@ -0,0 +1,219 @@ +import { http, type Hex, createWalletClient } from "viem" +import { generatePrivateKey, privateKeyToAccount } from "viem/accounts" +import { mainnet } from "viem/chains" +import { type SmartAccountSigner, WalletClientSigner } from "../../account" +import type { + ISessionStorage, + SessionLeafNode, + SessionSearchParam, + SessionStatus +} from "../interfaces/ISessionStorage.js" +import type { SignerData } from "../utils/Types.js" + +type MemoryStore = { + _store: Record<string, string> + getItem: (key: string) => string | undefined + setItem: (key: string, value: string) => void +} +const memoryStorage: MemoryStore = { + _store: {}, + getItem: (key: string): string => { + return memoryStorage._store[key] + }, + setItem: (key: string, value: string) => { + memoryStorage._store[key] = value + } +} + +export class SessionMemoryStorage implements ISessionStorage { + private smartAccountAddress: string + + constructor(smartAccountAddress: string) { + this.smartAccountAddress = smartAccountAddress.toLowerCase() + } + + private validateSearchParam(param: SessionSearchParam): void { + if ( + param.sessionID || + (!param.sessionID && + param.sessionPublicKey && + param.sessionValidationModule) + ) { + return + } + throw new Error( + "Either pass sessionId or a combination of sessionPublicKey and sessionValidationModule address." + ) + } + + private getSessionStore() { + const data = memoryStorage.getItem(this.getStorageKey("sessions")) + return data ? JSON.parse(data) : { merkleRoot: "", leafNodes: [] } + } + + private getSignerStore() { + const data = memoryStorage.getItem(this.getStorageKey("signers")) + return data ? JSON.parse(data) : {} + } + + private getStorageKey(type: "sessions" | "signers"): string { + return `${this.smartAccountAddress}_${type}` + } + + private toLowercaseAddress(address: string): string { + return address.toLowerCase() + } + + async addSessionData(leaf: SessionLeafNode): Promise<void> { + const data = this.getSessionStore() + leaf.sessionValidationModule = this.toLowercaseAddress( + leaf.sessionValidationModule + ) as Hex + leaf.sessionPublicKey = this.toLowercaseAddress( + leaf.sessionPublicKey + ) as Hex + data.leafNodes.push(leaf) + memoryStorage.setItem(this.getStorageKey("sessions"), JSON.stringify(data)) + } + + async getSessionData(param: SessionSearchParam): Promise<SessionLeafNode> { + this.validateSearchParam(param) + + const sessions = this.getSessionStore().leafNodes + const session = sessions.find((s: SessionLeafNode) => { + if (param.sessionID) { + return ( + s.sessionID === param.sessionID && + (!param.status || s.status === param.status) + ) + } + if (param.sessionPublicKey && param.sessionValidationModule) { + return ( + s.sessionPublicKey === + this.toLowercaseAddress(param.sessionPublicKey) && + s.sessionValidationModule === + this.toLowercaseAddress(param.sessionValidationModule) && + (!param.status || s.status === param.status) + ) + } + return undefined + }) + + if (!session) { + throw new Error("Session not found.") + } + return session + } + + async updateSessionStatus( + param: SessionSearchParam, + status: SessionStatus + ): Promise<void> { + this.validateSearchParam(param) + + const data = this.getSessionStore() + const session = data.leafNodes.find((s: SessionLeafNode) => { + if (param.sessionID) { + return s.sessionID === param.sessionID + } + if (param.sessionPublicKey && param.sessionValidationModule) { + return ( + s.sessionPublicKey === + this.toLowercaseAddress(param.sessionPublicKey) && + s.sessionValidationModule === + this.toLowercaseAddress(param.sessionValidationModule) + ) + } + return undefined + }) + + if (!session) { + throw new Error("Session not found.") + } + + session.status = status + memoryStorage.setItem(this.getStorageKey("sessions"), JSON.stringify(data)) + } + + async clearPendingSessions(): Promise<void> { + const data = this.getSessionStore() + data.leafNodes = data.leafNodes.filter( + (s: SessionLeafNode) => s.status !== "PENDING" + ) + memoryStorage.setItem(this.getStorageKey("sessions"), JSON.stringify(data)) + } + + async addSigner(signerData: SignerData): Promise<SmartAccountSigner> { + const signers = this.getSignerStore() + let signer: SignerData + if (!signerData) { + const pkey = generatePrivateKey() + signer = { + pvKey: pkey, + pbKey: privateKeyToAccount(pkey).publicKey + } + } else { + signer = signerData + } + const accountSigner = privateKeyToAccount(signer.pvKey) + const client = createWalletClient({ + account: accountSigner, + chain: signerData.chainId, + transport: http() + }) + const walletClientSigner = new WalletClientSigner( + client, + "json-rpc" // signerType + ) + signers[this.toLowercaseAddress(accountSigner.address)] = signerData + memoryStorage.setItem( + this.getStorageKey("signers"), + JSON.stringify(signers) + ) + return walletClientSigner + } + + async getSignerByKey(sessionPublicKey: string): Promise<SmartAccountSigner> { + const signers = this.getSignerStore() + const signerData = signers[this.toLowercaseAddress(sessionPublicKey)] + if (!signerData) { + throw new Error("Signer not found.") + } + const account = privateKeyToAccount(signerData.privateKey) + const client = createWalletClient({ + account, + chain: mainnet, + transport: http() + }) + const signer = new WalletClientSigner(client, "viem") + return signer + } + + async getSignerBySession( + param: SessionSearchParam + ): Promise<SmartAccountSigner> { + const session = await this.getSessionData(param) + return this.getSignerByKey(session.sessionPublicKey) + } + + async getAllSessionData( + param?: SessionSearchParam + ): Promise<SessionLeafNode[]> { + const sessions = this.getSessionStore().leafNodes + if (!param || !param.status) { + return sessions + } + return sessions.filter((s: SessionLeafNode) => s.status === param.status) + } + + async getMerkleRoot(): Promise<string> { + return this.getSessionStore().merkleRoot + } + + setMerkleRoot(merkleRoot: string): Promise<void> { + const data = this.getSessionStore() + data.merkleRoot = merkleRoot + memoryStorage.setItem(this.getStorageKey("sessions"), JSON.stringify(data)) + return Promise.resolve() + } +} diff --git a/packages/modules/src/session-validation-modules/ERC20SessionValidationModule.ts b/src/modules/session-validation-modules/ERC20SessionValidationModule.ts similarity index 54% rename from packages/modules/src/session-validation-modules/ERC20SessionValidationModule.ts rename to src/modules/session-validation-modules/ERC20SessionValidationModule.ts index 7791f1967..1e047cc6e 100644 --- a/packages/modules/src/session-validation-modules/ERC20SessionValidationModule.ts +++ b/src/modules/session-validation-modules/ERC20SessionValidationModule.ts @@ -1,6 +1,9 @@ -import { ISessionValidationModule } from "../interfaces/ISessionValidationModule.js"; -import { ERC20SessionKeyData, SessionValidationModuleConfig } from "../utils/Types.js"; -import { encodeAbiParameters, parseAbiParameters } from "viem"; +import { encodeAbiParameters, parseAbiParameters } from "viem" +import type { ISessionValidationModule } from "../interfaces/ISessionValidationModule.js" +import type { + ERC20SessionKeyData, + SessionValidationModuleConfig +} from "../utils/Types.js" /** * Session validation module for ERC20 token transfers. @@ -8,10 +11,12 @@ import { encodeAbiParameters, parseAbiParameters } from "viem"; * * @author Sachin Tomar <sachin.tomar@biconomy.io> */ -export class ERC20SessionValidationModule implements ISessionValidationModule<ERC20SessionKeyData> { - moduleAddress!: string; +export class ERC20SessionValidationModule + implements ISessionValidationModule<ERC20SessionKeyData> +{ + moduleAddress!: string - version = "V1_0_0"; + version = "V1_0_0" /** * This constructor is private. Use the static create method to instantiate ERC20SessionValidationModule @@ -20,9 +25,9 @@ export class ERC20SessionValidationModule implements ISessionValidationModule<ER */ private constructor(moduleConfig: SessionValidationModuleConfig) { if (!moduleConfig.moduleAddress) { - throw new Error("Module address is required"); + throw new Error("Module address is required") } - this.moduleAddress = moduleConfig.moduleAddress; + this.moduleAddress = moduleConfig.moduleAddress } /** @@ -30,41 +35,46 @@ export class ERC20SessionValidationModule implements ISessionValidationModule<ER * @param moduleConfig The configuration for the module * @returns A Promise that resolves to an instance of ERC20SessionValidationModule */ - public static async create(moduleConfig: SessionValidationModuleConfig): Promise<ERC20SessionValidationModule> { - const module = new ERC20SessionValidationModule(moduleConfig); - return module; + public static async create( + moduleConfig: SessionValidationModuleConfig + ): Promise<ERC20SessionValidationModule> { + const module = new ERC20SessionValidationModule(moduleConfig) + return module } async getSessionKeyData(sessionData: ERC20SessionKeyData): Promise<string> { - this._validateSessionKeyData(sessionData); - const sessionKeyData = encodeAbiParameters(parseAbiParameters("address, address, address, uint256"), [ - sessionData.sessionKey, - sessionData.token, - sessionData.recipient, - sessionData.maxAmount, - ]); - return sessionKeyData; + this._validateSessionKeyData(sessionData) + const sessionKeyData = encodeAbiParameters( + parseAbiParameters("address, address, address, uint256"), + [ + sessionData.sessionKey, + sessionData.token, + sessionData.recipient, + sessionData.maxAmount + ] + ) + return sessionKeyData } private _validateSessionKeyData(sessionData: ERC20SessionKeyData): void { if (!sessionData) { - throw new Error("Session data is required"); + throw new Error("Session data is required") } if (!sessionData.sessionKey) { - throw new Error("Session key is required in sessionData"); + throw new Error("Session key is required in sessionData") } if (!sessionData.token) { - throw new Error("Token address is required in sessionData"); + throw new Error("Token address is required in sessionData") } if (!sessionData.recipient) { - throw new Error("Recipient address is required in sessionData"); + throw new Error("Recipient address is required in sessionData") } if (!sessionData.maxAmount) { - throw new Error("MaxAmount is required in sessionData"); + throw new Error("MaxAmount is required in sessionData") } } getAddress(): string { - return this.moduleAddress; + return this.moduleAddress } } diff --git a/src/modules/utils/Constants.ts b/src/modules/utils/Constants.ts new file mode 100644 index 000000000..4c8c34192 --- /dev/null +++ b/src/modules/utils/Constants.ts @@ -0,0 +1,35 @@ +import type { ModuleVersion } from "./Types.js" + +export const DEFAULT_MODULE_VERSION: ModuleVersion = "V1_0_0" + +// Note: we could append these defaults with ADDRESS suffix +export const DEFAULT_ECDSA_OWNERSHIP_MODULE = + "0x0000001c5b32F37F5beA87BDD5374eB2aC54eA8e" + +export const ECDSA_OWNERSHIP_MODULE_ADDRESSES_BY_VERSION = { + V1_0_0: "0x0000001c5b32F37F5beA87BDD5374eB2aC54eA8e" +} + +export const DEFAULT_SESSION_KEY_MANAGER_MODULE = + "0x000002FbFfedd9B33F4E7156F2DE8D48945E7489" + +export const SESSION_MANAGER_MODULE_ADDRESSES_BY_VERSION = { + V1_0_0: "0x000000456b395c4e107e0302553B90D1eF4a32e9", + V1_0_1: "0x000002FbFfedd9B33F4E7156F2DE8D48945E7489" +} + +export const DEFAULT_BATCHED_SESSION_ROUTER_MODULE = + "0x00000D09967410f8C76752A104c9848b57ebba55" + +export const BATCHED_SESSION_ROUTER_MODULE_ADDRESSES_BY_VERSION = { + V1_0_0: "0x00000D09967410f8C76752A104c9848b57ebba55" +} + +export const DEFAULT_ERC20_MODULE = "0x000000D50C68705bd6897B2d17c7de32FB519fDA" + +export const DEFAULT_MULTICHAIN_MODULE = + "0x000000824dc138db84FD9109fc154bdad332Aa8E" + +export const MULTICHAIN_VALIDATION_MODULE_ADDRESSES_BY_VERSION = { + V1_0_0: "0x000000824dc138db84FD9109fc154bdad332Aa8E" +} diff --git a/src/modules/utils/Helper.ts b/src/modules/utils/Helper.ts new file mode 100644 index 000000000..aa125e759 --- /dev/null +++ b/src/modules/utils/Helper.ts @@ -0,0 +1,105 @@ +import { + type Hex, + concat, + encodeAbiParameters, + keccak256, + pad, + parseAbiParameters, + toHex +} from "viem" +import type { UserOperationStruct } from "../../account" + +export interface Rule { + offset: number + condition: number + referenceValue: `0x${string}` +} + +export interface Permission { + destContract: `0x${string}` + functionSelector: `0x${string}` + valueLimit: bigint + rules: Rule[] +} + +function packUserOp( + op: Partial<UserOperationStruct>, + forSignature = true +): string { + if (!op.initCode || !op.callData || !op.paymasterAndData) + throw new Error("Missing userOp properties") + if (forSignature) { + return encodeAbiParameters( + parseAbiParameters( + "address, uint256, bytes32, bytes32, uint256, uint256, uint256, uint256, uint256, bytes32" + ), + [ + op.sender as Hex, + BigInt(op.nonce as Hex), + keccak256(op.initCode as Hex), + keccak256(op.callData as Hex), + BigInt(op.callGasLimit as Hex), + BigInt(op.verificationGasLimit as Hex), + BigInt(op.preVerificationGas as Hex), + BigInt(op.maxFeePerGas as Hex), + BigInt(op.maxPriorityFeePerGas as Hex), + keccak256(op.paymasterAndData as Hex) + ] + ) + } + // for the purpose of calculating gas cost encode also signature (and no keccak of bytes) + return encodeAbiParameters( + parseAbiParameters( + "address, uint256, bytes, bytes, uint256, uint256, uint256, uint256, uint256, bytes, bytes" + ), + [ + op.sender as Hex, + BigInt(op.nonce as Hex), + op.initCode as Hex, + op.callData as Hex, + BigInt(op.callGasLimit as Hex), + BigInt(op.verificationGasLimit as Hex), + BigInt(op.preVerificationGas as Hex), + BigInt(op.maxFeePerGas as Hex), + BigInt(op.maxPriorityFeePerGas as Hex), + op.paymasterAndData as Hex, + op.signature as Hex + ] + ) +} + +export const getUserOpHash = ( + userOp: Partial<UserOperationStruct>, + entryPointAddress: Hex, + chainId: number +): Hex => { + const userOpHash = keccak256(packUserOp(userOp, true) as Hex) + const enc = encodeAbiParameters( + parseAbiParameters("bytes32, address, uint256"), + [userOpHash, entryPointAddress, BigInt(chainId)] + ) + return keccak256(enc) +} + +export async function getABISVMSessionKeyData( + sessionKey: `0x${string}` | Uint8Array, + permission: Permission +): Promise<`0x${string}` | Uint8Array> { + let sessionKeyData = concat([ + sessionKey, + permission.destContract, + permission.functionSelector, + pad(toHex(permission.valueLimit), { size: 16 }), + pad(toHex(permission.rules.length), { size: 2 }) // this can't be more 2**11 (see below), so uint16 (2 bytes) is enough + ]) as `0x${string}` + + for (let i = 0; i < permission.rules.length; i++) { + sessionKeyData = concat([ + sessionKeyData, + pad(toHex(permission.rules[i].offset), { size: 2 }), // offset is uint16, so there can't be more than 2**16/32 args = 2**11 + pad(toHex(permission.rules[i].condition), { size: 1 }), // uint8 + permission.rules[i].referenceValue + ]) + } + return sessionKeyData +} diff --git a/packages/modules/src/utils/Types.ts b/src/modules/utils/Types.ts similarity index 58% rename from packages/modules/src/utils/Types.ts rename to src/modules/utils/Types.ts index 68adf5194..26c0badcf 100644 --- a/packages/modules/src/utils/Types.ts +++ b/src/modules/utils/Types.ts @@ -1,160 +1,177 @@ -import { Chain, Hex } from "viem"; -import { SmartAccountSigner, UserOperationStruct } from "@alchemy/aa-core"; -import { SessionKeyManagerModule } from "../SessionKeyManagerModule.js"; -import { ISessionStorage } from "../interfaces/ISessionStorage.js"; -import { SupportedSigner } from "@biconomy/common"; -export type ModuleVersion = "V1_0_0"; // | 'V1_0_1' +import type { Chain, Hex } from "viem" +import type { + SimulationType, + SmartAccountSigner, + SupportedSigner, + UserOperationStruct +} from "../../account" +import type { SessionKeyManagerModule } from "../SessionKeyManagerModule.js" +import type { ISessionStorage } from "../interfaces/ISessionStorage.js" +export type ModuleVersion = "V1_0_0" // | 'V1_0_1' export interface BaseValidationModuleConfig { /** entryPointAddress: address of the entry point */ - entryPointAddress?: Hex; + entryPointAddress?: Hex } -export interface ECDSAOwnershipValidationModuleConfig extends BaseValidationModuleConfig { +export interface ECDSAOwnershipValidationModuleConfig + extends BaseValidationModuleConfig { /** Address of the module */ - moduleAddress?: Hex; + moduleAddress?: Hex /** Version of the module */ - version?: ModuleVersion; + version?: ModuleVersion /** Signer: viemWallet or ethers signer. Ingested when passed into smartAccount */ - signer: SupportedSigner; + signer: SupportedSigner } -export interface ECDSAOwnershipValidationModuleConfigConstructorProps extends BaseValidationModuleConfig { +export interface ECDSAOwnershipValidationModuleConfigConstructorProps + extends BaseValidationModuleConfig { /** Address of the module */ - moduleAddress?: Hex; + moduleAddress?: Hex /** Version of the module */ - version?: ModuleVersion; + version?: ModuleVersion /** Signer: Converted from viemWallet or ethers signer to SmartAccountSigner */ - signer: SmartAccountSigner; + signer: SmartAccountSigner } -export interface SessionKeyManagerModuleConfig extends BaseValidationModuleConfig { +export interface SessionKeyManagerModuleConfig + extends BaseValidationModuleConfig { /** Address of the module */ - moduleAddress?: Hex; + moduleAddress?: Hex /** Version of the module */ - version?: ModuleVersion; + version?: ModuleVersion /** SmartAccount address */ - smartAccountAddress: string; - storageType?: StorageType; - sessionStorageClient?: ISessionStorage; + smartAccountAddress: string + storageType?: StorageType + sessionStorageClient?: ISessionStorage } -export interface BatchedSessionRouterModuleConfig extends BaseValidationModuleConfig { +export interface BatchedSessionRouterModuleConfig + extends BaseValidationModuleConfig { /** Address of the module */ - moduleAddress?: Hex; + moduleAddress?: Hex /** Version of the module */ - version?: ModuleVersion; + version?: ModuleVersion /** Session Key Manager module: Could be BaseValidationModule */ - sessionKeyManagerModule?: SessionKeyManagerModule; + sessionKeyManagerModule?: SessionKeyManagerModule /** Session Key Manager module address */ - sessionManagerModuleAddress?: Hex; + sessionManagerModuleAddress?: Hex /** Address of the associated smart account */ - smartAccountAddress: string; + smartAccountAddress: string /** Storage type, e.g. local storage */ - storageType?: StorageType; + storageType?: StorageType } export enum StorageType { - LOCAL_STORAGE, + LOCAL_STORAGE = 0 } +export type SessionDataTuple = [ + bigint | number, + bigint | number, + Hex, + Hex, + string[], + string +] + export type SessionParams = { /** Redundant now as we've favoured uuid() */ - sessionID?: string; + sessionID?: string /** Session Signer: viemWallet or ethers signer. Ingested when passed into smartAccount */ - sessionSigner: SupportedSigner; + sessionSigner: SupportedSigner /** The session validation module is a sub-module smart-contract which works with session key manager validation module. It validates the userop calldata against the defined session permissions (session key data) within the contract. */ - sessionValidationModule?: Hex; + sessionValidationModule?: Hex /** Additional info if needed to be appended in signature */ - additionalSessionData?: string; -}; + additionalSessionData?: string +} export type ModuleInfo = { // Could be a full object of below params and that way it can be an array too! // sessionParams?: SessionParams[] // where SessionParams is below four - sessionID?: string; + sessionID?: string /** Session Signer: viemWallet or ethers signer. Ingested when passed into smartAccount */ - sessionSigner?: SupportedSigner; + sessionSigner?: SupportedSigner /** The session validation module is a sub-module smart-contract which works with session key manager validation module. It validates the userop calldata against the defined session permissions (session key data) within the contract. */ - sessionValidationModule?: Hex; + sessionValidationModule?: Hex /** Additional info if needed to be appended in signature */ - additionalSessionData?: string; - batchSessionParams?: SessionParams[]; -}; + additionalSessionData?: string + batchSessionParams?: SessionParams[] +} export interface SendUserOpParams extends ModuleInfo { /** "validation_and_execution" is recommended during development for improved debugging & devEx, but will add some additional latency to calls. "validation" can be used in production ro remove this latency once flows have been tested. */ - simulationType?: SimulationType; + simulationType?: SimulationType } -export type SimulationType = "validation" | "validation_and_execution"; - export type SignerData = { /** Public key */ - pbKey: string; + pbKey: string /** Private key */ - pvKey: `0x${string}`; + pvKey: `0x${string}` /** Network Id */ - chainId?: Chain; -}; + chainId?: Chain +} export type CreateSessionDataResponse = { - data: string; - sessionIDInfo: Array<string>; -}; + data: string + sessionIDInfo: Array<string> +} export interface CreateSessionDataParams { /** window end for the session key */ - validUntil: number; + validUntil: number /** window start for the session key */ - validAfter: number; - sessionValidationModule: Hex; - sessionPublicKey: Hex; - sessionKeyData: Hex; + validAfter: number + sessionValidationModule: Hex + sessionPublicKey: Hex + sessionKeyData: Hex /** we generate uuid based sessionId. but if you prefer to track it on your side and attach custom session identifier this can be passed */ - preferredSessionId?: string; + preferredSessionId?: string } -export interface MultiChainValidationModuleConfig extends BaseValidationModuleConfig { +export interface MultiChainValidationModuleConfig + extends BaseValidationModuleConfig { /** Address of the module */ - moduleAddress?: Hex; + moduleAddress?: Hex /** Version of the module */ - version?: ModuleVersion; + version?: ModuleVersion /** Signer: viemWallet or ethers signer. Ingested when passed into smartAccount */ - signer: SupportedSigner; + signer: SupportedSigner } -export interface MultiChainValidationModuleConfigConstructorProps extends BaseValidationModuleConfig { +export interface MultiChainValidationModuleConfigConstructorProps + extends BaseValidationModuleConfig { /** Address of the module */ - moduleAddress?: Hex; + moduleAddress?: Hex /** Version of the module */ - version?: ModuleVersion; + version?: ModuleVersion /** Signer: viemWallet or ethers signer. Ingested when passed into smartAccount */ - signer: SmartAccountSigner; + signer: SmartAccountSigner } export type MultiChainUserOpDto = { /** window end timestamp */ - validUntil?: number; + validUntil?: number /** window start timestamp */ - validAfter?: number; - chainId: number; - userOp: Partial<UserOperationStruct>; -}; + validAfter?: number + chainId: number + userOp: Partial<UserOperationStruct> +} export interface BaseSessionKeyData { - sessionKey: Hex; + sessionKey: Hex } export interface ERC20SessionKeyData extends BaseSessionKeyData { /** ERC20 token address */ - token: Hex; + token: Hex /** Recipient address */ - recipient: Hex; + recipient: Hex /** ERC20 amount (Bigint) */ - maxAmount: bigint; + maxAmount: bigint } export interface SessionValidationModuleConfig { /** Address of the module */ - moduleAddress: string; + moduleAddress: string } diff --git a/packages/modules/src/utils/Uid.ts b/src/modules/utils/Uid.ts similarity index 62% rename from packages/modules/src/utils/Uid.ts rename to src/modules/utils/Uid.ts index 5cf4a6cca..58080849d 100644 --- a/packages/modules/src/utils/Uid.ts +++ b/src/modules/utils/Uid.ts @@ -1,12 +1,12 @@ // small uid generator, hex: 0-9, a-f (10 chars) export const generateRandomHex = (): string => { - const hexChars = "0123456789abcdef"; - let result = ""; + const hexChars = "0123456789abcdef" + let result = "" for (let i = 0; i < 10; i++) { - const randomIndex = Math.floor(Math.random() * hexChars.length); - result += hexChars[randomIndex]; + const randomIndex = Math.floor(Math.random() * hexChars.length) + result += hexChars[randomIndex] } - return result; -}; + return result +} diff --git a/packages/paymaster/src/BiconomyPaymaster.ts b/src/paymaster/BiconomyPaymaster.ts similarity index 55% rename from packages/paymaster/src/BiconomyPaymaster.ts rename to src/paymaster/BiconomyPaymaster.ts index aa0af3f86..36e3e55ad 100644 --- a/packages/paymaster/src/BiconomyPaymaster.ts +++ b/src/paymaster/BiconomyPaymaster.ts @@ -1,39 +1,46 @@ -import { encodeFunctionData, parseAbi } from "viem"; -import type { BigNumberish, UserOperationStruct } from "@alchemy/aa-core"; +import { encodeFunctionData, parseAbi } from "viem" import { - PaymasterFeeQuote, - PaymasterConfig, - FeeQuotesOrDataResponse, - FeeQuotesOrDataDto, - SponsorUserOperationDto, - JsonRpcResponse, - BiconomyTokenPaymasterRequest, + type BiconomyTokenPaymasterRequest, + type BigNumberish, + HttpMethod, + Logger, + type Transaction, + type UserOperationStruct, + sendRequest +} from "../account" +import type { IHybridPaymaster } from "./interfaces/IHybridPaymaster.js" +import { ADDRESS_ZERO, ERC20_ABI, MAX_UINT256 } from "./utils/Constants.js" +import { getTimestampInSeconds } from "./utils/Helpers.js" +import { + type FeeQuotesOrDataDto, + type FeeQuotesOrDataResponse, + type Hex, + type JsonRpcResponse, + type PaymasterAndDataResponse, + type PaymasterConfig, + type PaymasterFeeQuote, PaymasterMode, - PaymasterAndDataResponse, - Transaction, - Hex, -} from "./utils/Types.js"; -import { IHybridPaymaster } from "./interfaces/IHybridPaymaster.js"; -import { MAX_UINT256, ERC20_ABI, ADDRESS_ZERO } from "./utils/Constants.js"; -import { sendRequest, HttpMethod, Logger } from "@biconomy/common"; -import { getTimestampInSeconds } from "./utils/Helpers.js"; + type SponsorUserOperationDto +} from "./utils/Types.js" const defaultPaymasterConfig: PaymasterConfig = { paymasterUrl: "", - strictMode: false, // Set your desired default value for strictMode here -}; + strictMode: false // Set your desired default value for strictMode here +} /** * @dev Hybrid - Generic Gas Abstraction paymaster */ -export class BiconomyPaymaster implements IHybridPaymaster<SponsorUserOperationDto> { - paymasterConfig: PaymasterConfig; +export class BiconomyPaymaster + implements IHybridPaymaster<SponsorUserOperationDto> +{ + paymasterConfig: PaymasterConfig constructor(config: PaymasterConfig) { const mergedConfig: PaymasterConfig = { ...defaultPaymasterConfig, - ...config, - }; - this.paymasterConfig = mergedConfig; + ...config + } + this.paymasterConfig = mergedConfig } /** @@ -41,27 +48,41 @@ export class BiconomyPaymaster implements IHybridPaymaster<SponsorUserOperationD * @param userOp The partial user operation. * @returns A Promise that resolves to the prepared partial user operation. */ - private async prepareUserOperation(userOp: Partial<UserOperationStruct>): Promise<Partial<UserOperationStruct>> { - const userOperation = { ...userOp }; + private async prepareUserOperation( + userOp: Partial<UserOperationStruct> + ): Promise<Partial<UserOperationStruct>> { + const userOperation = { ...userOp } try { - const keys1: (keyof UserOperationStruct)[] = ["nonce", "maxFeePerGas", "maxPriorityFeePerGas"]; + const keys1: (keyof UserOperationStruct)[] = [ + "nonce", + "maxFeePerGas", + "maxPriorityFeePerGas" + ] for (const key of keys1) { if (userOperation[key] && userOperation[key] !== "0x") { - userOperation[key] = ("0x" + BigInt(userOp[key] as BigNumberish).toString(16)) as `0x${string}`; + userOperation[key] = `0x${BigInt( + userOp[key] as BigNumberish + ).toString(16)}` as `0x${string}` } } - const keys2: (keyof UserOperationStruct)[] = ["callGasLimit", "verificationGasLimit", "preVerificationGas"]; + const keys2: (keyof UserOperationStruct)[] = [ + "callGasLimit", + "verificationGasLimit", + "preVerificationGas" + ] for (const key of keys2) { if (userOperation[key] && userOperation[key] !== "0x") { - userOperation[key] = BigInt(userOp[key] as BigNumberish).toString() as `0x${string}`; + userOperation[key] = BigInt( + userOp[key] as BigNumberish + ).toString() as `0x${string}` } } } catch (error) { - throw `Failed to transform user operation: ${error}`; + throw `Failed to transform user operation: ${error}` } - userOperation.signature = userOp.signature || "0x"; - userOperation.paymasterAndData = userOp.paymasterAndData || "0x"; - return userOperation; + userOperation.signature = userOp.signature || "0x" + userOperation.paymasterAndData = userOp.paymasterAndData || "0x" + return userOperation } /** @@ -70,10 +91,12 @@ export class BiconomyPaymaster implements IHybridPaymaster<SponsorUserOperationD * @param provider Optional provider object. * @returns A Promise that resolves to the built transaction object. */ - async buildTokenApprovalTransaction(tokenPaymasterRequest: BiconomyTokenPaymasterRequest): Promise<Transaction> { - const feeTokenAddress: string = tokenPaymasterRequest.feeQuote.tokenAddress; + async buildTokenApprovalTransaction( + tokenPaymasterRequest: BiconomyTokenPaymasterRequest + ): Promise<Transaction> { + const feeTokenAddress: string = tokenPaymasterRequest.feeQuote.tokenAddress - const spender = tokenPaymasterRequest.spender; + const spender = tokenPaymasterRequest.spender // logging provider object isProvider // Logger.log("provider object passed - is provider", provider?._isProvider); @@ -82,21 +105,29 @@ export class BiconomyPaymaster implements IHybridPaymaster<SponsorUserOperationD // Note: should also check in caller if the approval is already given, if yes return object with address or data 0 // Note: we would need userOp here to get the account/owner info to check allowance - let requiredApproval = BigInt(0); + let requiredApproval = BigInt(0) - if (tokenPaymasterRequest.maxApproval && tokenPaymasterRequest.maxApproval == true) { - requiredApproval = BigInt(MAX_UINT256); + if ( + tokenPaymasterRequest.maxApproval && + tokenPaymasterRequest.maxApproval === true + ) { + requiredApproval = BigInt(MAX_UINT256) } else { - requiredApproval = BigInt(Math.ceil(tokenPaymasterRequest.feeQuote.maxGasFee * Math.pow(10, tokenPaymasterRequest.feeQuote.decimal))); + requiredApproval = BigInt( + Math.ceil( + tokenPaymasterRequest.feeQuote.maxGasFee * + 10 ** tokenPaymasterRequest.feeQuote.decimal + ) + ) } try { - const parsedAbi = parseAbi(ERC20_ABI); + const parsedAbi = parseAbi(ERC20_ABI) const data = encodeFunctionData({ abi: parsedAbi, functionName: "approve", - args: [spender, requiredApproval], - }); + args: [spender, requiredApproval] + }) // TODO? // Note: For some tokens we may need to set allowance to 0 first so that would return batch of transactions and changes the return type to Transaction[] @@ -114,10 +145,10 @@ export class BiconomyPaymaster implements IHybridPaymaster<SponsorUserOperationD return { to: feeTokenAddress, value: "0x00", - data: data, - }; + data: data + } } catch (error) { - throw new Error("Failed to encode function data"); + throw new Error("Failed to encode function data") } } @@ -128,39 +159,46 @@ export class BiconomyPaymaster implements IHybridPaymaster<SponsorUserOperationD * @returns A Promise that resolves to the fee quotes or data response. */ async getPaymasterFeeQuotesOrData( - userOp: Partial<UserOperationStruct>, - paymasterServiceData: FeeQuotesOrDataDto, + _userOp: Partial<UserOperationStruct>, + paymasterServiceData: FeeQuotesOrDataDto ): Promise<FeeQuotesOrDataResponse> { - userOp = await this.prepareUserOperation(userOp); + const userOp = await this.prepareUserOperation(_userOp) - let mode = null; - let expiryDuration = null; - const calculateGasLimits = paymasterServiceData.calculateGasLimits ?? true; - let preferredToken = null; - let feeTokensArray: string[] = []; + let mode: PaymasterMode | null = null + let expiryDuration: number | null = null + const calculateGasLimits = paymasterServiceData.calculateGasLimits ?? true + let preferredToken: string | null = null + let feeTokensArray: string[] = [] // could make below null let smartAccountInfo = { name: "BICONOMY", - version: "2.0.0", - }; - let webhookData = null; + version: "2.0.0" + } + let webhookData: Record<string, any> | null = null if (paymasterServiceData.mode) { - mode = paymasterServiceData.mode; + mode = paymasterServiceData.mode // Validation on the mode passed / define allowed enums } if (paymasterServiceData.expiryDuration) { - expiryDuration = paymasterServiceData.expiryDuration; + expiryDuration = paymasterServiceData.expiryDuration } - preferredToken = paymasterServiceData?.preferredToken ? paymasterServiceData?.preferredToken : preferredToken; + preferredToken = paymasterServiceData?.preferredToken + ? paymasterServiceData?.preferredToken + : preferredToken - feeTokensArray = (paymasterServiceData?.tokenList?.length !== 0 ? paymasterServiceData?.tokenList : feeTokensArray) as string[]; + feeTokensArray = ( + paymasterServiceData?.tokenList?.length !== 0 + ? paymasterServiceData?.tokenList + : feeTokensArray + ) as string[] - webhookData = paymasterServiceData?.webhookData ?? webhookData; + webhookData = paymasterServiceData?.webhookData ?? webhookData - smartAccountInfo = paymasterServiceData?.smartAccountInfo ?? smartAccountInfo; + smartAccountInfo = + paymasterServiceData?.smartAccountInfo ?? smartAccountInfo try { const response: JsonRpcResponse = await sendRequest( @@ -177,67 +215,78 @@ export class BiconomyPaymaster implements IHybridPaymaster<SponsorUserOperationD ...(expiryDuration !== null && { expiryDuration }), tokenInfo: { tokenList: feeTokensArray, - ...(preferredToken !== null && { preferredToken }), + ...(preferredToken !== null && { preferredToken }) }, sponsorshipInfo: { ...(webhookData !== null && { webhookData }), - smartAccountInfo: smartAccountInfo, - }, - }, + smartAccountInfo: smartAccountInfo + } + } ], // As per current API id: getTimestampInSeconds(), - jsonrpc: "2.0", - }, + jsonrpc: "2.0" + } }, - "Paymaster", - ); - - if (response && response.result) { - if (response.result.mode == PaymasterMode.ERC20) { - const feeQuotesResponse: Array<PaymasterFeeQuote> = response.result.feeQuotes; - const paymasterAddress: Hex = response.result.paymasterAddress; + "Paymaster" + ) + + if (response?.result) { + if (response.result.mode === PaymasterMode.ERC20) { + const feeQuotesResponse: Array<PaymasterFeeQuote> = + response.result.feeQuotes + const paymasterAddress: Hex = response.result.paymasterAddress // check all objects iterate and populate below calculation for all tokens - return { feeQuotes: feeQuotesResponse, tokenPaymasterAddress: paymasterAddress }; - } else if (response.result.mode == PaymasterMode.SPONSORED) { - const paymasterAndData: Hex = response.result.paymasterAndData; - const preVerificationGas = response.result.preVerificationGas; - const verificationGasLimit = response.result.verificationGasLimit; - const callGasLimit = response.result.callGasLimit; + return { + feeQuotes: feeQuotesResponse, + tokenPaymasterAddress: paymasterAddress + } + } + if (response.result.mode === PaymasterMode.SPONSORED) { + const paymasterAndData: Hex = response.result.paymasterAndData + const preVerificationGas = response.result.preVerificationGas + const verificationGasLimit = response.result.verificationGasLimit + const callGasLimit = response.result.callGasLimit return { paymasterAndData: paymasterAndData, preVerificationGas: preVerificationGas, verificationGasLimit: verificationGasLimit, - callGasLimit: callGasLimit, - }; - } else { - const errorObject = { - code: 417, - message: "Expectation Failed: Invalid mode in Paymaster service response", - }; - throw errorObject; + callGasLimit: callGasLimit + } } + const errorObject = { + code: 417, + message: + "Expectation Failed: Invalid mode in Paymaster service response" + } + throw errorObject } } catch (error: any) { - Logger.error("Failed to fetch Fee Quotes or Paymaster data - reason: ", JSON.stringify(error)); + Logger.error( + "Failed to fetch Fee Quotes or Paymaster data - reason: ", + JSON.stringify(error) + ) // Note: we may not throw if we include strictMode off and return paymasterData '0x'. if ( !this.paymasterConfig.strictMode && - paymasterServiceData.mode == PaymasterMode.SPONSORED && - (error?.message.includes("Smart contract data not found") || error?.message.includes("No policies were set")) + paymasterServiceData.mode === PaymasterMode.SPONSORED && + (error?.message.includes("Smart contract data not found") || + error?.message.includes("No policies were set")) // can also check based on error.code being -32xxx ) { - Logger.warn(`Strict mode is ${this.paymasterConfig.strictMode}. sending paymasterAndData 0x`); + Logger.warn( + `Strict mode is ${this.paymasterConfig.strictMode}. sending paymasterAndData 0x` + ) return { paymasterAndData: "0x", // send below values same as userOp gasLimits preVerificationGas: userOp.preVerificationGas, verificationGasLimit: userOp.verificationGasLimit, - callGasLimit: userOp.callGasLimit, - }; + callGasLimit: userOp.callGasLimit + } } - throw error; + throw error } - throw new Error("Failed to fetch feeQuote or paymaster data"); + throw new Error("Failed to fetch feeQuote or paymaster data") } /** @@ -247,40 +296,44 @@ export class BiconomyPaymaster implements IHybridPaymaster<SponsorUserOperationD * @returns A Promise that resolves to the paymaster and data string. */ async getPaymasterAndData( - userOp: Partial<UserOperationStruct>, - paymasterServiceData?: SponsorUserOperationDto, // mode is necessary. partial context of token paymaster or verifying + _userOp: Partial<UserOperationStruct>, + paymasterServiceData?: SponsorUserOperationDto // mode is necessary. partial context of token paymaster or verifying ): Promise<PaymasterAndDataResponse> { - userOp = await this.prepareUserOperation(userOp); + const userOp = await this.prepareUserOperation(_userOp) if (paymasterServiceData?.mode === undefined) { - throw new Error("mode is required in paymasterServiceData"); + throw new Error("mode is required in paymasterServiceData") } - const mode = paymasterServiceData.mode; + const mode = paymasterServiceData.mode - const calculateGasLimits = paymasterServiceData.calculateGasLimits ?? true; + const calculateGasLimits = paymasterServiceData.calculateGasLimits ?? true - let tokenInfo = null; - let expiryDuration = null; + let tokenInfo: Record<string, string | undefined> | null = null // could make below null let smartAccountInfo = { name: "BICONOMY", - version: "2.0.0", - }; - let webhookData = null; + version: "2.0.0" + } + let webhookData: Record<string, any> | null = null + let expiryDuration: number | null = null if (mode === PaymasterMode.ERC20) { - if (!paymasterServiceData?.feeTokenAddress && paymasterServiceData?.feeTokenAddress === ADDRESS_ZERO) { - throw new Error("feeTokenAddress is required and should be non-zero"); + if ( + !paymasterServiceData?.feeTokenAddress && + paymasterServiceData?.feeTokenAddress === ADDRESS_ZERO + ) { + throw new Error("feeTokenAddress is required and should be non-zero") } tokenInfo = { - feeTokenAddress: paymasterServiceData.feeTokenAddress, - }; + feeTokenAddress: paymasterServiceData.feeTokenAddress + } } - webhookData = paymasterServiceData?.webhookData ?? webhookData; - smartAccountInfo = paymasterServiceData?.smartAccountInfo ?? smartAccountInfo; - expiryDuration = paymasterServiceData?.expiryDuration ?? expiryDuration; + webhookData = paymasterServiceData?.webhookData ?? webhookData + smartAccountInfo = + paymasterServiceData?.smartAccountInfo ?? smartAccountInfo + expiryDuration = paymasterServiceData?.expiryDuration ?? expiryDuration // Note: The idea is before calling this below rpc, userOp values presense and types should be in accordance with how we call eth_estimateUseropGas on the bundler @@ -300,34 +353,38 @@ export class BiconomyPaymaster implements IHybridPaymaster<SponsorUserOperationD ...(tokenInfo !== null && { tokenInfo }), sponsorshipInfo: { ...(webhookData !== null && { webhookData }), - smartAccountInfo: smartAccountInfo, - }, - }, + smartAccountInfo: smartAccountInfo + } + } ], id: getTimestampInSeconds(), - jsonrpc: "2.0", - }, + jsonrpc: "2.0" + } }, - "Paymaster", - ); - - if (response && response.result) { - const paymasterAndData = response.result.paymasterAndData; - const preVerificationGas = response.result.preVerificationGas; - const verificationGasLimit = response.result.verificationGasLimit; - const callGasLimit = response.result.callGasLimit; + "Paymaster" + ) + + if (response?.result) { + const paymasterAndData = response.result.paymasterAndData + const preVerificationGas = response.result.preVerificationGas + const verificationGasLimit = response.result.verificationGasLimit + const callGasLimit = response.result.callGasLimit return { paymasterAndData: paymasterAndData, preVerificationGas: preVerificationGas, verificationGasLimit: verificationGasLimit, - callGasLimit: callGasLimit, - }; + callGasLimit: callGasLimit + } } + // biome-ignore lint/suspicious/noExplicitAny: caught error is any } catch (error: any) { - Logger.error("Error in generating paymasterAndData - reason: ", JSON.stringify(error)); - throw error; + Logger.error( + "Error in generating paymasterAndData - reason: ", + JSON.stringify(error) + ) + throw error } - throw new Error("Error in generating paymasterAndData"); + throw new Error("Error in generating paymasterAndData") } /** @@ -338,12 +395,14 @@ export class BiconomyPaymaster implements IHybridPaymaster<SponsorUserOperationD */ async getDummyPaymasterAndData( _userOp: Partial<UserOperationStruct>, - _paymasterServiceData?: SponsorUserOperationDto, // mode is necessary. partial context of token paymaster or verifying + _paymasterServiceData?: SponsorUserOperationDto // mode is necessary. partial context of token paymaster or verifying ): Promise<string> { - return "0x"; + return "0x" } - public static async create(config: PaymasterConfig): Promise<BiconomyPaymaster> { - return new BiconomyPaymaster(config); + public static async create( + config: PaymasterConfig + ): Promise<BiconomyPaymaster> { + return new BiconomyPaymaster(config) } } diff --git a/src/paymaster/index.ts b/src/paymaster/index.ts new file mode 100644 index 000000000..2cebd53f5 --- /dev/null +++ b/src/paymaster/index.ts @@ -0,0 +1,8 @@ +import { BiconomyPaymaster } from "./BiconomyPaymaster.js" +export * from "./interfaces/IPaymaster.js" +export * from "./interfaces/IHybridPaymaster.js" +export * from "./utils/Types.js" +export * from "./BiconomyPaymaster.js" + +export const Paymaster = BiconomyPaymaster +export const createPaymaster = Paymaster.create diff --git a/src/paymaster/interfaces/IHybridPaymaster.ts b/src/paymaster/interfaces/IHybridPaymaster.ts new file mode 100644 index 000000000..104029e0a --- /dev/null +++ b/src/paymaster/interfaces/IHybridPaymaster.ts @@ -0,0 +1,29 @@ +import type { UserOperationStruct } from "../../account" +import type { + BiconomyTokenPaymasterRequest, + Transaction +} from "../../account/utils/Types.js" +import type { + FeeQuotesOrDataDto, + FeeQuotesOrDataResponse, + PaymasterAndDataResponse +} from "../utils/Types.js" +import type { IPaymaster } from "./IPaymaster.js" + +export interface IHybridPaymaster<T> extends IPaymaster { + getPaymasterAndData( + _userOp: Partial<UserOperationStruct>, + _paymasterServiceData?: T + ): Promise<PaymasterAndDataResponse> + getDummyPaymasterAndData( + _userOp: Partial<UserOperationStruct>, + _paymasterServiceData?: T + ): Promise<string> + buildTokenApprovalTransaction( + _tokenPaymasterRequest: BiconomyTokenPaymasterRequest + ): Promise<Transaction> + getPaymasterFeeQuotesOrData( + _userOp: Partial<UserOperationStruct>, + _paymasterServiceData: FeeQuotesOrDataDto + ): Promise<FeeQuotesOrDataResponse> +} diff --git a/src/paymaster/interfaces/IPaymaster.ts b/src/paymaster/interfaces/IPaymaster.ts new file mode 100644 index 000000000..3aee820b2 --- /dev/null +++ b/src/paymaster/interfaces/IPaymaster.ts @@ -0,0 +1,12 @@ +import type { UserOperationStruct } from "../../account" +import type { PaymasterAndDataResponse } from "../utils/Types.js" + +export interface IPaymaster { + // Implementing class may add extra parameter (for example paymasterServiceData with it's own type) in below function signature + getPaymasterAndData( + _userOp: Partial<UserOperationStruct> + ): Promise<PaymasterAndDataResponse> + getDummyPaymasterAndData( + _userOp: Partial<UserOperationStruct> + ): Promise<string> +} diff --git a/packages/paymaster/src/utils/Constants.ts b/src/paymaster/utils/Constants.ts similarity index 83% rename from packages/paymaster/src/utils/Constants.ts rename to src/paymaster/utils/Constants.ts index 9a534ee8f..cdf1e4837 100644 --- a/packages/paymaster/src/utils/Constants.ts +++ b/src/paymaster/utils/Constants.ts @@ -1,6 +1,7 @@ -export const MAX_UINT256 = "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; -export const ENTRYPOINT_ADDRESS = "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -export const ADDRESS_ZERO = "0x0000000000000000000000000000000000000000"; +export const MAX_UINT256 = + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" +export const ENTRYPOINT_ADDRESS = "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" +export const ADDRESS_ZERO = "0x0000000000000000000000000000000000000000" // export const ERC20_PAYMASTER_ADDRESS = '0xE9f6Ffc87cac92bc94f704AE017e85cB83DBe4EC' // likely to be same address on all chains export const ERC20_ABI = [ @@ -8,5 +9,5 @@ export const ERC20_ABI = [ "function transferFrom(address from, address to, uint256 value) external returns (bool)", "function approve(address spender, uint256 value) external returns (bool)", "function allowance(address owner, address spender) external view returns (uint256)", - "function balanceOf(address owner) external view returns (uint256)", -]; + "function balanceOf(address owner) external view returns (uint256)" +] diff --git a/packages/paymaster/src/utils/Helpers.ts b/src/paymaster/utils/Helpers.ts similarity index 77% rename from packages/paymaster/src/utils/Helpers.ts rename to src/paymaster/utils/Helpers.ts index b6f5568d2..d9aeceea9 100644 --- a/packages/paymaster/src/utils/Helpers.ts +++ b/src/paymaster/utils/Helpers.ts @@ -3,5 +3,5 @@ * @returns Number */ export const getTimestampInSeconds = (): number => { - return Math.floor(Date.now() / 1000); -}; + return Math.floor(Date.now() / 1000) +} diff --git a/src/paymaster/utils/Types.ts b/src/paymaster/utils/Types.ts new file mode 100644 index 000000000..1d19d4773 --- /dev/null +++ b/src/paymaster/utils/Types.ts @@ -0,0 +1,128 @@ +export type Hex = `0x${string}` +import type { BigNumberish } from "../../account" +import type { JsonRpcError } from "../../bundler/utils/Types" + +export type PaymasterServiceErrorResponse = { + jsonrpc: string + id: number + error: JsonRpcError +} + +export type JsonRpcResponse = { + jsonrpc: string + id: number + // biome-ignore lint/suspicious/noExplicitAny: <explanation> + result?: any + error?: JsonRpcError +} + +export type PaymasterConfig = { + paymasterUrl: string + strictMode?: boolean +} + +export type SponsorUserOperationDto = { + /** mode: sponsored or erc20 */ + mode: PaymasterMode + /** Always recommended, especially when using token paymaster */ + calculateGasLimits?: boolean + /** Expiry duration in seconds */ + expiryDuration?: number + /** Webhooks to be fired after user op is sent */ + webhookData?: Record<string, any> + /** Smart account meta data */ + smartAccountInfo?: SmartAccountData + /** the fee-paying token address */ + feeTokenAddress?: string +} + +export type FeeQuotesOrDataDto = { + /** mode: sponsored or erc20 */ + mode?: PaymasterMode + /** Expiry duration in seconds */ + expiryDuration?: number + /** Always recommended, especially when using token paymaster */ + calculateGasLimits?: boolean + /** List of tokens to be used for fee quotes, if ommitted fees for all supported will be returned */ + tokenList?: string[] + /** preferredToken: Can be ommitted to return all quotes */ + preferredToken?: string + /** Webhooks to be fired after user op is sent */ + // biome-ignore lint/suspicious/noExplicitAny: <explanation> + webhookData?: Record<string, any> + /** Smart account meta data */ + smartAccountInfo?: SmartAccountData +} + +export type FeeQuoteParams = { + tokenList?: string[] + preferredToken?: string +} + +export type FeeTokenInfo = { + feeTokenAddress: string +} + +export type SponsorpshipInfo = { + /** Webhooks to be fired after user op is sent */ + // biome-ignore lint/suspicious/noExplicitAny: <explanation> + webhookData?: Record<string, any> + /** Smart account meta data */ + smartAccountInfo: SmartAccountData +} + +export type SmartAccountData = { + /** name: Name of the smart account */ + name: string + /** version: Version of the smart account */ + version: string +} + +export type PaymasterFeeQuote = { + /** symbol: Token symbol */ + symbol: string + /** tokenAddress: Token address */ + tokenAddress: string + /** decimal: Token decimal */ + decimal: number + logoUrl?: string + /** maxGasFee: in wei */ + maxGasFee: number + /** maxGasFee: in dollars */ + maxGasFeeUSD?: number + usdPayment?: number + /** The premium paid on the token */ + premiumPercentage: number + /** validUntil: Unix timestamp */ + validUntil?: number +} + +export type FeeQuotesOrDataResponse = { + /** Array of results from the paymaster */ + feeQuotes?: PaymasterFeeQuote[] + /** Normally set to the spender in the proceeding call to send the tx */ + tokenPaymasterAddress?: Hex + /** Relevant Data returned from the paymaster */ + paymasterAndData?: Uint8Array | Hex + /* Gas overhead of this UserOperation */ + preVerificationGas?: BigNumberish + /* Actual gas used by the validation of this UserOperation */ + verificationGasLimit?: BigNumberish + /* Value used by inner account execution */ + callGasLimit?: BigNumberish +} + +export type PaymasterAndDataResponse = { + paymasterAndData: Hex + /* Gas overhead of this UserOperation */ + preVerificationGas: number + /* Actual gas used by the validation of this UserOperation */ + verificationGasLimit: number + /* Value used by inner account execution */ + callGasLimit: number +} + +export enum PaymasterMode { + ERC20 = "ERC20", + SPONSORED = "SPONSORED" +} diff --git a/tests/account/read.test.ts b/tests/account/read.test.ts new file mode 100644 index 000000000..ca24cc709 --- /dev/null +++ b/tests/account/read.test.ts @@ -0,0 +1,760 @@ +import { JsonRpcProvider } from "@ethersproject/providers" +import { Wallet } from "@ethersproject/wallet" +import { + http, + type Hex, + createPublicClient, + createWalletClient, + encodeAbiParameters, + encodeFunctionData, + hashMessage, + parseAbi, + parseAbiParameters +} from "viem" +import { generatePrivateKey, privateKeyToAccount } from "viem/accounts" +import { bsc } from "viem/chains" +import { beforeAll, describe, expect, test } from "vitest" +import { + type BiconomySmartAccountV2, + type BiconomySmartAccountV2Config, + DEFAULT_ENTRYPOINT_ADDRESS, + ERROR_MESSAGES, + NATIVE_TOKEN_ALIAS, + compareChainIds, + createSmartAccountClient, + isNullOrUndefined +} from "../../src/account" +import { type UserOperationStruct, getChain } from "../../src/account" +import { EntryPointAbi } from "../../src/account/abi/EntryPointAbi" +import { BiconomyAccountAbi } from "../../src/account/abi/SmartAccount" +import { + DEFAULT_ECDSA_OWNERSHIP_MODULE, + DEFAULT_SESSION_KEY_MANAGER_MODULE, + createECDSAOwnershipValidationModule +} from "../../src/modules" +import { Paymaster, PaymasterMode } from "../../src/paymaster" +import { checkBalance, getBundlerUrl, getConfig } from "../utils" + +describe("Account:Read", () => { + const nftAddress = "0x1758f42Af7026fBbB559Dc60EcE0De3ef81f665e" + const token = "0x747A4168DB14F57871fa8cda8B5455D8C2a8e90a" + const { + chain, + chainId, + privateKey, + privateKeyTwo, + bundlerUrl, + paymasterUrl + } = getConfig() + const account = privateKeyToAccount(`0x${privateKey}`) + const accountTwo = privateKeyToAccount(`0x${privateKeyTwo}`) + const sender = account.address + const recipient = accountTwo.address + const publicClient = createPublicClient({ + chain, + transport: http() + }) + let [smartAccount, smartAccountTwo]: BiconomySmartAccountV2[] = [] + let [smartAccountAddress, smartAccountAddressTwo]: Hex[] = [] + + const [walletClient, walletClientTwo] = [ + createWalletClient({ + account, + chain, + transport: http() + }), + createWalletClient({ + account: accountTwo, + chain, + transport: http() + }) + ] + + beforeAll(async () => { + ;[smartAccount, smartAccountTwo] = await Promise.all( + [walletClient, walletClientTwo].map((client) => + createSmartAccountClient({ + chainId, + signer: client, + bundlerUrl, + paymasterUrl + }) + ) + ) + ;[smartAccountAddress, smartAccountAddressTwo] = await Promise.all( + [smartAccount, smartAccountTwo].map((account) => + account.getAccountAddress() + ) + ) + }) + + test.concurrent( + "should accept PrivateKeyAccount as signer and sign a message", + async () => { + const account = privateKeyToAccount(`0x${privateKey}`) + + const smartAccount = await createSmartAccountClient({ + signer: account, + bundlerUrl, + rpcUrl: chain.rpcUrls.default.http[0] + }) + + const message = "hello world" + const signature = await smartAccount.signMessage(message) + expect(signature).toBeTruthy() + }, + 50000 + ) + + test.concurrent( + "should estimate gas for minting an NFT", + async () => { + const encodedCall = encodeFunctionData({ + abi: parseAbi(["function safeMint(address _to)"]), + functionName: "safeMint", + args: [recipient] + }) + const transaction = { + to: nftAddress, // NFT address + data: encodedCall + } + const results = await Promise.all([ + smartAccount.getGasEstimate([transaction]), + smartAccount.getGasEstimate([transaction, transaction]), + smartAccount.getGasEstimate([transaction], { + paymasterServiceData: { + mode: PaymasterMode.SPONSORED + } + }), + smartAccount.getGasEstimate([transaction, transaction], { + paymasterServiceData: { + mode: PaymasterMode.SPONSORED + } + }), + smartAccount.getGasEstimate([transaction], { + paymasterServiceData: { + mode: PaymasterMode.ERC20, + preferredToken: token + } + }), + await smartAccount.getGasEstimate([transaction, transaction], { + paymasterServiceData: { + mode: PaymasterMode.ERC20, + preferredToken: token + } + }) + ]) + + const increasingGasExpenditure = results.every( + (result, i) => result > (results[i - 1] ?? 0) + ) + + expect(increasingGasExpenditure).toBeTruthy() + }, + 60000 + ) + + test.concurrent( + "should throw if PrivateKeyAccount is used as signer and rpcUrl is not provided", + async () => { + const account = privateKeyToAccount(`0x${privateKey}`) + + const createSmartAccount = createSmartAccountClient({ + signer: account, + bundlerUrl + }) + + await expect(createSmartAccount).rejects.toThrow( + ERROR_MESSAGES.MISSING_RPC_URL + ) + }, + 50000 + ) + + test.concurrent( + "should get all modules", + async () => { + const modules = await smartAccount.getAllModules() + expect(modules).toContain(DEFAULT_SESSION_KEY_MANAGER_MODULE) // session manager module + expect(modules).toContain(DEFAULT_ECDSA_OWNERSHIP_MODULE) // ecdsa ownership module + }, + 30000 + ) + + test.concurrent( + "should check if module is enabled on the smart account", + async () => { + const isEnabled = await smartAccount.isModuleEnabled( + DEFAULT_ECDSA_OWNERSHIP_MODULE + ) + expect(isEnabled).toBeTruthy() + }, + 30000 + ) + + test.concurrent( + "should get disabled module data", + async () => { + const disableModuleData = await smartAccount.getDisableModuleData( + DEFAULT_ECDSA_OWNERSHIP_MODULE, + DEFAULT_ECDSA_OWNERSHIP_MODULE + ) + expect(disableModuleData).toBeTruthy() + }, + 30000 + ) + + test.concurrent( + "should get setup and enable module data", + async () => { + const module = await createECDSAOwnershipValidationModule({ + signer: walletClient + }) + const initData = await module.getInitData() + const setupAndEnableModuleData = + await smartAccount.getSetupAndEnableModuleData( + DEFAULT_ECDSA_OWNERSHIP_MODULE, + initData + ) + expect(setupAndEnableModuleData).toBeTruthy() + }, + 30000 + ) + + test.concurrent( + "should create a smartAccountClient from an ethers signer", + async () => { + const ethersProvider = new JsonRpcProvider(chain.rpcUrls.default.http[0]) + const ethersSigner = new Wallet(privateKey, ethersProvider) + + const smartAccount = await createSmartAccountClient({ + signer: ethersSigner, + bundlerUrl, + rpcUrl: chain.rpcUrls.default.http[0] + }) + const address = await smartAccount.getAccountAddress() + expect(address).toBeTruthy() + } + ) + + test.concurrent( + "should pickup the rpcUrl from viem wallet and ethers", + async () => { + const newRpcUrl = "http://localhost:8545" + const defaultRpcUrl = chain.rpcUrls.default.http[0] //http://127.0.0.1:8545" + + const ethersProvider = new JsonRpcProvider(newRpcUrl) + const ethersSignerWithNewRpcUrl = new Wallet(privateKey, ethersProvider) + + const originalEthersProvider = new JsonRpcProvider( + chain.rpcUrls.default.http[0] + ) + const ethersSigner = new Wallet(privateKey, originalEthersProvider) + + const accountOne = privateKeyToAccount(`0x${privateKey}`) + const walletClientWithNewRpcUrl = createWalletClient({ + account: accountOne, + chain, + transport: http(newRpcUrl) + }) + const [ + smartAccountFromEthersWithNewRpc, + smartAccountFromViemWithNewRpc, + smartAccountFromEthersWithOldRpc, + smartAccountFromViemWithOldRpc + ] = await Promise.all([ + createSmartAccountClient({ + chainId, + signer: ethersSignerWithNewRpcUrl, + bundlerUrl: getBundlerUrl(1337), + rpcUrl: newRpcUrl + }), + createSmartAccountClient({ + chainId, + signer: walletClientWithNewRpcUrl, + bundlerUrl: getBundlerUrl(1337), + rpcUrl: newRpcUrl + }), + createSmartAccountClient({ + chainId, + signer: ethersSigner, + bundlerUrl: getBundlerUrl(1337), + rpcUrl: chain.rpcUrls.default.http[0] + }), + createSmartAccountClient({ + chainId, + signer: walletClient, + bundlerUrl: getBundlerUrl(1337), + rpcUrl: chain.rpcUrls.default.http[0] + }) + ]) + + const [ + smartAccountFromEthersWithNewRpcAddress, + smartAccountFromViemWithNewRpcAddress, + smartAccountFromEthersWithOldRpcAddress, + smartAccountFromViemWithOldRpcAddress + ] = await Promise.all([ + smartAccountFromEthersWithNewRpc.getAccountAddress(), + smartAccountFromViemWithNewRpc.getAccountAddress(), + smartAccountFromEthersWithOldRpc.getAccountAddress(), + smartAccountFromViemWithOldRpc.getAccountAddress() + ]) + + expect( + [ + smartAccountFromEthersWithNewRpcAddress, + smartAccountFromViemWithNewRpcAddress, + smartAccountFromEthersWithOldRpcAddress, + smartAccountFromViemWithOldRpcAddress + ].every(Boolean) + ).toBeTruthy() + + expect(smartAccountFromEthersWithNewRpc.rpcProvider.transport.url).toBe( + newRpcUrl + ) + expect(smartAccountFromViemWithNewRpc.rpcProvider.transport.url).toBe( + newRpcUrl + ) + expect(smartAccountFromEthersWithOldRpc.rpcProvider.transport.url).toBe( + defaultRpcUrl + ) + expect(smartAccountFromViemWithOldRpc.rpcProvider.transport.url).toBe( + defaultRpcUrl + ) + } + ) + + test.concurrent( + "should read estimated user op gas values", + async () => { + const tx = { + to: recipient, + data: "0x" + } + + const userOp = await smartAccount.buildUserOp([tx]) + + const estimatedGas = await smartAccount.estimateUserOpGas(userOp) + expect(estimatedGas.maxFeePerGas).toBeTruthy() + expect(estimatedGas.maxPriorityFeePerGas).toBeTruthy() + expect(estimatedGas.verificationGasLimit).toBeTruthy() + expect(estimatedGas.callGasLimit).toBeTruthy() + expect(estimatedGas.preVerificationGas).toBeTruthy() + expect(estimatedGas).toHaveProperty("paymasterAndData", "0x") + }, + 30000 + ) + + test.concurrent("should have an active validation module", async () => { + const module = smartAccount.activeValidationModule + expect(module).toBeTruthy() + }) + + test.concurrent( + "should create a smart account with paymaster by creating instance", + async () => { + const paymaster = new Paymaster({ paymasterUrl }) + + const smartAccount = await createSmartAccountClient({ + signer: walletClient, + bundlerUrl, + paymaster + }) + expect(smartAccount.paymaster).not.toBeNull() + expect(smartAccount.paymaster).not.toBeUndefined() + } + ) + test.concurrent( + "should fail to create a smartAccountClient from a walletClient without a chainId", + async () => { + const account = privateKeyToAccount(generatePrivateKey()) + const viemWalletClientNoChainId = createWalletClient({ + account, + transport: http(chain.rpcUrls.default.http[0]) + }) + + expect( + await expect( + createSmartAccountClient({ + signer: viemWalletClientNoChainId, + bundlerUrl, + rpcUrl: chain.rpcUrls.default.http[0] + }) + ).rejects.toThrow("Cannot consume a viem wallet without a chainId") + ) + } + ) + + test.concurrent( + "should fail to create a smartAccountClient from a walletClient without an account", + async () => { + const viemWalletNoAccount = createWalletClient({ + transport: http(chain.rpcUrls.default.http[0]) + }) + + expect(async () => + createSmartAccountClient({ + signer: viemWalletNoAccount, + bundlerUrl, + rpcUrl: chain.rpcUrls.default.http[0] + }) + ).rejects.toThrow("Cannot consume a viem wallet without an account") + } + ) + + test.concurrent("should have account addresses", async () => { + const addresses = await Promise.all([ + sender, + smartAccount.getAddress(), + recipient, + smartAccountTwo.getAddress() + ]) + /* + * addresses: [ + * '0xFA66E705cf2582cF56528386Bb9dFCA119767262', // sender + * '0xe6dBb5C8696d2E0f90B875cbb6ef26E3bBa575AC', // smartAccountSender + * '0x3079B249DFDE4692D7844aA261f8cf7D927A0DA5', // recipient + * '0x5F141ee1390D4c9d033a00CB940E509A4811a5E0' // smartAccountRecipient + * ] + */ + expect(addresses.every(Boolean)).toBeTruthy() + }) + + test.concurrent( + "should create a smart account with paymaster with an api key", + async () => { + const paymaster = smartAccount.paymaster + expect(paymaster).not.toBeNull() + expect(paymaster).not.toBeUndefined() + } + ) + + test.concurrent("should not throw and error, chain ids match", async () => { + const mockBundlerUrl = + "https://bundler.biconomy.io/api/v2/80002/nJPK7B3ru.dd7f7861-190d-41bd-af80-6877f74b8f44" + const mockPaymasterUrl = + "https://paymaster.biconomy.io/api/v1/80002/-RObQRX9ei.fc6918eb-c582-4417-9d5a-0507b17cfe71" + + const config: BiconomySmartAccountV2Config = { + signer: walletClient, + bundlerUrl: mockBundlerUrl, + paymasterUrl: mockPaymasterUrl + } + + await expect( + compareChainIds(walletClient, config, false) + ).resolves.not.toThrow() + }) + + test.concurrent( + "should throw and error, bundlerUrl chain id and paymaster url chain id does not match with validation module", + async () => { + const mockPaymasterUrl = + "https://paymaster.biconomy.io/api/v1/1337/-RObQRX9ei.fc6918eb-c582-4417-9d5a-0507b17cfe71" + + const ecdsaModule = await createECDSAOwnershipValidationModule({ + signer: walletClient + }) + + const config: BiconomySmartAccountV2Config = { + defaultValidationModule: ecdsaModule, + activeValidationModule: ecdsaModule, + bundlerUrl, + paymasterUrl: mockPaymasterUrl + } + + await expect( + compareChainIds(walletClient, config, false) + ).rejects.toThrow() + } + ) + + test.concurrent( + "should throw and error, signer has chain id (56) and paymasterUrl has chain id (80002)", + async () => { + const mockPaymasterUrl = + "https://paymaster.biconomy.io/api/v1/80002/-RObQRX9ei.fc6918eb-c582-4417-9d5a-0507b17cfe71" + + const walletClientBsc = createWalletClient({ + account: walletClient.account, + chain: bsc, + transport: http(bsc.rpcUrls.default.http[0]) + }) + + const config: BiconomySmartAccountV2Config = { + signer: walletClientBsc, + bundlerUrl, + paymasterUrl: mockPaymasterUrl + } + + await expect( + compareChainIds(walletClientBsc, config, false) + ).rejects.toThrow() + } + ) + + test.concurrent("should return chain object for chain id 1", async () => { + const chainId = 1 + const chain = getChain(chainId) + expect(chain.id).toBe(chainId) + }) + + test.concurrent("should have correct fields", async () => { + const chainId = 1 + const chain = getChain(chainId) + ;[ + "blockExplorers", + "contracts", + "fees", + "formatters", + "id", + "name", + "nativeCurrency", + "rpcUrls", + "serializers" + ].every((field) => { + expect(chain).toHaveProperty(field) + }) + }) + + test.concurrent("should throw an error, chain id not found", async () => { + const chainId = 0 + expect(() => getChain(chainId)).toThrow(ERROR_MESSAGES.CHAIN_NOT_FOUND) + }) + + test.concurrent( + "should have matching #getUserOpHash and entryPoint.getUserOpHash", + async () => { + const userOp: UserOperationStruct = { + sender: "0x".padEnd(42, "1") as string, + nonce: 2, + initCode: "0x3333", + callData: "0x4444", + callGasLimit: 5, + verificationGasLimit: 6, + preVerificationGas: 7, + maxFeePerGas: 8, + maxPriorityFeePerGas: 9, + paymasterAndData: "0xaaaaaa", + signature: "0xbbbb" + } + + const epHash = await publicClient.readContract({ + address: DEFAULT_ENTRYPOINT_ADDRESS, + abi: EntryPointAbi, + functionName: "getUserOpHash", + // @ts-ignore + args: [userOp] + }) + + const hash = await smartAccount.getUserOpHash(userOp) + expect(hash).toBe(epHash) + }, + 30000 + ) + + test.concurrent( + "should be deployed to counterfactual address", + async () => { + const accountAddress = await smartAccount.getAccountAddress() + const byteCode = await publicClient.getBytecode({ + address: accountAddress as Hex + }) + + expect(byteCode?.length).toBeGreaterThan(2) + }, + 10000 + ) + + test.concurrent( + "should check if ecdsaOwnershipModule is enabled", + async () => { + const ecdsaOwnershipModule = "0x0000001c5b32F37F5beA87BDD5374eB2aC54eA8e" + + expect(ecdsaOwnershipModule).toBe( + smartAccount.activeValidationModule.getAddress() + ) + } + ) + + test.concurrent( + "should fail to deploy a smart account if no native token balance or paymaster", + async () => { + const newPrivateKey = generatePrivateKey() + const newAccount = privateKeyToAccount(newPrivateKey) + + const newViemWallet = createWalletClient({ + account: newAccount, + chain, + transport: http() + }) + + const smartAccount = await createSmartAccountClient({ + signer: newViemWallet, + paymasterUrl, + bundlerUrl + }) + + expect(async () => smartAccount.deploy()).rejects.toThrow( + ERROR_MESSAGES.NO_NATIVE_TOKEN_BALANCE_DURING_DEPLOY + ) + } + ) + + test.concurrent( + "should fail to deploy a smart account if already deployed", + async () => { + expect(async () => smartAccount.deploy()).rejects.toThrow( + ERROR_MESSAGES.ACCOUNT_ALREADY_DEPLOYED + ) + }, + 60000 + ) + + test.concurrent("should fetch balances for smartAccount", async () => { + const token = "0x747A4168DB14F57871fa8cda8B5455D8C2a8e90a" + const tokenBalanceBefore = await checkBalance(smartAccountAddress, token) + const [tokenBalanceFromSmartAccount] = await smartAccount.getBalances([ + token + ]) + + expect(tokenBalanceBefore).toBe(tokenBalanceFromSmartAccount.amount) + }) + + test.concurrent("should error if no recipient exists", async () => { + const token: Hex = "0x747A4168DB14F57871fa8cda8B5455D8C2a8e90a" + + const txs = [ + { address: token, amount: BigInt(1), recipient: sender }, + { address: NATIVE_TOKEN_ALIAS, amount: BigInt(1) } + ] + + expect(async () => smartAccount.withdraw(txs)).rejects.toThrow( + ERROR_MESSAGES.NO_RECIPIENT + ) + }) + + test.concurrent( + "should error when withdraw all of native token is attempted without an amount explicitly set", + async () => { + expect(async () => smartAccount.withdraw(null, sender)).rejects.toThrow( + ERROR_MESSAGES.NATIVE_TOKEN_WITHDRAWAL_WITHOUT_AMOUNT + ) + }, + 6000 + ) + + test.concurrent( + "should check native token balance and more token info for smartAccount", + async () => { + const [ethBalanceFromSmartAccount] = await smartAccount.getBalances() + + expect(ethBalanceFromSmartAccount.amount).toBeGreaterThan(0n) + expect(ethBalanceFromSmartAccount.address).toBe(NATIVE_TOKEN_ALIAS) + expect(ethBalanceFromSmartAccount.chainId).toBe(chainId) + expect(ethBalanceFromSmartAccount.decimals).toBe(18) + }, + 60000 + ) + + test.concurrent( + "should check balance of supported token", + async () => { + const tokens = await smartAccount.getSupportedTokens() + const [firstToken] = tokens + + expect(tokens.length).toBeGreaterThan(0) + expect(tokens[0]).toHaveProperty("balance") + expect(firstToken.balance.amount).toBeGreaterThanOrEqual(0n) + }, + 60000 + ) + + test.concurrent( + "should verify a correct signature through isValidSignature", + async () => { + const eip1271MagicValue = "0x1626ba7e" + const message = "Some message from dApp" + const messageHash = hashMessage(message) + const signature = await smartAccount.signMessage(messageHash) + + const response = await publicClient.readContract({ + address: await smartAccount.getAccountAddress(), + abi: BiconomyAccountAbi, + functionName: "isValidSignature", + args: [messageHash, signature] + }) + + expect(response).toBe(eip1271MagicValue) + } + ) + + test.concurrent("should confirm that signature is not valid", async () => { + const randomPrivKey = generatePrivateKey() + const randomWallet = privateKeyToAccount(randomPrivKey) + + const smartAccount = await createSmartAccountClient({ + signer: walletClient, + bundlerUrl + }) + + const eip1271MagicValue = "0xffffffff" + const message = "Some message from dApp" + const messageHash = hashMessage(message) + const signature = await randomWallet.signMessage({ message: messageHash }) + const signatureWithModuleAddress = encodeAbiParameters( + parseAbiParameters("bytes, address"), + [signature, smartAccount.defaultValidationModule.getAddress()] + ) + + const response = await publicClient.readContract({ + address: await smartAccount.getAccountAddress(), + abi: BiconomyAccountAbi, + functionName: "isValidSignature", + args: [messageHash, signatureWithModuleAddress] + }) + + expect(response).toBe(eip1271MagicValue) + }) + + test.concurrent("should verifySignature of deployed", async () => { + const smartAccount = await createSmartAccountClient({ + signer: walletClient, + bundlerUrl, + index: 1 + }) + + const message = "hello world" + + const signature = await smartAccount.signMessage(message) + + const isVerified = await publicClient.verifyMessage({ + address: await smartAccount.getAddress(), + message, + signature + }) + + expect(isVerified).toBeTruthy() + }) + + test.concurrent("should verifySignature of not deployed", async () => { + const smartAccount = await createSmartAccountClient({ + signer: walletClient, + bundlerUrl, + index: 100 + }) + + const message = "hello world" + + const signature = await smartAccount.signMessage(message) + + const isVerified = await publicClient.verifyMessage({ + address: await smartAccount.getAddress(), + message, + signature + }) + + expect(isVerified).toBeTruthy() + }) +}) diff --git a/tests/account/write.test.ts b/tests/account/write.test.ts new file mode 100644 index 000000000..2ea34e67e --- /dev/null +++ b/tests/account/write.test.ts @@ -0,0 +1,318 @@ +import { + http, + type Hex, + createPublicClient, + createWalletClient, + encodeFunctionData, + getContract, + parseAbi, + zeroAddress +} from "viem" +import { generatePrivateKey, privateKeyToAccount } from "viem/accounts" +import { beforeAll, describe, expect, test } from "vitest" +import { + type BiconomySmartAccountV2, + DEFAULT_ENTRYPOINT_ADDRESS, + ERC20_ABI, + createSmartAccountClient +} from "../../src/account" +import { EntryPointAbi } from "../../src/account/abi/EntryPointAbi" +import { PaymasterMode } from "../../src/paymaster" +import { testOnlyOnOptimism } from "../setupFiles" +import { checkBalance, getConfig, nonZeroBalance, topUp } from "../utils" + +describe("Account:Write", () => { + const nftAddress = "0x1758f42Af7026fBbB559Dc60EcE0De3ef81f665e" + const token = "0x747A4168DB14F57871fa8cda8B5455D8C2a8e90a" + const { + chain, + chainId, + privateKey, + privateKeyTwo, + bundlerUrl, + paymasterUrl + } = getConfig() + const account = privateKeyToAccount(`0x${privateKey}`) + const accountTwo = privateKeyToAccount(`0x${privateKeyTwo}`) + const sender = account.address + const recipient = accountTwo.address + const publicClient = createPublicClient({ + chain, + transport: http() + }) + let [smartAccount, smartAccountTwo]: BiconomySmartAccountV2[] = [] + let [smartAccountAddress, smartAccountAddressTwo]: Hex[] = [] + + const [walletClient, walletClientTwo] = [ + createWalletClient({ + account, + chain, + transport: http() + }), + createWalletClient({ + account: accountTwo, + chain, + transport: http() + }) + ] + + beforeAll(async () => { + ;[smartAccount, smartAccountTwo] = await Promise.all( + [walletClient, walletClientTwo].map((client) => + createSmartAccountClient({ + chainId, + signer: client, + bundlerUrl, + paymasterUrl + }) + ) + ) + ;[smartAccountAddress, smartAccountAddressTwo] = await Promise.all( + [smartAccount, smartAccountTwo].map((account) => + account.getAccountAddress() + ) + ) + }) + + test("should send some native token to recipient via the entrypoint", async () => { + const balanceOfRecipient = await checkBalance(recipient) + + // biome-ignore lint/style/useConst: <explanation> + let userOp = await smartAccount.buildUserOp([ + { + to: recipient, + value: 1n + } + ]) + + userOp.signature = undefined + + const signedUserOp = await smartAccount.signUserOp(userOp) + + const entrypointContract = getContract({ + address: DEFAULT_ENTRYPOINT_ADDRESS, + abi: EntryPointAbi, + client: { public: publicClient, wallet: walletClient } + }) + + const hash = await entrypointContract.write.handleOps([ + [ + { + sender: signedUserOp.sender as Hex, + nonce: BigInt(signedUserOp.nonce ?? 0), + callGasLimit: BigInt(signedUserOp.callGasLimit ?? 0), + verificationGasLimit: BigInt(signedUserOp.verificationGasLimit ?? 0), + preVerificationGas: BigInt(signedUserOp.preVerificationGas ?? 0), + maxFeePerGas: BigInt(signedUserOp.maxFeePerGas ?? 0), + maxPriorityFeePerGas: BigInt(signedUserOp.maxPriorityFeePerGas ?? 0), + initCode: signedUserOp.initCode as Hex, + callData: signedUserOp.callData as Hex, + paymasterAndData: signedUserOp.paymasterAndData as Hex, + signature: signedUserOp.signature as Hex + } + ], + sender + ]) + + const { status, transactionHash } = + await publicClient.waitForTransactionReceipt({ hash }) + + expect(status).toBe("success") + expect(transactionHash).toBeTruthy() + + const balanceOfRecipientAfter = await checkBalance(recipient) + + expect(balanceOfRecipientAfter - balanceOfRecipient).toBe(1n) + }, 50000) + + test("should deploy a smart account with native token balance", async () => { + const newPrivateKey = generatePrivateKey() + const newAccount = privateKeyToAccount(newPrivateKey) + + const newViemWallet = createWalletClient({ + account: newAccount, + chain, + transport: http() + }) + + const newSmartAccount = await createSmartAccountClient({ + signer: newViemWallet, + paymasterUrl, + bundlerUrl + }) + + const newSmartAccountAddress = await newSmartAccount.getAccountAddress() + + // Setup: + await topUp(newSmartAccountAddress, BigInt(100000000000000000)) + + const balanceCheck = await checkBalance(newSmartAccountAddress) + + // Test: + const { wait } = await newSmartAccount.deploy() + const { success } = await wait() + + const byteCode = await publicClient.getBytecode({ + address: newSmartAccountAddress + }) + expect(success).toBe("true") + expect(byteCode).toBeTruthy() + }, 60000) + + testOnlyOnOptimism( + "should send some native token to a recipient on optimism", + async () => { + const balanceOfRecipient = await checkBalance(recipient) + + const { wait } = await smartAccount.sendTransaction( + { + to: recipient, + value: BigInt(1) + }, + { + simulationType: "validation_and_execution" + } + ) + + const result = await wait() + const newBalanceOfRecipient = await checkBalance(recipient) + + expect(result?.receipt?.transactionHash).toBeTruthy() + expect(result.success).toBe("true") + expect(newBalanceOfRecipient).toBeGreaterThan(balanceOfRecipient) + }, + 50000 + ) + + testOnlyOnOptimism( + "should create a smart account with paymaster with an api key on optimism", + async () => { + const paymaster = smartAccount.paymaster + expect(paymaster).not.toBeNull() + expect(paymaster).not.toBeUndefined() + } + ) + + test("should withdraw erc20 balances", async () => { + await nonZeroBalance(smartAccountAddress, token) + + const tokenBalanceOfSABefore = await checkBalance( + smartAccountAddress, + token + ) + const tokenBalanceOfRecipientBefore = await checkBalance(sender, token) + const { wait } = await smartAccount.withdraw( + [{ address: token, amount: BigInt(1), recipient: sender }], + undefined, + { + paymasterServiceData: { + mode: PaymasterMode.SPONSORED + } + } + ) + + const { + receipt: { transactionHash }, + userOpHash, + success + } = await wait() + + expect(userOpHash).toBeTruthy() + expect(success).toBe("true") + expect(transactionHash).toBeTruthy() + + const tokenBalanceOfSAAfter = await checkBalance(smartAccountAddress, token) + const tokenBalanceOfRecipientAfter = await checkBalance(sender, token) + + expect(tokenBalanceOfSAAfter - tokenBalanceOfSABefore).toBe(-1n) + expect(tokenBalanceOfRecipientAfter - tokenBalanceOfRecipientBefore).toBe( + 1n + ) + }, 25000) + + test("should mint an NFT and pay with ERC20 - with token", async () => { + const encodedCall = encodeFunctionData({ + abi: parseAbi(["function safeMint(address _to)"]), + functionName: "safeMint", + args: [recipient] + }) + const transaction = { + to: nftAddress, // NFT address + data: encodedCall + } + const balance = await checkBalance(recipient, nftAddress) + const nativeBalanceBefore = await checkBalance(smartAccountAddress) + const tokenBalanceBefore = await checkBalance(smartAccountAddress, token) + const { wait } = await smartAccount.sendTransaction([transaction], { + paymasterServiceData: { + mode: PaymasterMode.ERC20, + preferredToken: token + } + }) + const { + receipt: { transactionHash }, + userOpHash, + success + } = await wait() + expect(transactionHash).toBeTruthy() + expect(userOpHash).toBeTruthy() + expect(success).toBe("true") + const nativeBalanceAfter = await checkBalance(smartAccountAddress) + expect(nativeBalanceAfter).toEqual(nativeBalanceBefore) + const tokenBalanceAfter = await checkBalance(smartAccountAddress, token) + expect(tokenBalanceAfter).toBeLessThan(tokenBalanceBefore) + const newBalance = await checkBalance(recipient, nftAddress) + expect(newBalance - balance).toBe(1n) + }, 60000) + + test("should mint an NFT and pay with ERC20 - with token selection and no maxApproval", async () => { + const encodedCall = encodeFunctionData({ + abi: parseAbi(["function safeMint(address _to)"]), + functionName: "safeMint", + args: [recipient] + }) + const transaction = { + to: nftAddress, // NFT address + data: encodedCall + } + const feeQuotesResponse = await smartAccount.getTokenFees(transaction, { + paymasterServiceData: { + mode: PaymasterMode.ERC20, + preferredToken: token + } + }) + const selectedFeeQuote = feeQuotesResponse.feeQuotes?.[0] + // biome-ignore lint/style/noNonNullAssertion: <explanation> + const spender = feeQuotesResponse.tokenPaymasterAddress! + const contract = getContract({ + address: token, + abi: parseAbi(ERC20_ABI), + client: publicClient + }) + + const balance = await checkBalance(recipient, nftAddress) + const nativeBalanceBefore = await checkBalance(smartAccountAddress) + const tokenBalanceBefore = await checkBalance(smartAccountAddress, token) + const { wait } = await smartAccount.sendTransaction(transaction, { + paymasterServiceData: { + mode: PaymasterMode.ERC20, + feeQuote: selectedFeeQuote, + spender: feeQuotesResponse.tokenPaymasterAddress + } + }) + const { + receipt: { transactionHash }, + userOpHash, + success + } = await wait() + expect(userOpHash).toBeTruthy() + expect(success).toBe("true") + expect(transactionHash).toBeTruthy() + const nativeBalanceAfter = await checkBalance(smartAccountAddress) + expect(nativeBalanceAfter).toEqual(nativeBalanceBefore) + const tokenBalanceAfter = await checkBalance(smartAccountAddress, token) + expect(tokenBalanceAfter).toBeLessThan(tokenBalanceBefore) + const newBalance = await checkBalance(recipient, nftAddress) + expect(newBalance - balance).toBe(1n) + }, 60000) +}) diff --git a/tests/bundler/read.test.ts b/tests/bundler/read.test.ts new file mode 100644 index 000000000..9a0604976 --- /dev/null +++ b/tests/bundler/read.test.ts @@ -0,0 +1,202 @@ +import { http, type Chain, type Hex, createWalletClient } from "viem" +import { generatePrivateKey, privateKeyToAccount } from "viem/accounts" +import { beforeAll, describe, expect, test } from "vitest" +import { + type BiconomySmartAccountV2, + type BiconomySmartAccountV2Config, + compareChainIds, + createSmartAccountClient +} from "../../src/account" +import { createBundler } from "../../src/bundler" +import { getBundlerUrl, getConfig } from "../utils" + +describe("Bundler:Read", () => { + const { + chain, + chainId, + privateKey, + privateKeyTwo, + bundlerUrl, + paymasterUrl + } = getConfig() + const account = privateKeyToAccount(`0x${privateKey}`) + const accountTwo = privateKeyToAccount(`0x${privateKeyTwo}`) + const recipient = accountTwo.address + + let [smartAccount, smartAccountTwo]: BiconomySmartAccountV2[] = [] + let [smartAccountAddress, smartAccountAddressTwo]: Hex[] = [] + + const [walletClient, walletClientTwo] = [ + createWalletClient({ + account, + chain, + transport: http() + }), + createWalletClient({ + account: accountTwo, + chain, + transport: http() + }) + ] + + beforeAll(async () => { + ;[smartAccount, smartAccountTwo] = await Promise.all( + [walletClient, walletClientTwo].map((client) => + createSmartAccountClient({ + chainId, + signer: client, + bundlerUrl, + paymasterUrl + }) + ) + ) + ;[smartAccountAddress, smartAccountAddressTwo] = await Promise.all( + [smartAccount, smartAccountTwo].map((account) => + account.getAccountAddress() + ) + ) + }) + + test.concurrent( + "Should throw and give advice", + async () => { + const randomPrivateKey = generatePrivateKey() + const unfundedAccount = privateKeyToAccount(randomPrivateKey) + + const unfundedSmartAccountClient = await createSmartAccountClient({ + signer: createWalletClient({ + account: unfundedAccount, + chain, + transport: http() + }), + paymasterUrl, + bundlerUrl + }) + + await expect( + unfundedSmartAccountClient.sendTransaction({ + to: recipient, + value: 1 + }) + ).rejects.toThrow("Send some native tokens in your smart wallet") + }, + 20000 + ) + + test.concurrent( + "should parse the rpcUrl when a custom chain and bundler are used", + async () => { + const customBlastChain = { + id: 81_457, + name: "Blast", + // network: "blast", + nativeCurrency: { + decimals: 18, + name: "Ethereum", + symbol: "ETH" + }, + rpcUrls: { + public: { http: ["https://rpc.blast.io"] }, + default: { http: ["https://rpc.blast.io"] } + }, + blockExplorers: { + etherscan: { name: "Blastscan", url: "https://blastscan.io/" }, + default: { name: "Blastscan", url: "https://blastscan.io/" } + }, + contracts: { + multicall3: { + address: "0xca11bde05977b3631167028862be2a173976ca11", + blockCreated: 88_189 + } + } + } as const satisfies Chain + + const accountOne = privateKeyToAccount(`0x${privateKey}`) + + const walletClientWithCustomChain = createWalletClient({ + account: accountOne, + chain: customBlastChain, + transport: http() + }) + + const blastBundler = await createBundler({ + bundlerUrl: getBundlerUrl(customBlastChain.id), + viemChain: customBlastChain + }) + const smartAccountFromViemWithCustomChain = + await createSmartAccountClient({ + viemChain: customBlastChain, + signer: walletClientWithCustomChain, + bundler: blastBundler, + rpcUrl: customBlastChain.rpcUrls.default.http[0] + }) + + expect( + smartAccountFromViemWithCustomChain.rpcProvider.transport.url + ).toBe("https://rpc.blast.io") + expect(blastBundler.getBundlerUrl()).toBe( + getBundlerUrl(customBlastChain.id) + ) + } + ) + + test.concurrent( + "should throw an error, bundlerUrl chain id and signer chain id does not match", + async () => { + const config: BiconomySmartAccountV2Config = { + signer: walletClient, + bundlerUrl: getBundlerUrl(1337), + paymasterUrl + } + + await expect( + compareChainIds(walletClient, config, false) + ).rejects.toThrow() + } + ) + test.concurrent( + "should throw an error, bundlerUrl chainId and paymasterUrl + chainId does not match", + async () => { + const mockPaymasterUrl = + "https://paymaster.biconomy.io/api/v1/1337/-RObQRX9ei.fc6918eb-c582-4417-9d5a-0507b17cfe71" + + const config: BiconomySmartAccountV2Config = { + signer: walletClient, + bundlerUrl, + paymasterUrl: mockPaymasterUrl + } + + await expect( + compareChainIds(walletClient, config, false) + ).rejects.toThrow() + } + ) + + test.concurrent( + "should throw, chain id from signer and bundlerUrl do not match", + async () => { + const createAccount = createSmartAccountClient({ + signer: walletClient, + bundlerUrl: + "https://bundler.biconomy.io/api/v2/1/nJPK7B3ru.dd7f7861-190d-41bd-af80-6877f74b8f44" // mock + }) + + await expect(createAccount).rejects.toThrow() + } + ) + + test.concurrent( + "should throw, chain id from paymasterUrl and bundlerUrl do not match", + async () => { + const createAccount = createSmartAccountClient({ + signer: walletClient, + paymasterUrl: + "https://paymaster.biconomy.io/api/v1/1/-RObQRX9ei.fc6918eb-c582-4417-9d5a-0507b17cfe71", + bundlerUrl: + "https://bundler.biconomy.io/api/v2/80002/nJPK7B3ru.dd7f7861-190d-41bd-af80-6877f74b8f44" // mock + }) + + await expect(createAccount).rejects.toThrow() + } + ) +}) diff --git a/tests/bundler/write.test.ts b/tests/bundler/write.test.ts new file mode 100644 index 000000000..5fd3b3d9d --- /dev/null +++ b/tests/bundler/write.test.ts @@ -0,0 +1,159 @@ +import { http, type Hex, createPublicClient, createWalletClient } from "viem" +import { privateKeyToAccount } from "viem/accounts" +import { beforeAll, describe, expect, test } from "vitest" +import { + type BiconomySmartAccountV2, + createSmartAccountClient, + getChain +} from "../../src/account" +import { createBundler } from "../../src/bundler" +import { + checkBalance, + getBundlerUrl, + getConfig, + nonZeroBalance, + topUp +} from "../utils" + +describe("Bundler:Write", () => { + const nftAddress = "0x1758f42Af7026fBbB559Dc60EcE0De3ef81f665e" + const { + chain, + chainId, + privateKey, + privateKeyTwo, + bundlerUrl, + paymasterUrl + } = getConfig() + const account = privateKeyToAccount(`0x${privateKey}`) + const accountTwo = privateKeyToAccount(`0x${privateKeyTwo}`) + const recipient = accountTwo.address + const publicClient = createPublicClient({ + chain, + transport: http() + }) + let [smartAccount, smartAccountTwo]: BiconomySmartAccountV2[] = [] + let [smartAccountAddress, smartAccountAddressTwo]: Hex[] = [] + + const [walletClient, walletClientTwo] = [ + createWalletClient({ + account, + chain, + transport: http() + }), + createWalletClient({ + account: accountTwo, + chain, + transport: http() + }) + ] + + beforeAll(async () => { + ;[smartAccount, smartAccountTwo] = await Promise.all( + [walletClient, walletClientTwo].map((client) => + createSmartAccountClient({ + chainId, + signer: client, + bundlerUrl, + paymasterUrl + }) + ) + ) + ;[smartAccountAddress, smartAccountAddressTwo] = await Promise.all( + [smartAccount, smartAccountTwo].map((account) => + account.getAccountAddress() + ) + ) + }) + + test("should send some native token to a recipient", async () => { + await topUp(smartAccountAddress, BigInt(1000000000000000000)) + const balanceOfRecipient = await checkBalance(recipient) + + const { wait } = await smartAccount.sendTransaction({ + to: recipient, + value: 1n + }) + + const { + receipt: { transactionHash }, + success + } = await wait(3) + + expect(success).toBe("true") + + const newBalanceOfRecipient = await checkBalance(recipient) + + expect(transactionHash).toBeTruthy() + expect(newBalanceOfRecipient - balanceOfRecipient).toBe(1n) + }, 60000) + + test("should send some native token to a recipient with a bundler instance", async () => { + await topUp(smartAccountAddress, BigInt(1000000000000000000)) + + const balanceOfRecipient = await checkBalance(recipient) + + const smartAccountClientWithBundlerInstance = + await createSmartAccountClient({ + signer: walletClient, + bundler: await createBundler({ + bundlerUrl, + userOpReceiptMaxDurationIntervals: { + [chainId]: 50000 + } + }), + paymasterUrl + }) + + const { wait } = + await smartAccountClientWithBundlerInstance.sendTransaction({ + to: recipient, + value: 1 + }) + + const { + receipt: { transactionHash }, + success + } = await wait(3) + + expect(success).toBe("true") + + const newBalanceOfRecipient = await checkBalance(recipient) + + expect(transactionHash).toBeTruthy() + expect(newBalanceOfRecipient - balanceOfRecipient).toBe(1n) + }, 70000) + + test("should test a new network", async () => { + /* Set the network id and paymaster key */ + const NETWORK_ID = 80002 + const PAYMASTER_KEY = "<API_KEY>" + /****************************************/ + const chain = getChain(NETWORK_ID) + const bundlerUrl = getBundlerUrl(NETWORK_ID) + const paymasterUrl = `https://paymaster.biconomy.io/api/v1/${NETWORK_ID}/${PAYMASTER_KEY}` + + const newWalletClient = createWalletClient({ + account, + chain, + transport: http() + }) + + const newSmartAccount = await createSmartAccountClient({ + signer: newWalletClient, + bundlerUrl + // paymasterUrl + }) + + expect(chain.id).toBe(NETWORK_ID) + + const { wait } = await newSmartAccount.sendTransaction({ + to: recipient, + value: 1n + }) + + const { success } = await wait() + + expect(success).toBe("true") + }, 70000) +}) diff --git a/tests/chains.config.ts b/tests/chains.config.ts deleted file mode 100644 index 97e453c29..000000000 --- a/tests/chains.config.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { localhost, Chain } from "viem/chains"; -import { polygonMumbai, baseSepolia, optimism } from "viem/chains"; -import { config } from "dotenv"; - -config(); - -export type SupportedTestChain = "ganache" | "baseSepolia" | "mumbai" | "optimism"; -type BaseChainConfig = { - chainId: number; - entryPointAddress: string; - bundlerUrl: string; - paymasterUrl?: string; - viemChain: Chain; - biconomyPaymasterApiKey?: string; - deploymentCost: number; - nftAddress: string; -}; -export const CHAIN_CONFIG: Record<SupportedTestChain, BaseChainConfig> = { - ganache: { // No useful bundler or paymaster tests for ganache - chainId: 1337, - entryPointAddress: "0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789", - bundlerUrl: "https://bundler.biconomy.io/api/v2/1/cJPK7B3ru.dd7f7861-190d-45ic-af80-6877f74b8f44", - viemChain: localhost, - deploymentCost: 100000000000000000, - nftAddress: "0x1758f42Af7026fBbB559Dc60EcE0De3ef81f665e", - }, - baseSepolia: { - chainId: 84532, - entryPointAddress: "0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789", - bundlerUrl: "https://bundler.biconomy.io/api/v2/84532/cJPK7B3ru.dd7f7861-190d-45ic-af80-6877f74b8f44", - paymasterUrl: "https://paymaster.biconomy.io/api/v1/84532/" + process.env.E2E_BICO_PAYMASTER_KEY_BASE!, - viemChain: baseSepolia, - biconomyPaymasterApiKey: process.env.E2E_BICO_PAYMASTER_KEY_BASE!, - deploymentCost: 100000000000000000, - nftAddress: "0x1758f42Af7026fBbB559Dc60EcE0De3ef81f665e", - }, - mumbai: { - chainId: 80001, - entryPointAddress: "0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789", - bundlerUrl: "https://bundler.biconomy.io/api/v2/80001/cJPK7B3ru.dd7f7861-190d-45ic-af80-6877f74b8f44", - paymasterUrl: "https://paymaster.biconomy.io/api/v1/80001/" + process.env.E2E_BICO_PAYMASTER_KEY_MUMBAI!, - viemChain: polygonMumbai, - biconomyPaymasterApiKey: process.env.E2E_BICO_PAYMASTER_KEY_MUMBAI!, - deploymentCost: 100000000000000000, - nftAddress: "0x1758f42Af7026fBbB559Dc60EcE0De3ef81f665e", - }, - optimism: { - chainId: 10, - entryPointAddress: "0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789", - bundlerUrl: "https://bundler.biconomy.io/api/v2/10/cJPK7B3ru.dd7f7861-190d-45ic-af80-6877f74b8f44", - paymasterUrl: "https://paymaster.biconomy.io/api/v1/10/" + process.env.E2E_BICO_PAYMASTER_KEY_OP!, - viemChain: optimism, - biconomyPaymasterApiKey: process.env.E2E_BICO_PAYMASTER_KEY_OP!, - deploymentCost: 100000000000000000, - nftAddress: "0x1758f42Af7026fBbB559Dc60EcE0De3ef81f665e", - } -}; -export const E2E_TEST_CHAINS = [CHAIN_CONFIG.mumbai, CHAIN_CONFIG.baseSepolia, CHAIN_CONFIG.optimism]; -export const UNIT_TEST_CHAIN = CHAIN_CONFIG.ganache; - -export default CHAIN_CONFIG; \ No newline at end of file diff --git a/tests/globalSetup.ts b/tests/globalSetup.ts new file mode 100644 index 000000000..7b2602c67 --- /dev/null +++ b/tests/globalSetup.ts @@ -0,0 +1,5 @@ +import { getConfig } from "./utils.js" + +export default function setup({ provide: _ }) { + getConfig() +} diff --git a/tests/index.d.ts b/tests/index.d.ts deleted file mode 100644 index 25e39cf50..000000000 --- a/tests/index.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Chain, Hex, PrivateKeyAccount, PublicClient, WalletClient } from "viem"; -import { WalletClientSigner } from "@alchemy/aa-core"; -import { JsonRpcProvider } from "@ethersproject/providers"; -import { Signer } from "@ethersproject/abstract-signer"; - -interface WalletProps { - alchemyWalletClientSigner: WalletClientSigner; - viemWallet: WalletClient; - balance: bigint; - publicAddress: Hex; - account: PrivateKeyAccount; - privateKey: Hex; - ethersSigner: Signer; -} - -export type TestData = { - nftAddress: Hex; - deploymentCost: number; - whale: WalletProps; - minnow: WalletProps; - publicClient: PublicClient; - chainId: number; - bundlerUrl: string; - entryPointAddress: string; - viemChain: Chain; - paymasterUrl: string; - biconomyPaymasterApiKey: string; - ethersProvider: JsonRpcProvider; -}; diff --git a/tests/modules/read.test.ts b/tests/modules/read.test.ts new file mode 100644 index 000000000..a5d5c1a5e --- /dev/null +++ b/tests/modules/read.test.ts @@ -0,0 +1,247 @@ +import { defaultAbiCoder } from "@ethersproject/abi" +import { JsonRpcProvider } from "@ethersproject/providers" +import { Wallet } from "@ethersproject/wallet" +import { + http, + createWalletClient, + encodeAbiParameters, + parseAbiParameters +} from "viem" +import { privateKeyToAccount } from "viem/accounts" +import { beforeAll, describe, expect, test } from "vitest" +import { + type BiconomySmartAccountV2, + createSmartAccountClient +} from "../../src/account" +import { + createECDSAOwnershipValidationModule, + createMultiChainValidationModule +} from "../../src/modules" +import { getConfig } from "../utils" + +describe("Modules:Read", () => { + const { + chain, + chainId, + privateKey, + privateKeyTwo, + bundlerUrl, + paymasterUrl + } = getConfig() + const account = privateKeyToAccount(`0x${privateKey}`) + const accountTwo = privateKeyToAccount(`0x${privateKeyTwo}`) + let [smartAccount, smartAccountTwo]: BiconomySmartAccountV2[] = [] + let [smartAccountAddress, smartAccountAddressTwo]: Hex[] = [] + + const [walletClient, walletClientTwo] = [ + createWalletClient({ + account, + chain, + transport: http() + }), + createWalletClient({ + account: accountTwo, + chain, + transport: http() + }) + ] + + beforeAll(async () => { + ;[smartAccount, smartAccountTwo] = await Promise.all( + [walletClient, walletClientTwo].map((client) => + createSmartAccountClient({ + chainId, + signer: client, + bundlerUrl, + paymasterUrl + }) + ) + ) + ;[smartAccountAddress, smartAccountAddressTwo] = await Promise.all( + [smartAccount, smartAccountTwo].map((account) => + account.getAccountAddress() + ) + ) + }) + + test.concurrent("should encode params successfully", async () => { + const hardcodedPaddedSignature = + "0x000000000000000000000000000002fbffedd9b33f4e7156f2de8d48945e74890000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d50c68705bd6897b2d17c7de32fb519fda00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000fa66e705cf2582cf56528386bb9dfca119767262000000000000000000000000da5289fcaaf71d52a80a254da614a192b693e9770000000000000000000000003079b249dfde4692d7844aa261f8cf7d927a0da500000000000000000000000000000000000000000000000000000000009896800000000000000000000000000000000000000000000000000000000000000003ca2b0ef4564d7ca7044b8c9d75685659975c0cab591408cb20e4a2ab278ab282633eb23075a8cb9bc5b01a5a4fa367b73da76821105f67a62ed7eedd335f6c0e361e73015ce4bb83439ab0742bdfed338ec39e2e8dd0819528f02be218fc1db90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007ba4a7338d7a90dfa465cf975cc6691812c3772e00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000020000000000000000000000000fa66e705cf2582cf56528386bb9dfca1197672620000000000000000000000000000000000000000000000000000000000000003b91f47666ba9b0b6b2cfbb60bf39b241d269786aa01f388021057d080863dd40633eb23075a8cb9bc5b01a5a4fa367b73da76821105f67a62ed7eedd335f6c0e361e73015ce4bb83439ab0742bdfed338ec39e2e8dd0819528f02be218fc1db90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004173c3ac716c487ca34bb858247b5ccf1dc354fbaabdd089af3b2ac8e78ba85a4959a2d76250325bd67c11771c31fccda87c33ceec17cc0de912690521bb95ffcb1b00000000000000000000000000000000000000000000000000000000000000" + + const sessionKeyManagerAddress = + "0x000002FbFfedd9B33F4E7156F2DE8D48945E7489" + const mockEcdsaSessionKeySig = + "0x73c3ac716c487ca34bb858247b5ccf1dc354fbaabdd089af3b2ac8e78ba85a4959a2d76250325bd67c11771c31fccda87c33ceec17cc0de912690521bb95ffcb1b" + const sessionDataTupleArray = [ + [ + 0n, + 0n, + "0x000000d50c68705bd6897b2d17c7de32fb519fda", + "0x000000000000000000000000fa66e705cf2582cf56528386bb9dfca119767262000000000000000000000000da5289fcaaf71d52a80a254da614a192b693e9770000000000000000000000003079b249dfde4692d7844aa261f8cf7d927a0da50000000000000000000000000000000000000000000000000000000000989680", + [ + "0xca2b0ef4564d7ca7044b8c9d75685659975c0cab591408cb20e4a2ab278ab282", + "0x633eb23075a8cb9bc5b01a5a4fa367b73da76821105f67a62ed7eedd335f6c0e", + "0x361e73015ce4bb83439ab0742bdfed338ec39e2e8dd0819528f02be218fc1db9" + ], + "0x" + ], + [ + 0n, + 0n, + "0x7ba4a7338d7a90dfa465cf975cc6691812c3772e", + "0x000000000000000000000000fa66e705cf2582cf56528386bb9dfca119767262", + [ + "0xb91f47666ba9b0b6b2cfbb60bf39b241d269786aa01f388021057d080863dd40", + "0x633eb23075a8cb9bc5b01a5a4fa367b73da76821105f67a62ed7eedd335f6c0e", + "0x361e73015ce4bb83439ab0742bdfed338ec39e2e8dd0819528f02be218fc1db9" + ], + "0x" + ] + ] + + const paddedSignature = defaultAbiCoder.encode( + [ + "address", + "tuple(uint48,uint48,address,bytes,bytes32[],bytes)[]", + "bytes" + ], + [sessionKeyManagerAddress, sessionDataTupleArray, mockEcdsaSessionKeySig] + ) + + const abiParameters = [ + { type: "address" }, + { + type: "tuple[]", + components: [ + { type: "uint48" }, + { type: "uint48" }, + { type: "address" }, + { type: "bytes" }, + { type: "bytes32[]" }, + { type: "bytes" } + ] + }, + { type: "bytes" } + ] + + const paddedSignatureWithViem = encodeAbiParameters(abiParameters, [ + sessionKeyManagerAddress, + sessionDataTupleArray, + mockEcdsaSessionKeySig + ]) + + expect(paddedSignature).toEqual(hardcodedPaddedSignature) + expect(paddedSignatureWithViem).toEqual(hardcodedPaddedSignature) + }) + + test.concurrent( + "should create a ECDSAOwnershipValidationModule with signer", + async () => { + const defaultValidationModule = + await createECDSAOwnershipValidationModule({ + signer: walletClient + }) + // Should not require a signer or chainId + const smartAccount = await createSmartAccountClient({ + bundlerUrl, + defaultValidationModule, + signer: walletClient + }) + const address = await smartAccount.getAccountAddress() + expect(address).toBeTruthy() + expect(smartAccount.activeValidationModule).toEqual( + defaultValidationModule + ) + } + ) + + test.concurrent( + "should create a ECDSAOwnershipValidationModule without signer", + async () => { + const defaultValidationModule = + await createECDSAOwnershipValidationModule({ + signer: walletClient + }) + // Should not require a signer or chainId + const smartAccount = await createSmartAccountClient({ + bundlerUrl, + defaultValidationModule + }) + const address = await smartAccount.getAccountAddress() + expect(address).toBeTruthy() + expect(smartAccount.activeValidationModule).toEqual( + defaultValidationModule + ) + } + ) + + test.concurrent( + "should create a ECDSAOwnershipValidationModule by default, without explicitly setting it on the smart account", + async () => { + const defaultValidationModule = + await createECDSAOwnershipValidationModule({ + signer: walletClient + }) + const smartAccount = await createSmartAccountClient({ + bundlerUrl, + signer: walletClient + }) + const address = await smartAccount.getAccountAddress() + expect(address).toBeTruthy() + const smartAccountValidationModuleAddress = + await smartAccount.activeValidationModule.getAddress() + expect(smartAccountValidationModuleAddress).toEqual( + defaultValidationModule.moduleAddress + ) + } + ) + + test.concurrent( + "should create a MultiChainValidationModule from an ethers signer using convertSigner", + async () => { + const ethersProvider = new JsonRpcProvider(chain.rpcUrls.default.http[0]) + const ethersSigner = new Wallet(privateKey, ethersProvider) + + const defaultValidationModule = await createMultiChainValidationModule({ + signer: ethersSigner + }) + // Should not require a signer or chainId + const newSmartAccount = await createSmartAccountClient({ + bundlerUrl, + defaultValidationModule, + rpcUrl: chain.rpcUrls.default.http[0] + }) + + const address = await newSmartAccount.getAccountAddress() + expect(address).toBeTruthy() + // expect the relevant module to be set + expect(newSmartAccount.activeValidationModule).toEqual( + defaultValidationModule + ) + }, + 50000 + ) + + test.concurrent( + "should create a ECDSAOwnershipValidationModule from a viem signer using convertSigner", + async () => { + const defaultValidationModule = + await createECDSAOwnershipValidationModule({ + signer: walletClient + }) + // Should not require a signer or chainId + const smartAccount = await createSmartAccountClient({ + bundlerUrl, + defaultValidationModule, + rpcUrl: chain.rpcUrls.default.http[0] + }) + const address = await smartAccount.getAccountAddress() + expect(address).toBeTruthy() + // expect the relevant module to be set + expect(smartAccount.activeValidationModule).toEqual( + defaultValidationModule + ) + }, + 50000 + ) +}) diff --git a/tests/modules/write.test.ts b/tests/modules/write.test.ts new file mode 100644 index 000000000..5d66994ab --- /dev/null +++ b/tests/modules/write.test.ts @@ -0,0 +1,586 @@ +import { + http, + type Hex, + createPublicClient, + createWalletClient, + encodeAbiParameters, + encodeFunctionData, + pad, + parseAbi, + parseEther, + parseUnits, + slice, + toFunctionSelector +} from "viem" +import { privateKeyToAccount } from "viem/accounts" +import { beforeAll, describe, expect, test } from "vitest" +import { + type BiconomySmartAccountV2, + type Transaction, + type WalletClientSigner, + createSmartAccountClient +} from "../../src/account" +import { Logger, getChain } from "../../src/account" +import { + DEFAULT_BATCHED_SESSION_ROUTER_MODULE, + DEFAULT_MULTICHAIN_MODULE, + DEFAULT_SESSION_KEY_MANAGER_MODULE, + createBatchedSessionRouterModule, + createMultiChainValidationModule, + createSessionKeyManagerModule, + getABISVMSessionKeyData +} from "../../src/modules" +import { SessionMemoryStorage } from "../../src/modules/session-storage/SessionMemoryStorage" +import { PaymasterMode } from "../../src/paymaster" +import { checkBalance, getBundlerUrl, getConfig, topUp } from "../utils" + +describe("Modules:Write", () => { + const nftAddress = "0x1758f42Af7026fBbB559Dc60EcE0De3ef81f665e" + const { + chain, + chainId, + privateKey, + privateKeyTwo, + bundlerUrl, + paymasterUrl, + paymasterUrlTwo + } = getConfig() + const account = privateKeyToAccount(`0x${privateKey}`) + const accountTwo = privateKeyToAccount(`0x${privateKeyTwo}`) + const publicClient = createPublicClient({ + chain, + transport: http() + }) + + let [smartAccount, smartAccountTwo]: BiconomySmartAccountV2[] = [] + let [smartAccountAddress, smartAccountAddressTwo]: Hex[] = [] + + const [walletClient, walletClientTwo] = [ + createWalletClient({ + account, + chain, + transport: http() + }), + createWalletClient({ + account: accountTwo, + chain, + transport: http() + }) + ] + + beforeAll(async () => { + ;[smartAccount, smartAccountTwo] = await Promise.all( + [walletClient, walletClientTwo].map((client) => + createSmartAccountClient({ + chainId, + signer: client, + bundlerUrl, + paymasterUrl + }) + ) + ) + ;[smartAccountAddress, smartAccountAddressTwo] = await Promise.all( + [smartAccount, smartAccountTwo].map((account) => + account.getAccountAddress() + ) + ) + }) + + test("should enable session module", async () => { + const smartAccount = await createSmartAccountClient({ + signer: walletClient, + bundlerUrl, + paymasterUrl + }) + + const isSessionKeyEnabled = await smartAccount.isModuleEnabled( + DEFAULT_SESSION_KEY_MANAGER_MODULE + ) + + if (!isSessionKeyEnabled) { + const tx = await smartAccount.getEnableModuleData( + DEFAULT_SESSION_KEY_MANAGER_MODULE + ) + const { wait } = await smartAccount.sendTransaction(tx, { + paymasterServiceData: { mode: PaymasterMode.SPONSORED } + }) + const { success } = await wait() + expect(success).toBe("true") + } + }, 50000) + + test.skip("should use MultichainValidationModule to mint an NFT on two chains with sponsorship", async () => { + const nftAddress: Hex = "0x1758f42Af7026fBbB559Dc60EcE0De3ef81f665e" + const recipientForBothChains = walletClient.account.address + + const chainIdBase = 84532 + const bundlerUrlBase = getBundlerUrl(chainIdBase) + + const signerBase = createWalletClient({ + account: privateKeyToAccount(`0x${privateKey}`), + chain: getChain(84532), + transport: http() + }) + + const paymasterUrlBase = paymasterUrlTwo + + const multiChainModule = await createMultiChainValidationModule({ + signer: walletClient, + moduleAddress: DEFAULT_MULTICHAIN_MODULE + }) + + const [polygonAccount, baseAccount] = await Promise.all([ + createSmartAccountClient({ + chainId, + signer: walletClient, + bundlerUrl, + defaultValidationModule: multiChainModule, + activeValidationModule: multiChainModule, + paymasterUrl + }), + createSmartAccountClient({ + chainId: chainIdBase, + signer: signerBase, + bundlerUrl: bundlerUrlBase, + defaultValidationModule: multiChainModule, + activeValidationModule: multiChainModule, + paymasterUrl: paymasterUrlBase + }) + ]) + + // Check if the smart account has been deployed + const [isPolygonDeployed, isBaseDeployed] = await Promise.all([ + polygonAccount.isAccountDeployed(), + baseAccount.isAccountDeployed() + ]) + if (!isPolygonDeployed) { + const { wait } = await polygonAccount.deploy({ + paymasterServiceData: { mode: PaymasterMode.SPONSORED } + }) + const { success } = await wait() + expect(success).toBe("true") + } + if (!isBaseDeployed) { + const { wait } = await baseAccount.deploy({ + paymasterServiceData: { mode: PaymasterMode.SPONSORED } + }) + const { success } = await wait() + expect(success).toBe("true") + } + + const moduleEnabled1 = await polygonAccount.isModuleEnabled( + DEFAULT_MULTICHAIN_MODULE + ) + const moduleActive1 = polygonAccount.activeValidationModule + expect(moduleEnabled1).toBeTruthy() + expect(moduleActive1.getAddress()).toBe(DEFAULT_MULTICHAIN_MODULE) + + const moduleEnabled2 = await baseAccount.isModuleEnabled( + DEFAULT_MULTICHAIN_MODULE + ) + const moduleActive2 = polygonAccount.activeValidationModule + expect(moduleEnabled2).toBeTruthy() + expect(moduleActive2.getAddress()).toBe(DEFAULT_MULTICHAIN_MODULE) + + const encodedCall = encodeFunctionData({ + abi: parseAbi([ + "function safeMint(address owner) view returns (uint balance)" + ]), + functionName: "safeMint", + args: [recipientForBothChains] + }) + + const transaction = { + to: nftAddress, + data: encodedCall + } + + const [partialUserOp1, partialUserOp2] = await Promise.all([ + baseAccount.buildUserOp([transaction], { + paymasterServiceData: { mode: PaymasterMode.SPONSORED } + }), + polygonAccount.buildUserOp([transaction], { + paymasterServiceData: { mode: PaymasterMode.SPONSORED } + }) + ]) + + expect(partialUserOp1.paymasterAndData).not.toBe("0x") + expect(partialUserOp2.paymasterAndData).not.toBe("0x") + + // Sign the user ops using multiChainModule + const returnedOps = await multiChainModule.signUserOps([ + { userOp: partialUserOp1, chainId: chainIdBase }, + { userOp: partialUserOp2, chainId } + ]) + + // Send the signed user ops on both chains + const userOpResponse1 = await baseAccount.sendSignedUserOp( + // biome-ignore lint/suspicious/noExplicitAny: <explanation> + returnedOps[0] as any + ) + const userOpResponse2 = await polygonAccount.sendSignedUserOp( + // biome-ignore lint/suspicious/noExplicitAny: <explanation> + returnedOps[1] as any + ) + + Logger.log(userOpResponse1.userOpHash, "MULTICHAIN BASE USER OP HASH") + Logger.log(userOpResponse2.userOpHash, "MULTICHAIN POLYGON USER OP HASH") + + expect(userOpResponse1.userOpHash).toBeTruthy() + expect(userOpResponse2.userOpHash).toBeTruthy() + + const { success: success1 } = await userOpResponse1.wait() + const { success: success2 } = await userOpResponse2.wait() + + expect(success1).toBe("true") + expect(success2).toBe("true") + }, 50000) + + test("should use SessionValidationModule to send a user op", async () => { + let sessionSigner: WalletClientSigner + const sessionKeyEOA = walletClient.account.address + const recipient = walletClientTwo.account.address + + // Create smart account + let smartAccount = await createSmartAccountClient({ + chainId, + signer: walletClient, + bundlerUrl, + paymasterUrl, + index: 5 // Increasing index to not conflict with other test cases and use a new smart account + }) + const accountAddress = await smartAccount.getAccountAddress() + const sessionMemoryStorage: SessionMemoryStorage = new SessionMemoryStorage( + accountAddress + ) + // First we need to check if smart account is deployed + // if not deployed, send an empty transaction to deploy it + const isDeployed = await smartAccount.isAccountDeployed() + Logger.log("session", { isDeployed }) + if (!isDeployed) { + const { wait } = await smartAccount.deploy({ + paymasterServiceData: { mode: PaymasterMode.SPONSORED } + }) + const { success } = await wait() + expect(success).toBe("true") + } + + try { + sessionSigner = await sessionMemoryStorage.getSignerByKey(sessionKeyEOA) + } catch (error) { + sessionSigner = await sessionMemoryStorage.addSigner({ + pbKey: sessionKeyEOA, + pvKey: `0x${privateKey}`, + chainId: chain + }) + } + + expect(sessionSigner).toBeTruthy() + // Create session module + const sessionModule = await createSessionKeyManagerModule({ + moduleAddress: DEFAULT_SESSION_KEY_MANAGER_MODULE, + smartAccountAddress: await smartAccount.getAddress(), + sessionStorageClient: sessionMemoryStorage + }) + const functionSelector = slice( + toFunctionSelector("safeMint(address)"), + 0, + 4 + ) + // Set enabled call on session + const sessionKeyData = await getABISVMSessionKeyData(sessionKeyEOA as Hex, { + destContract: "0xdd526eba63ef200ed95f0f0fb8993fe3e20a23d0" as Hex, // nft address + functionSelector: functionSelector, + valueLimit: parseEther("0"), + rules: [ + { + offset: 0, // offset 0 means we are checking first parameter of safeMint (recipient address) + condition: 0, // 0 = Condition.EQUAL + referenceValue: pad("0xd3C85Fdd3695Aee3f0A12B3376aCD8DC54020549", { + size: 32 + }) // recipient address + } + ] + }) + const abiSvmAddress = "0x000006bC2eCdAe38113929293d241Cf252D91861" + const sessionTxData = await sessionModule.createSessionData([ + { + validUntil: 0, + validAfter: 0, + sessionValidationModule: abiSvmAddress, + sessionPublicKey: sessionKeyEOA as Hex, + sessionKeyData: sessionKeyData as Hex + } + ]) + const setSessionAllowedTrx = { + to: DEFAULT_SESSION_KEY_MANAGER_MODULE, + data: sessionTxData.data + } + // biome-ignore lint/suspicious/noExplicitAny: <explanation> + const txArray: any = [] + // Check if module is enabled + const isEnabled = await smartAccount.isModuleEnabled( + DEFAULT_SESSION_KEY_MANAGER_MODULE + ) + if (!isEnabled) { + const enableModuleTrx = await smartAccount.getEnableModuleData( + DEFAULT_SESSION_KEY_MANAGER_MODULE + ) + txArray.push(enableModuleTrx) + txArray.push(setSessionAllowedTrx) + } else { + Logger.log("MODULE ALREADY ENABLED") + txArray.push(setSessionAllowedTrx) + } + const userOp = await smartAccount.buildUserOp(txArray, { + paymasterServiceData: { + mode: PaymasterMode.SPONSORED + } + }) + const userOpResponse1 = await smartAccount.sendUserOp(userOp) + const transactionDetails = await userOpResponse1.wait() + expect(transactionDetails.success).toBe("true") + Logger.log("Tx Hash: ", transactionDetails.receipt.transactionHash) + const encodedCall = encodeFunctionData({ + abi: parseAbi(["function safeMint(address _to)"]), + functionName: "safeMint", + args: ["0xd3C85Fdd3695Aee3f0A12B3376aCD8DC54020549"] + }) + const nftMintTx = { + to: "0xdd526eba63ef200ed95f0f0fb8993fe3e20a23d0", + data: encodedCall + } + smartAccount = smartAccount.setActiveValidationModule(sessionModule) + const maticBalanceBefore = await checkBalance(smartAccountAddress) + const userOpResponse2 = await smartAccount.sendTransaction(nftMintTx, { + params: { + sessionSigner: sessionSigner, + sessionValidationModule: abiSvmAddress + }, + paymasterServiceData: { + mode: PaymasterMode.SPONSORED + } + }) + expect(userOpResponse2.userOpHash).toBeTruthy() + expect(userOpResponse2.userOpHash).not.toBeNull() + const maticBalanceAfter = await checkBalance(smartAccountAddress) + expect(maticBalanceAfter).toEqual(maticBalanceBefore) + Logger.log( + `Tx at: https://jiffyscan.xyz/userOpHash/${userOpResponse2.userOpHash}?network=mumbai` + ) + }, 60000) + + test("should enable batched module", async () => { + const smartAccount = await createSmartAccountClient({ + signer: walletClient, + bundlerUrl, + paymasterUrl + }) + + const isBRMenabled = await smartAccount.isModuleEnabled( + DEFAULT_BATCHED_SESSION_ROUTER_MODULE + ) + + if (!isBRMenabled) { + const tx = await smartAccount.getEnableModuleData( + DEFAULT_BATCHED_SESSION_ROUTER_MODULE + ) + const { wait } = await smartAccount.sendTransaction(tx, { + paymasterServiceData: { mode: PaymasterMode.SPONSORED } + }) + const { success } = await wait() + expect(success).toBe("true") + } + }, 50000) + + test.skip("should use BatchedSessionValidationModule to send a user op", async () => { + let sessionSigner: WalletClientSigner + const sessionKeyEOA = walletClient.account.address + const recipient = walletClientTwo.account.address + const token = "0x747A4168DB14F57871fa8cda8B5455D8C2a8e90a" + + let smartAccount = await createSmartAccountClient({ + chainId, + signer: walletClient, + bundlerUrl, + paymasterUrl, + index: 6 // Increasing index to not conflict with other test cases and use a new smart account + }) + + // const accountAddress = await smartAccount.getAccountAddress() + const smartAccountAddress = await smartAccount.getAddress() + await topUp(smartAccountAddress, undefined, token) + await topUp(smartAccountAddress, undefined) + + const sessionMemoryStorage: SessionMemoryStorage = new SessionMemoryStorage( + smartAccountAddress + ) + + try { + sessionSigner = await sessionMemoryStorage.getSignerByKey(sessionKeyEOA) + } catch (error) { + sessionSigner = await sessionMemoryStorage.addSigner({ + pbKey: sessionKeyEOA, + pvKey: `0x${privateKey}`, + chainId: chain + }) + } + + expect(sessionSigner).toBeTruthy() + const sessionModule = await createSessionKeyManagerModule({ + moduleAddress: DEFAULT_SESSION_KEY_MANAGER_MODULE, + smartAccountAddress, + sessionStorageClient: sessionMemoryStorage + }) + // Create batched session module + const batchedSessionModule = await createBatchedSessionRouterModule({ + moduleAddress: DEFAULT_BATCHED_SESSION_ROUTER_MODULE, + smartAccountAddress, + sessionKeyManagerModule: sessionModule + }) + + // Set enabled call on session, only allows calling USDC contract transfer with <= 10 USDC + const sessionKeyData = encodeAbiParameters( + [ + { type: "address" }, + { type: "address" }, + { type: "address" }, + { type: "uint256" } + ], + [ + sessionKeyEOA, + token, // erc20 token address + recipient, // receiver address + parseUnits("10", 6) + ] + ) + // only requires that the caller is the session key + // can call anything using the mock session module + const sessionKeyData2 = encodeAbiParameters( + [{ type: "address" }], + [sessionKeyEOA] + ) + const erc20ModuleAddr = "0x000000D50C68705bd6897B2d17c7de32FB519fDA" + const mockSessionModuleAddr = "0x7Ba4a7338D7A90dfA465cF975Cc6691812C3772E" + const sessionTxData = await batchedSessionModule.createSessionData([ + { + validUntil: 0, + validAfter: 0, + sessionValidationModule: erc20ModuleAddr, + sessionPublicKey: sessionKeyEOA, + sessionKeyData: sessionKeyData + }, + { + validUntil: 0, + validAfter: 0, + sessionValidationModule: mockSessionModuleAddr, + sessionPublicKey: sessionKeyEOA, + sessionKeyData: sessionKeyData2 + } + ]) + + const setSessionAllowedTrx = { + to: DEFAULT_SESSION_KEY_MANAGER_MODULE, + data: sessionTxData.data + } + + const isDeployed = await smartAccount.isAccountDeployed() + if (!isDeployed) { + const { wait } = await smartAccount.deploy() + const { success } = await wait() + expect(success).toBe("true") + } + + const txArray: Transaction[] = [] + // Check if session module is enabled + const isEnabled = await smartAccount.isModuleEnabled( + DEFAULT_SESSION_KEY_MANAGER_MODULE + ) + if (!isEnabled) { + const enableModuleTrx = await smartAccount.getEnableModuleData( + DEFAULT_SESSION_KEY_MANAGER_MODULE + ) + txArray.push(enableModuleTrx) + } + // Check if batched session module is enabled + const isBRMenabled = await smartAccount.isModuleEnabled( + DEFAULT_BATCHED_SESSION_ROUTER_MODULE + ) + if (!isBRMenabled) { + // -----> enableModule batched session router module + const tx2 = await smartAccount.getEnableModuleData( + DEFAULT_BATCHED_SESSION_ROUTER_MODULE + ) + txArray.push(tx2) + } + txArray.push(setSessionAllowedTrx) + const userOpResponse1 = await smartAccount.sendTransaction(txArray, { + paymasterServiceData: { mode: PaymasterMode.SPONSORED } + }) // this user op will enable the modules and setup session allowed calls + const transactionDetails = await userOpResponse1.wait() + expect(transactionDetails.success).toBe("true") + Logger.log("Tx Hash: ", transactionDetails.receipt.transactionHash) + + const usdcBalance = await checkBalance(smartAccountAddress, token) + const nativeTokenBalance = await checkBalance(smartAccountAddress) + + expect(usdcBalance).toBeGreaterThan(0) + smartAccount = smartAccount.setActiveValidationModule(batchedSessionModule) + // WARNING* If the smart account does not have enough USDC, user op execution will FAIL + const encodedCall = encodeFunctionData({ + abi: parseAbi(["function transfer(address _to, uint256 _value)"]), + functionName: "transfer", + args: [recipient, parseUnits("0.001", 6)] + }) + const encodedCall2 = encodeFunctionData({ + abi: parseAbi(["function transfer(address _to, uint256 _value)"]), + functionName: "transfer", + args: [ + "0xd3C85Fdd3695Aee3f0A12B3376aCD8DC54020549", + parseUnits("0.001", 6) + ] + }) + const transferTx = { + to: "0x747A4168DB14F57871fa8cda8B5455D8C2a8e90a", + data: encodedCall + } + const transferTx2 = { + to: "0x747A4168DB14F57871fa8cda8B5455D8C2a8e90a", + data: encodedCall2 + } + const activeModule = smartAccount.activeValidationModule + expect(activeModule).toEqual(batchedSessionModule) + const maticBalanceBefore = await checkBalance(smartAccountAddress) + // failing with dummyTx because of invalid sessionKeyData + const userOpResponse2 = await smartAccount.sendTransaction( + [transferTx, transferTx2], + { + params: { + batchSessionParams: [ + { + sessionSigner: walletClient, + sessionValidationModule: erc20ModuleAddr + }, + { + sessionSigner: walletClient, + sessionValidationModule: mockSessionModuleAddr + } + ] + }, + paymasterServiceData: { + mode: PaymasterMode.SPONSORED + } + } + ) + const receipt = await userOpResponse2.wait() + console.log(receipt.userOpHash, "Batched user op hash") + expect(receipt.success).toBe("true") + expect(userOpResponse2.userOpHash).toBeTruthy() + expect(userOpResponse2.userOpHash).not.toBeNull() + const maticBalanceAfter = await checkBalance(smartAccountAddress) + expect(maticBalanceAfter).toEqual(maticBalanceBefore) + Logger.log( + `Tx at: https://jiffyscan.xyz/userOpHash/${userOpResponse2.userOpHash}?network=mumbai` + ) + }, 60000) +}) diff --git a/tests/paymaster/read.test.ts b/tests/paymaster/read.test.ts new file mode 100644 index 000000000..3b851100b --- /dev/null +++ b/tests/paymaster/read.test.ts @@ -0,0 +1,146 @@ +import { + http, + type Hex, + createPublicClient, + createWalletClient, + encodeFunctionData, + parseAbi +} from "viem" +import { privateKeyToAccount } from "viem/accounts" +import { beforeAll, describe, expect, test } from "vitest" +import { + type BiconomySmartAccountV2, + ERROR_MESSAGES, + createSmartAccountClient +} from "../../src/account" +import { + type FeeQuotesOrDataResponse, + PaymasterMode +} from "../../src/paymaster" +import { getConfig } from "../utils" + +describe("Paymaster:Read", () => { + const nftAddress = "0x1758f42Af7026fBbB559Dc60EcE0De3ef81f665e" + const { + chain, + chainId, + privateKey, + privateKeyTwo, + bundlerUrl, + paymasterUrl + } = getConfig() + const account = privateKeyToAccount(`0x${privateKey}`) + const accountTwo = privateKeyToAccount(`0x${privateKeyTwo}`) + const sender = account.address + const recipient = accountTwo.address + const publicClient = createPublicClient({ + chain, + transport: http() + }) + let [smartAccount, smartAccountTwo]: BiconomySmartAccountV2[] = [] + let [smartAccountAddress, smartAccountAddressTwo]: Hex[] = [] + + const [walletClient, walletClientTwo] = [ + createWalletClient({ + account, + chain, + transport: http() + }), + createWalletClient({ + account: accountTwo, + chain, + transport: http() + }) + ] + + beforeAll(async () => { + ;[smartAccount, smartAccountTwo] = await Promise.all( + [walletClient, walletClientTwo].map((client) => + createSmartAccountClient({ + chainId, + signer: client, + bundlerUrl, + paymasterUrl + }) + ) + ) + ;[smartAccountAddress, smartAccountAddressTwo] = await Promise.all( + [smartAccount, smartAccountTwo].map((account) => + account.getAccountAddress() + ) + ) + }) + + test.concurrent( + "should expect several feeQuotes in resonse to empty tokenInfo fields", + async () => { + const encodedCall = encodeFunctionData({ + abi: parseAbi(["function safeMint(address _to)"]), + functionName: "safeMint", + args: [recipient] + }) + + const transaction = { + to: nftAddress, // NFT address + data: encodedCall + } + + const feeQuotesResponse = await smartAccount.getTokenFees(transaction, { + paymasterServiceData: { mode: PaymasterMode.ERC20 } + }) + + expect(feeQuotesResponse.feeQuotes?.length).toBeGreaterThan(1) + } + ) + + test.concurrent( + "should get supported tokens from the paymaster", + async () => { + const tokens = await smartAccount.getSupportedTokens() + + expect(tokens.length).toBeGreaterThan(0) + expect(tokens[0]).toHaveProperty("tokenAddress") + expect(tokens[0]).toHaveProperty("symbol") + expect(tokens[0]).toHaveProperty("decimal") + expect(tokens[0]).toHaveProperty("premiumPercentage") + expect(tokens[0]).toHaveProperty("logoUrl") + expect(tokens[0]).toHaveProperty("balance") + }, + 60000 + ) + + test.concurrent( + "should throw and error if missing field for ERC20 Paymaster user op", + async () => { + const encodedCall = encodeFunctionData({ + abi: parseAbi(["function safeMint(address _to)"]), + functionName: "safeMint", + args: [recipient] + }) + + const transaction = { + to: nftAddress, // NFT address + data: encodedCall + } + + const feeQuotesResponse: FeeQuotesOrDataResponse = + await smartAccount.getTokenFees(transaction, { + paymasterServiceData: { + mode: PaymasterMode.ERC20, + preferredToken: "0x747A4168DB14F57871fa8cda8B5455D8C2a8e90a" + } + }) + + expect(async () => + smartAccount.sendTransaction(transaction, { + paymasterServiceData: { + mode: PaymasterMode.ERC20, + feeQuote: feeQuotesResponse.feeQuotes?.[0] + }, + simulationType: "validation" + }) + ).rejects.toThrow(ERROR_MESSAGES.SPENDER_REQUIRED) + }, + 60000 + ) +}) diff --git a/tests/paymaster/write.test.ts b/tests/paymaster/write.test.ts new file mode 100644 index 000000000..cb1170318 --- /dev/null +++ b/tests/paymaster/write.test.ts @@ -0,0 +1,303 @@ +import { + http, + type Hex, + createPublicClient, + createWalletClient, + encodeFunctionData, + parseAbi +} from "viem" +import { generatePrivateKey, privateKeyToAccount } from "viem/accounts" +import { beforeAll, describe, expect, test } from "vitest" +import { + type BiconomySmartAccountV2, + NATIVE_TOKEN_ALIAS, + createSmartAccountClient +} from "../../src/account" +import { PaymasterMode } from "../../src/paymaster" +import { testOnlyOnOptimism } from "../setupFiles" +import { checkBalance, getConfig, nonZeroBalance, topUp } from "../utils" + +describe("Paymaster:Write", () => { + const nftAddress = "0x1758f42Af7026fBbB559Dc60EcE0De3ef81f665e" + const { + chain, + chainId, + privateKey, + privateKeyTwo, + bundlerUrl, + paymasterUrl + } = getConfig() + const account = privateKeyToAccount(`0x${privateKey}`) + const accountTwo = privateKeyToAccount(`0x${privateKeyTwo}`) + const sender = account.address + const recipient = accountTwo.address + const publicClient = createPublicClient({ + chain, + transport: http() + }) + let [smartAccount, smartAccountTwo]: BiconomySmartAccountV2[] = [] + let [smartAccountAddress, smartAccountAddressTwo]: Hex[] = [] + + const [walletClient, walletClientTwo] = [ + createWalletClient({ + account, + chain, + transport: http() + }), + createWalletClient({ + account: accountTwo, + chain, + transport: http() + }) + ] + + beforeAll(async () => { + ;[smartAccount, smartAccountTwo] = await Promise.all( + [walletClient, walletClientTwo].map((client) => + createSmartAccountClient({ + chainId, + signer: client, + bundlerUrl, + paymasterUrl + }) + ) + ) + ;[smartAccountAddress, smartAccountAddressTwo] = await Promise.all( + [smartAccount, smartAccountTwo].map((account) => + account.getAccountAddress() + ) + ) + }) + + test("should mint an NFT with sponsorship", async () => { + await nonZeroBalance(smartAccountAddress) + + const encodedCall = encodeFunctionData({ + abi: parseAbi(["function safeMint(address to) public"]), + functionName: "safeMint", + args: [recipient] + }) + + const transaction = { + to: nftAddress, // NFT address + data: encodedCall + } + + const balance = await checkBalance(recipient, nftAddress) + const maticBalanceBefore = await checkBalance(smartAccountAddress) + + const response = await smartAccount.sendTransaction(transaction, { + paymasterServiceData: { mode: PaymasterMode.SPONSORED }, + simulationType: "validation" + }) + + const userOpReceipt = await response.wait(3) + expect(userOpReceipt.userOpHash).toBeTruthy() + expect(userOpReceipt.success).toBe("true") + + const maticBalanceAfter = await checkBalance(smartAccountAddress) + + expect(maticBalanceAfter).toEqual(maticBalanceBefore) + + const newBalance = (await checkBalance(recipient, nftAddress)) as bigint + + expect(newBalance - balance).toBe(1n) + }, 60000) + + test("should deploy a smart account with sponsorship", async () => { + const newPrivateKey = generatePrivateKey() + const newAccount = privateKeyToAccount(newPrivateKey) + + const newViemWallet = createWalletClient({ + account: newAccount, + chain, + transport: http() + }) + + const smartAccount = await createSmartAccountClient({ + signer: newViemWallet, + paymasterUrl, + bundlerUrl + }) + + const smartAccountAddress = await smartAccount.getAccountAddress() + const balance = await publicClient.getBalance({ + address: smartAccountAddress + }) + expect(balance).toBe(0n) + + const { wait } = await smartAccount.deploy({ + paymasterServiceData: { mode: PaymasterMode.SPONSORED } + }) + const { success } = await wait() + + const byteCode = await publicClient.getBytecode({ + address: smartAccountAddress + }) + expect(success).toBe("true") + expect(byteCode).toBeTruthy() + }, 60000) + + test("should withdraw nativeToken with sponsorship", async () => { + await nonZeroBalance(smartAccountAddress) + + const balanceOfSABefore = await checkBalance(smartAccountAddress) + const balanceOfRecipientBefore = await checkBalance(sender) + + const { wait } = await smartAccount.withdraw( + [ + { + address: NATIVE_TOKEN_ALIAS, + amount: BigInt(1), + recipient: sender + } + ], + null, + { + paymasterServiceData: { mode: PaymasterMode.SPONSORED } + } + ) + + const { + receipt: { transactionHash }, + userOpHash, + success + } = await wait() + + expect(userOpHash).toBeTruthy() + expect(success).toBe("true") + expect(transactionHash).toBeTruthy() + + const balanceOfSAAfter = await checkBalance(smartAccountAddress) + const balanceOfRecipientAfter = await checkBalance(sender) + + expect(balanceOfSABefore - balanceOfSAAfter).toBe(1n) + expect(balanceOfRecipientAfter - balanceOfRecipientBefore).toBe(1n) + }, 25000) + + testOnlyOnOptimism( + "should mint an NFT on optimism with sponsorship", + async () => { + const encodedCall = encodeFunctionData({ + abi: parseAbi(["function safeMint(address to) public"]), + functionName: "safeMint", + args: [recipient] + }) + + const transaction = { + to: nftAddress, // NFT address + data: encodedCall + } + + const balance = await checkBalance(recipient, nftAddress) + + const maticBalanceBefore = await checkBalance(smartAccountAddress) + + const response = await smartAccount.sendTransaction(transaction, { + paymasterServiceData: { mode: PaymasterMode.SPONSORED }, + simulationType: "validation_and_execution" + }) + + const userOpReceipt = await response.wait(3) + expect(userOpReceipt.userOpHash).toBeTruthy() + expect(userOpReceipt.success).toBe("true") + + const maticBalanceAfter = await checkBalance(smartAccountAddress) + expect(maticBalanceAfter).toEqual(maticBalanceBefore) + const newBalance = (await checkBalance(recipient, nftAddress)) as bigint + + expect(newBalance - balance).toBe(1n) + }, + 50000 + ) + + test("should withdraw nativeToken and an erc20 token", async () => { + const token = "0x747A4168DB14F57871fa8cda8B5455D8C2a8e90a" + + await nonZeroBalance(smartAccountAddress, token) + await nonZeroBalance(smartAccountAddress) + + const balanceOfSABefore = await checkBalance(smartAccountAddress) + const balanceOfRecipientBefore = await checkBalance(sender) + const tokenBalanceOfSABefore = await checkBalance( + smartAccountAddress, + token + ) + const tokenBalanceOfRecipientBefore = await checkBalance(sender, token) + + const { wait } = await smartAccount.withdraw( + [ + { address: token, amount: BigInt(1) }, + { address: NATIVE_TOKEN_ALIAS, amount: BigInt(1) } + ], + sender, + { + paymasterServiceData: { mode: PaymasterMode.SPONSORED } + } + ) + + const { + receipt: { transactionHash }, + userOpHash, + success + } = await wait() + + expect(userOpHash).toBeTruthy() + expect(success).toBe("true") + expect(transactionHash).toBeTruthy() + + const balanceOfSAAfter = await checkBalance(smartAccountAddress) + const balanceOfRecipientAfter = await checkBalance(sender) + const tokenBalanceOfSAAfter = await checkBalance(smartAccountAddress, token) + const tokenBalanceOfRecipientAfter = await checkBalance(sender, token) + + expect(balanceOfSABefore - balanceOfSAAfter).toBe(1n) + expect(balanceOfRecipientAfter - balanceOfRecipientBefore).toBe(1n) + + expect(tokenBalanceOfSAAfter - tokenBalanceOfSABefore).toBe(-1n) + expect(tokenBalanceOfRecipientAfter - tokenBalanceOfRecipientBefore).toBe( + 1n + ) + }, 60000) + + test("should withdraw all native token", async () => { + await nonZeroBalance(smartAccountAddress) + const balanceOfSABefore = await checkBalance(smartAccountAddress) + const balanceOfRecipientBefore = await checkBalance(sender) + + const { wait } = await smartAccount.withdraw( + [] /* null or undefined or [] */, + sender, + { + paymasterServiceData: { mode: PaymasterMode.SPONSORED } // Will leave no dust + } + ) + + const { + receipt: { transactionHash }, + userOpHash, + success + } = await wait() + + expect(userOpHash).toBeTruthy() + expect(success).toBe("true") + expect(transactionHash).toBeTruthy() + + const balanceOfSAAfter = await checkBalance(smartAccountAddress) + const balanceOfRecipientAfter = await checkBalance(sender) + + expect(balanceOfSAAfter).toBe(0n) + expect(balanceOfRecipientAfter).toBe( + balanceOfSABefore + balanceOfRecipientBefore + ) + + // Teardown: send back the native token to the smart account + const teardownHash = await walletClient.sendTransaction({ + to: smartAccountAddress, + value: balanceOfSABefore, + account, + chain + }) + expect(teardownHash).toBeTruthy() + }, 60000) +}) diff --git a/tests/setup-e2e-tests.ts b/tests/setup-e2e-tests.ts deleted file mode 100644 index 4d3d8af77..000000000 --- a/tests/setup-e2e-tests.ts +++ /dev/null @@ -1,150 +0,0 @@ -import { createWalletClient, http, createPublicClient } from "viem"; -import { JsonRpcProvider } from "@ethersproject/providers"; -import { Wallet } from "@ethersproject/wallet"; -import { privateKeyToAccount } from "viem/accounts"; -import { WalletClientSigner } from "@alchemy/aa-core"; -import { config } from "dotenv"; -import { E2E_TEST_CHAINS } from "./chains.config"; - -config(); - -beforeAll(async () => { - envVarCheck(); - - const privateKeyOne: `0x${string}` = `0x${process.env.E2E_PRIVATE_KEY_ONE}`; - const privateKeyTwo: `0x${string}` = `0x${process.env.E2E_PRIVATE_KEY_TWO}`; - const walletOne = privateKeyToAccount(privateKeyOne); - const walletTwo = privateKeyToAccount(privateKeyTwo); - - const promises = E2E_TEST_CHAINS.map((chain) => { - const ethersProvider = new JsonRpcProvider(chain.viemChain.rpcUrls.default.http[0]); - const ethersSignerOne = new Wallet(privateKeyOne, ethersProvider); - const ethersSignerTwo = new Wallet(privateKeyTwo, ethersProvider); - - const publicClient = createPublicClient({ - chain: chain.viemChain, - transport: http(), - }); - - const viemWalletClientOne = createWalletClient({ - account: walletOne, - chain: chain.viemChain, - transport: http(chain.viemChain.rpcUrls.default.http[0]), - }); - const viemWalletClientTwo = createWalletClient({ - account: walletTwo, - chain: chain.viemChain, - transport: http(chain.viemChain.rpcUrls.default.http[0]), - }); - const walletClientSignerOne = new WalletClientSigner(viemWalletClientOne, "viem"); - const walletClientSignerTwo = new WalletClientSigner(viemWalletClientTwo, "viem"); - - return Promise.all([ - Promise.all([ - { - ...chain, - publicClient, - account: walletOne, - publicAddress: walletOne.address, - viemWallet: viemWalletClientOne, - alchemyWalletClientSigner: walletClientSignerOne, - ethersProvider, - ethersSigner: ethersSignerOne, - privateKey: privateKeyOne, - }, - publicClient.getBalance({ - address: walletOne.address, - }), - ]), - Promise.all([ - { - ...chain, - publicClient, - account: walletTwo, - publicAddress: walletTwo.address, - viemWallet: viemWalletClientTwo, - alchemyWalletClientSigner: walletClientSignerTwo, - ethersProvider, - ethersSigner: ethersSignerTwo, - privateKey: privateKeyTwo, - }, - publicClient.getBalance({ - address: walletTwo.address, - }), - ]), - ]); - }); - const balancesPerChain = await Promise.all(promises); - - // @ts-ignore - testDataPerChain = balancesPerChain.map((dataAndBalanceArray) => { - const sortedBalances = dataAndBalanceArray - .map(([datum, balance]) => ({ - ...datum, - balance, - })) - .sort((a, b) => { - if (a.balance > b.balance) { - return -1; - } else if (a.balance > b.balance) { - return 1; - } else { - return 0; - } - }); - - const whaleBalance = sortedBalances[0]; - const minnowBalance = sortedBalances[1]; - - const commonData = { - publicClient: whaleBalance.publicClient, - chainId: whaleBalance.chainId, - bundlerUrl: whaleBalance.bundlerUrl, - deploymentCost: whaleBalance.deploymentCost, - nftAddress: whaleBalance.nftAddress, - entryPointAddress: whaleBalance.entryPointAddress, - viemChain: whaleBalance.viemChain, - ethersProvider: whaleBalance.ethersProvider, - paymasterUrl: whaleBalance.paymasterUrl, - biconomyPaymasterApiKey: whaleBalance.biconomyPaymasterApiKey, - }; - - const datum = { - ...commonData, - whale: { - balance: whaleBalance.balance, - viemWallet: whaleBalance.viemWallet, - alchemyWalletClientSigner: whaleBalance.alchemyWalletClientSigner, - publicAddress: whaleBalance.publicAddress, - account: whaleBalance.account, - ethersSigner: whaleBalance.ethersSigner, - privateKey: whaleBalance.privateKey, - }, - minnow: { - balance: minnowBalance.balance, - viemWallet: minnowBalance.viemWallet, - alchemyWalletClientSigner: minnowBalance.alchemyWalletClientSigner, - publicAddress: minnowBalance.publicAddress, - account: minnowBalance.account, - ethersSigner: whaleBalance.ethersSigner, - privateKey: minnowBalance.privateKey, - }, - }; - return datum; - }); -}); - -const envVarCheck = () => { - const REQUIRED_FIELDS = [ - "E2E_PRIVATE_KEY_ONE", - "E2E_PRIVATE_KEY_TWO", - "E2E_BICO_PAYMASTER_KEY_MUMBAI", - "E2E_BICO_PAYMASTER_KEY_BASE", - "E2E_BICO_PAYMASTER_KEY_OP", - ]; - const hasFields = REQUIRED_FIELDS.every((field) => !!process.env[field]); - if (!hasFields) { - console.error("Missing env var"); - process.exit(1); - } -}; diff --git a/tests/setup-unit-tests.ts b/tests/setup-unit-tests.ts deleted file mode 100644 index d2fdba7d3..000000000 --- a/tests/setup-unit-tests.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { createWalletClient, http, createPublicClient } from "viem"; -import { WalletClientSigner } from "@alchemy/aa-core"; -import { JsonRpcProvider } from "@ethersproject/providers"; -import { Wallet } from "@ethersproject/wallet"; -import { UNIT_TEST_CHAIN } from "./chains.config"; -import { privateKeyToAccount, generatePrivateKey } from "viem/accounts"; - -beforeAll(() => { - const { chainId, bundlerUrl, viemChain, entryPointAddress, deploymentCost, nftAddress } = UNIT_TEST_CHAIN; - const privateKeyOne = generatePrivateKey(); - const accountOne = privateKeyToAccount(privateKeyOne); - - const ethersProvider = new JsonRpcProvider(viemChain.rpcUrls.default.http[0]); - const ethersSignerOne = new Wallet(privateKeyOne, ethersProvider); - - const viemWalletClientOne = createWalletClient({ - account: accountOne, - chain: viemChain, - transport: http(viemChain.rpcUrls.default.http[0]), - }); - - const walletClientSignerOne = new WalletClientSigner(viemWalletClientOne, "viem"); - const publicAddressOne = accountOne.address; - const publicClient = createPublicClient({ - chain: viemChain, - transport: http(), - }); - - const privateKeyTwo = generatePrivateKey(); - const accountTwo = privateKeyToAccount(privateKeyTwo); - - const ethersSignerTwo = new Wallet(privateKeyTwo, ethersProvider); - - const viemWalletClientTwo = createWalletClient({ - account: accountTwo, - chain: viemChain, - transport: http(viemChain.rpcUrls.default.http[0]), - }); - const walletClientSignerTwo = new WalletClientSigner(viemWalletClientTwo, "viem"); - const publicAddressTwo = accountTwo.address; - - const whale = { - viemWallet: viemWalletClientOne, - alchemyWalletClientSigner: walletClientSignerOne, - balance: 0, - publicAddress: publicAddressOne, - ethersSigner: ethersSignerOne, - account: accountOne, - privateKey: privateKeyOne, - }; - - const minnow = { - viemWallet: viemWalletClientTwo, - alchemyWalletClientSigner: walletClientSignerTwo, - balance: 0, - publicAddress: publicAddressTwo, - ethersSigner: ethersSignerTwo, - account: accountTwo, - privateKey: privateKeyTwo, - }; - - // @ts-ignore - testDataPerChain = [{ nftAddress, deploymentCost, whale, minnow, publicClient, chainId, bundlerUrl, entryPointAddress, viemChain, ethersProvider }]; -}); diff --git a/tests/setupFiles.ts b/tests/setupFiles.ts new file mode 100644 index 000000000..fea74d4a2 --- /dev/null +++ b/tests/setupFiles.ts @@ -0,0 +1,9 @@ +import { test } from "vitest" + +export const testOnlyOnSpecificNetwork = (chainId: number) => { + return Number(process.env.CHAIN_ID || 0) === chainId ? test : test.skip +} + +export const testOnlyOnOptimism = testOnlyOnSpecificNetwork(10) +export const testOnlyOnArbitrum = testOnlyOnSpecificNetwork(42161) +export const testOnlyOnBaseSopelia = testOnlyOnSpecificNetwork(84532) diff --git a/tests/utils.ts b/tests/utils.ts index b7fd5ea13..69b88d31b 100644 --- a/tests/utils.ts +++ b/tests/utils.ts @@ -1,47 +1,189 @@ -import { Hex, PublicClient, parseAbi } from "viem"; +import { + http, + type Chain, + type Hex, + createPublicClient, + createWalletClient, + parseAbi +} from "viem" +import { privateKeyToAccount } from "viem/accounts" +import { Logger, getChain } from "../src/account" +import { + extractChainIdFromBundlerUrl, + extractChainIdFromPaymasterUrl +} from "../src/bundler" + +export const getEnvVars = () => { + const fields = [ + "BUNDLER_URL", + "E2E_PRIVATE_KEY_ONE", + "E2E_PRIVATE_KEY_TWO", + "E2E_BICO_PAYMASTER_KEY_AMOY", + "E2E_BICO_PAYMASTER_KEY_BASE", + "CHAIN_ID" + ] + const errorFields = fields.filter((field) => !process.env[field]) + if (errorFields.length) { + throw new Error( + `Missing environment variable${ + errorFields.length > 1 ? "s" : "" + }: ${errorFields.join(", ")}` + ) + } + return { + bundlerUrl: process.env.BUNDLER_URL || "", + privateKey: process.env.E2E_PRIVATE_KEY_ONE || "", + privateKeyTwo: process.env.E2E_PRIVATE_KEY_TWO || "", + paymasterUrl: `https://paymaster.biconomy.io/api/v1/80002/${ + process.env.E2E_BICO_PAYMASTER_KEY_AMOY || "" + }`, + paymasterUrlTwo: `https://paymaster.biconomy.io/api/v1/84532/${ + process.env.E2E_BICO_PAYMASTER_KEY_BASE || "" + }`, + chainId: process.env.CHAIN_ID || "0" + } +} + +export type TestConfig = { + chain: Chain + chainId: number + paymasterUrl: string + paymasterUrlTwo: string + bundlerUrl: string + privateKey: string + privateKeyTwo: string +} +export const getConfig = (): TestConfig => { + const { + paymasterUrl, + paymasterUrlTwo, + bundlerUrl, + chainId: chainIdFromEnv, + privateKey, + privateKeyTwo + } = getEnvVars() + const chains = [Number.parseInt(chainIdFromEnv)] + const chainId = chains[0] + const chain = getChain(chainId) + + try { + const chainIdFromBundlerUrl = extractChainIdFromBundlerUrl(bundlerUrl) + chains.push(chainIdFromBundlerUrl) + } catch (e) {} + + try { + const chainIdFromPaymasterUrl = extractChainIdFromPaymasterUrl(paymasterUrl) + chains.push(chainIdFromPaymasterUrl) + } catch (e) {} + + const allChainsMatch = chains.every((chain) => chain === chains[0]) + + if (!allChainsMatch) { + throw new Error("Chain IDs do not match") + } + + return { + chain, + chainId, + paymasterUrl, + paymasterUrlTwo, + bundlerUrl, + privateKey, + privateKeyTwo + } +} + +export const checkBalance = (owner: Hex, tokenAddress?: Hex) => { + const { chain } = getConfig() + + const publicClient = createPublicClient({ + chain, + transport: http() + }) -export const checkBalance = (publicClient: PublicClient, address: Hex, tokenAddress?: Hex) => { if (!tokenAddress) { - return publicClient.getBalance({ address }); + return publicClient.getBalance({ address: owner }) + } + return publicClient.readContract({ + address: tokenAddress, + abi: parseAbi([ + "function balanceOf(address owner) view returns (uint balance)" + ]), + functionName: "balanceOf", + args: [owner] + }) +} + +export const nonZeroBalance = async (address: Hex, tokenAddress?: Hex) => { + const balance = await checkBalance(address, tokenAddress) + if (balance > BigInt(0)) return + throw new Error( + `Insufficient balance ${ + tokenAddress ? `of token ${tokenAddress}` : "of native token" + } during test setup of owner: ${address}` + ) +} + +export const topUp = async ( + recipient: Hex, + amount = BigInt(1000000), + token?: Hex +) => { + const { chain, privateKey } = getConfig() + const account = privateKeyToAccount(`0x${privateKey}`) + const sender = account.address + + const publicClient = createPublicClient({ + chain, + transport: http() + }) + + const balanceOfSender = await checkBalance(sender, token) + const balanceOfRecipient = await checkBalance(recipient, token) + + if (balanceOfRecipient > amount) { + Logger.log( + `balanceOfRecipient (${recipient}) already has enough ${ + token ?? "native token" + } (${balanceOfRecipient}) during topUp` + ) + return await Promise.resolve() + } + + if (balanceOfSender < amount) { + throw new Error( + `Insufficient ${ + token ? token : "" + }balance during test setup: ${balanceOfSender}` + ) + } + + Logger.log(`topping up (${recipient}): (${balanceOfRecipient}).`) + + const walletClient = createWalletClient({ + account, + chain, + transport: http() + }) + + if (token) { + const hash = await walletClient.writeContract({ + address: token, + abi: parseAbi([ + "function transfer(address recipient, uint256 amount) external" + ]), + functionName: "transfer", + args: [recipient, amount] + }) + await publicClient.waitForTransactionReceipt({ hash }) } else { - return publicClient.readContract({ - address: tokenAddress, - abi: parseAbi(["function balanceOf(address owner) view returns (uint balance)"]), - functionName: "balanceOf", - // @ts-ignore - args: [address], - }); - } -}; - -export const getMockBundlerUrl = (chainId: number) => `https://bundler.biconomy.io/api/v2/${chainId}/nJPK7B3ru.dd7f7861-190d-41bd-af80-6877f74b8f14`; - -// TODO(Joe): Make human readable -export const entryPointABI = [ - { - inputs: [ - { - components: [ - { internalType: "address", name: "sender", type: "address" }, - { internalType: "uint256", name: "nonce", type: "uint256" }, - { internalType: "bytes", name: "initCode", type: "bytes" }, - { internalType: "bytes", name: "callData", type: "bytes" }, - { internalType: "uint256", name: "callGasLimit", type: "uint256" }, - { internalType: "uint256", name: "verificationGasLimit", type: "uint256" }, - { internalType: "uint256", name: "preVerificationGas", type: "uint256" }, - { internalType: "uint256", name: "maxFeePerGas", type: "uint256" }, - { internalType: "uint256", name: "maxPriorityFeePerGas", type: "uint256" }, - { internalType: "bytes", name: "paymasterAndData", type: "bytes" }, - { internalType: "bytes", name: "signature", type: "bytes" }, - ], - internalType: "struct UserOperation", - name: "userOp", - type: "tuple", - }, - ], - name: "getUserOpHash", - outputs: [{ internalType: "bytes32", name: "", type: "bytes32" }], - stateMutability: "view", - type: "function", - }, -]; + const hash = await walletClient.sendTransaction({ + to: recipient, + value: amount + }) + await publicClient.waitForTransactionReceipt({ hash }) + } +} + +export const getBundlerUrl = (chainId: number) => + `https://bundler.biconomy.io/api/v2/${chainId}/nJPK7B3ru.dd7f7861-190d-41bd-af80-6877f74b8f14` diff --git a/tests/vitest.config.ts b/tests/vitest.config.ts new file mode 100644 index 000000000..d7dd2a794 --- /dev/null +++ b/tests/vitest.config.ts @@ -0,0 +1,35 @@ +import { join } from "node:path" +import { defineConfig } from "vitest/config" + +export default defineConfig({ + test: { + coverage: { + all: false, + provider: "v8", + reporter: process.env.CI + ? ["json-summary", "json"] + : ["text", "json", "html"], + exclude: [ + "**/errors/utils.ts", + "**/_cjs/**", + "**/_esm/**", + "**/_types/**", + "**/*.test.ts", + "**/test/**" + ], + include: ["src/**/*.ts"], + thresholds: { + lines: 80, + functions: 50, + branches: 60, + statements: 80 + } + }, + environment: "node", + include: ["tests/**/*.test.ts"], + setupFiles: [join(__dirname, "./setupFiles.ts")], + globalSetup: [join(__dirname, "./globalSetup.ts")], + // hookTimeout: 20_000, + testTimeout: 20_000 + } +}) diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json deleted file mode 100644 index e4b76f44d..000000000 --- a/tsconfig.eslint.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["packages/**/*"] -} diff --git a/tsconfig.json b/tsconfig.json deleted file mode 100644 index 8172cdac6..000000000 --- a/tsconfig.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "compilerOptions": { - "target": "es2020", - "module": "commonjs", - "declaration": true, - "sourceMap": true, - "strict": true, - "esModuleInterop": true, - "lib": ["es2020"], - "types": ["node", "jest"] - }, - "include": ["packages/**/*"], - "references": [ - { "path": "./packages/transak" }, - { "path": "./packages/bundler" }, - { "path": "./packages/particle-auth" }, - { "path": "./packages/paymaster" }, - { "path": "./packages/account" }, - { "path": "./packages/common" }, - { "path": "./packages/modules" }, - ] -} diff --git a/tsconfig.settings.json b/tsconfig.settings.json deleted file mode 100644 index fbd122a5e..000000000 --- a/tsconfig.settings.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2019" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, - "module": "CommonJS" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, - "allowJs": false /* Allow javascript files to be compiled. */, - "declaration": true /* Generates corresponding '.d.ts' file. */, - "sourceMap": true /* Generates corresponding '.map' file. */, - "strict": true /* Enable all strict type-checking options. */, - "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, - "strictNullChecks": true /* Enable strict null checks. */, - "strictFunctionTypes": true /* Enable strict checking of function types. */, - "strictBindCallApply": true /* Enable strict 'bind', 'call', and 'apply' methods on functions. */, - "strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */, - "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */, - "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */, - "noUnusedParameters": true /* Report errors on unused parameters. */, - "noImplicitReturns": true /* Report error when not all code paths in function return a value. */, - "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */, - "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */, - "allowSyntheticDefaultImports": true /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */, - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, - "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */, - "skipLibCheck": true /* Skip type checking of declaration files. */, - "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, - "resolveJsonModule": true - } -} diff --git a/tsconfig/tsconfig.base.json b/tsconfig/tsconfig.base.json new file mode 100644 index 000000000..671115660 --- /dev/null +++ b/tsconfig/tsconfig.base.json @@ -0,0 +1,32 @@ +{ + "include": [], + "compilerOptions": { + "incremental": false, + "useDefineForClassFields": true, + "noFallthroughCasesInSwitch": true, + "noImplicitReturns": true, + "useUnknownInCatchVariables": true, + "noImplicitOverride": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "allowJs": false, + "checkJs": false, + "esModuleInterop": false, + "allowSyntheticDefaultImports": false, + "forceConsistentCasingInFileNames": true, + "verbatimModuleSyntax": true, + "importHelpers": true, + "moduleResolution": "NodeNext", + "module": "NodeNext", + "target": "ES2021", + "lib": ["ES2022"], + "skipLibCheck": true, + "noErrorTruncation": true, + "noEmit": true, + "strict": true + }, + "tsc-alias": { + "resolveFullPaths": true, + "verbose": false + } +} \ No newline at end of file diff --git a/tsconfig/tsconfig.cjs.json b/tsconfig/tsconfig.cjs.json new file mode 100644 index 000000000..d5607ac12 --- /dev/null +++ b/tsconfig/tsconfig.cjs.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "commonjs", + "outDir": "../dist/_cjs", + "removeComments": true, + "verbatimModuleSyntax": false, + "noEmit": false + } +} diff --git a/tsconfig/tsconfig.esm.json b/tsconfig/tsconfig.esm.json new file mode 100644 index 000000000..136a81fc1 --- /dev/null +++ b/tsconfig/tsconfig.esm.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "es2015", + "outDir": "../dist/_esm", + "noEmit": false + } +} diff --git a/tsconfig/tsconfig.json b/tsconfig/tsconfig.json new file mode 100644 index 000000000..2c9c1e634 --- /dev/null +++ b/tsconfig/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "./tsconfig.base.json", + "include": [ + "../src/" + ], + "exclude": [ + "../src/**/*.test.ts", + "../src/**/*.test-d.ts", + "../src/**/*.bench.ts" + ], + "compilerOptions": { + "moduleResolution": "node", + "sourceMap": true, + "rootDir": "../src" + } +} \ No newline at end of file diff --git a/tsconfig/tsconfig.types.json b/tsconfig/tsconfig.types.json new file mode 100644 index 000000000..bb70b996d --- /dev/null +++ b/tsconfig/tsconfig.types.json @@ -0,0 +1,12 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "esnext", + "outDir": "../dist/_esm", + "declarationDir": "../dist/_types", + "emitDeclarationOnly": true, + "declaration": true, + "declarationMap": true, + "noEmit": false + } +} diff --git a/packages/account/typedoc.json b/typedoc.json similarity index 100% rename from packages/account/typedoc.json rename to typedoc.json diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index 02caba64f..000000000 --- a/yarn.lock +++ /dev/null @@ -1,9660 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@aashutoshrathi/word-wrap@^1.2.3": - version "1.2.6" - resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" - integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== - -"@adraffy/ens-normalize@1.10.0": - version "1.10.0" - resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz#d2a39395c587e092d77cbbc80acf956a54f38bf7" - integrity sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q== - -"@alchemy/aa-core@^3.1.1": - version "3.4.0" - resolved "https://registry.yarnpkg.com/@alchemy/aa-core/-/aa-core-3.4.0.tgz#08e514bf2f97a9c1452424a7f7915aa48daf4db2" - integrity sha512-kEqsMwweMxQU6b8mKNmkUacyZRxdU7WBBiAYNmGxJK5djOdsGlfCBZGHu2AyAb8ogfrGWX8J+uVuYTnCIZS6ew== - dependencies: - abitype "^0.8.3" - eventemitter3 "^5.0.1" - viem "^2.7.8" - zod "^3.22.4" - -"@ampproject/remapping@^2.2.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4" - integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw== - dependencies: - "@jridgewell/gen-mapping" "^0.3.5" - "@jridgewell/trace-mapping" "^0.3.24" - -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.23.5": - version "7.23.5" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.5.tgz#9009b69a8c602293476ad598ff53e4562e15c244" - integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA== - dependencies: - "@babel/highlight" "^7.23.4" - chalk "^2.4.2" - -"@babel/compat-data@^7.23.5": - version "7.23.5" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.5.tgz#ffb878728bb6bdcb6f4510aa51b1be9afb8cfd98" - integrity sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw== - -"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.23.9": - version "7.24.0" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.24.0.tgz#56cbda6b185ae9d9bed369816a8f4423c5f2ff1b" - integrity sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw== - dependencies: - "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.23.5" - "@babel/generator" "^7.23.6" - "@babel/helper-compilation-targets" "^7.23.6" - "@babel/helper-module-transforms" "^7.23.3" - "@babel/helpers" "^7.24.0" - "@babel/parser" "^7.24.0" - "@babel/template" "^7.24.0" - "@babel/traverse" "^7.24.0" - "@babel/types" "^7.24.0" - convert-source-map "^2.0.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.3" - semver "^6.3.1" - -"@babel/generator@^7.23.6", "@babel/generator@^7.7.2": - version "7.23.6" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.6.tgz#9e1fca4811c77a10580d17d26b57b036133f3c2e" - integrity sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw== - dependencies: - "@babel/types" "^7.23.6" - "@jridgewell/gen-mapping" "^0.3.2" - "@jridgewell/trace-mapping" "^0.3.17" - jsesc "^2.5.1" - -"@babel/helper-compilation-targets@^7.23.6": - version "7.23.6" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz#4d79069b16cbcf1461289eccfbbd81501ae39991" - integrity sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ== - dependencies: - "@babel/compat-data" "^7.23.5" - "@babel/helper-validator-option" "^7.23.5" - browserslist "^4.22.2" - lru-cache "^5.1.1" - semver "^6.3.1" - -"@babel/helper-environment-visitor@^7.22.20": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" - integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== - -"@babel/helper-function-name@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" - integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== - dependencies: - "@babel/template" "^7.22.15" - "@babel/types" "^7.23.0" - -"@babel/helper-hoist-variables@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" - integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== - dependencies: - "@babel/types" "^7.22.5" - -"@babel/helper-module-imports@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0" - integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== - dependencies: - "@babel/types" "^7.22.15" - -"@babel/helper-module-transforms@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz#d7d12c3c5d30af5b3c0fcab2a6d5217773e2d0f1" - integrity sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ== - dependencies: - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-module-imports" "^7.22.15" - "@babel/helper-simple-access" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/helper-validator-identifier" "^7.22.20" - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0": - version "7.24.0" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz#945681931a52f15ce879fd5b86ce2dae6d3d7f2a" - integrity sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w== - -"@babel/helper-simple-access@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" - integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== - dependencies: - "@babel/types" "^7.22.5" - -"@babel/helper-split-export-declaration@^7.22.6": - version "7.22.6" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" - integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== - dependencies: - "@babel/types" "^7.22.5" - -"@babel/helper-string-parser@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz#9478c707febcbbe1ddb38a3d91a2e054ae622d83" - integrity sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ== - -"@babel/helper-validator-identifier@^7.22.20": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" - integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== - -"@babel/helper-validator-option@^7.23.5": - version "7.23.5" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz#907a3fbd4523426285365d1206c423c4c5520307" - integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw== - -"@babel/helpers@^7.24.0": - version "7.24.0" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.24.0.tgz#a3dd462b41769c95db8091e49cfe019389a9409b" - integrity sha512-ulDZdc0Aj5uLc5nETsa7EPx2L7rM0YJM8r7ck7U73AXi7qOV44IHHRAYZHY6iU1rr3C5N4NtTmMRUJP6kwCWeA== - dependencies: - "@babel/template" "^7.24.0" - "@babel/traverse" "^7.24.0" - "@babel/types" "^7.24.0" - -"@babel/highlight@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.23.4.tgz#edaadf4d8232e1a961432db785091207ead0621b" - integrity sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A== - dependencies: - "@babel/helper-validator-identifier" "^7.22.20" - chalk "^2.4.2" - js-tokens "^4.0.0" - -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.24.0": - version "7.24.0" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.0.tgz#26a3d1ff49031c53a97d03b604375f028746a9ac" - integrity sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg== - -"@babel/plugin-syntax-async-generators@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" - integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-bigint@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" - integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-class-properties@^7.8.3": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" - integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== - dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - -"@babel/plugin-syntax-import-meta@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" - integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-json-strings@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" - integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-jsx@^7.7.2": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz#8f2e4f8a9b5f9aa16067e142c1ac9cd9f810f473" - integrity sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" - integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" - integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-numeric-separator@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" - integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-object-rest-spread@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" - integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-catch-binding@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" - integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-chaining@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" - integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-top-level-await@^7.8.3": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" - integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-typescript@^7.7.2": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz#24f460c85dbbc983cd2b9c4994178bcc01df958f" - integrity sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/runtime@^7.21.0": - version "7.24.0" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.0.tgz#584c450063ffda59697021430cb47101b085951e" - integrity sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw== - dependencies: - regenerator-runtime "^0.14.0" - -"@babel/template@^7.22.15", "@babel/template@^7.24.0", "@babel/template@^7.3.3": - version "7.24.0" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.24.0.tgz#c6a524aa93a4a05d66aaf31654258fae69d87d50" - integrity sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA== - dependencies: - "@babel/code-frame" "^7.23.5" - "@babel/parser" "^7.24.0" - "@babel/types" "^7.24.0" - -"@babel/traverse@^7.24.0": - version "7.24.0" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.24.0.tgz#4a408fbf364ff73135c714a2ab46a5eab2831b1e" - integrity sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw== - dependencies: - "@babel/code-frame" "^7.23.5" - "@babel/generator" "^7.23.6" - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-function-name" "^7.23.0" - "@babel/helper-hoist-variables" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/parser" "^7.24.0" - "@babel/types" "^7.24.0" - debug "^4.3.1" - globals "^11.1.0" - -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.6", "@babel/types@^7.24.0", "@babel/types@^7.3.3": - version "7.24.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.24.0.tgz#3b951f435a92e7333eba05b7566fd297960ea1bf" - integrity sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w== - dependencies: - "@babel/helper-string-parser" "^7.23.4" - "@babel/helper-validator-identifier" "^7.22.20" - to-fast-properties "^2.0.0" - -"@bcoe/v8-coverage@^0.2.3": - version "0.2.3" - resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" - integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== - -"@colors/colors@1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.6.0.tgz#ec6cd237440700bc23ca23087f513c75508958b0" - integrity sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA== - -"@cspotcode/source-map-support@^0.8.0": - version "0.8.1" - resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" - integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== - dependencies: - "@jridgewell/trace-mapping" "0.3.9" - -"@dabh/diagnostics@^2.0.2": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@dabh/diagnostics/-/diagnostics-2.0.3.tgz#7f7e97ee9a725dffc7808d93668cc984e1dc477a" - integrity sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA== - dependencies: - colorspace "1.1.x" - enabled "2.0.x" - kuler "^2.0.0" - -"@esbuild/aix-ppc64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz#d1bc06aedb6936b3b6d313bf809a5a40387d2b7f" - integrity sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA== - -"@esbuild/android-arm64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz#7ad65a36cfdb7e0d429c353e00f680d737c2aed4" - integrity sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA== - -"@esbuild/android-arm@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.19.12.tgz#b0c26536f37776162ca8bde25e42040c203f2824" - integrity sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w== - -"@esbuild/android-x64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.19.12.tgz#cb13e2211282012194d89bf3bfe7721273473b3d" - integrity sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew== - -"@esbuild/darwin-arm64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz#cbee41e988020d4b516e9d9e44dd29200996275e" - integrity sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g== - -"@esbuild/darwin-x64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz#e37d9633246d52aecf491ee916ece709f9d5f4cd" - integrity sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A== - -"@esbuild/freebsd-arm64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz#1ee4d8b682ed363b08af74d1ea2b2b4dbba76487" - integrity sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA== - -"@esbuild/freebsd-x64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz#37a693553d42ff77cd7126764b535fb6cc28a11c" - integrity sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg== - -"@esbuild/linux-arm64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz#be9b145985ec6c57470e0e051d887b09dddb2d4b" - integrity sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA== - -"@esbuild/linux-arm@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz#207ecd982a8db95f7b5279207d0ff2331acf5eef" - integrity sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w== - -"@esbuild/linux-ia32@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz#d0d86b5ca1562523dc284a6723293a52d5860601" - integrity sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA== - -"@esbuild/linux-loong64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz#9a37f87fec4b8408e682b528391fa22afd952299" - integrity sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA== - -"@esbuild/linux-mips64el@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz#4ddebd4e6eeba20b509d8e74c8e30d8ace0b89ec" - integrity sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w== - -"@esbuild/linux-ppc64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz#adb67dadb73656849f63cd522f5ecb351dd8dee8" - integrity sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg== - -"@esbuild/linux-riscv64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz#11bc0698bf0a2abf8727f1c7ace2112612c15adf" - integrity sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg== - -"@esbuild/linux-s390x@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz#e86fb8ffba7c5c92ba91fc3b27ed5a70196c3cc8" - integrity sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg== - -"@esbuild/linux-x64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz#5f37cfdc705aea687dfe5dfbec086a05acfe9c78" - integrity sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg== - -"@esbuild/netbsd-x64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz#29da566a75324e0d0dd7e47519ba2f7ef168657b" - integrity sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA== - -"@esbuild/openbsd-x64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz#306c0acbdb5a99c95be98bdd1d47c916e7dc3ff0" - integrity sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw== - -"@esbuild/sunos-x64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz#0933eaab9af8b9b2c930236f62aae3fc593faf30" - integrity sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA== - -"@esbuild/win32-arm64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz#773bdbaa1971b36db2f6560088639ccd1e6773ae" - integrity sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A== - -"@esbuild/win32-ia32@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz#000516cad06354cc84a73f0943a4aa690ef6fd67" - integrity sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ== - -"@esbuild/win32-x64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz#c57c8afbb4054a3ab8317591a0b7320360b444ae" - integrity sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA== - -"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": - version "4.4.0" - resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" - integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== - dependencies: - eslint-visitor-keys "^3.3.0" - -"@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": - version "4.10.0" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63" - integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== - -"@eslint/eslintrc@^2.1.4": - version "2.1.4" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad" - integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ== - dependencies: - ajv "^6.12.4" - debug "^4.3.2" - espree "^9.6.0" - globals "^13.19.0" - ignore "^5.2.0" - import-fresh "^3.2.1" - js-yaml "^4.1.0" - minimatch "^3.1.2" - strip-json-comments "^3.1.1" - -"@eslint/js@8.57.0": - version "8.57.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.0.tgz#a5417ae8427873f1dd08b70b3574b453e67b5f7f" - integrity sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g== - -"@ethereumjs/rlp@^4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@ethereumjs/rlp/-/rlp-4.0.1.tgz#626fabfd9081baab3d0a3074b0c7ecaf674aaa41" - integrity sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw== - -"@ethereumjs/util@^8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@ethereumjs/util/-/util-8.1.0.tgz#299df97fb6b034e0577ce9f94c7d9d1004409ed4" - integrity sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA== - dependencies: - "@ethereumjs/rlp" "^4.0.1" - ethereum-cryptography "^2.0.0" - micro-ftch "^0.3.1" - -"@ethersproject/abi@^5.1.2", "@ethersproject/abi@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.7.0.tgz#b3f3e045bbbeed1af3947335c247ad625a44e449" - integrity sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA== - dependencies: - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/abstract-provider@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz#b0a8550f88b6bf9d51f90e4795d48294630cb9ef" - integrity sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/networks" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/web" "^5.7.0" - -"@ethersproject/abstract-signer@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz#13f4f32117868452191a4649723cb086d2b596b2" - integrity sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ== - dependencies: - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - -"@ethersproject/address@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.7.0.tgz#19b56c4d74a3b0a46bfdbb6cfcc0a153fc697f37" - integrity sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/rlp" "^5.7.0" - -"@ethersproject/base64@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.7.0.tgz#ac4ee92aa36c1628173e221d0d01f53692059e1c" - integrity sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ== - dependencies: - "@ethersproject/bytes" "^5.7.0" - -"@ethersproject/basex@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.7.0.tgz#97034dc7e8938a8ca943ab20f8a5e492ece4020b" - integrity sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - -"@ethersproject/bignumber@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.7.0.tgz#e2f03837f268ba655ffba03a57853e18a18dc9c2" - integrity sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - bn.js "^5.2.1" - -"@ethersproject/bytes@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.7.0.tgz#a00f6ea8d7e7534d6d87f47188af1148d71f155d" - integrity sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A== - dependencies: - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/constants@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.7.0.tgz#df80a9705a7e08984161f09014ea012d1c75295e" - integrity sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - -"@ethersproject/hash@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.7.0.tgz#eb7aca84a588508369562e16e514b539ba5240a7" - integrity sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g== - dependencies: - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/base64" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/hdnode@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.7.0.tgz#e627ddc6b466bc77aebf1a6b9e47405ca5aef9cf" - integrity sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg== - dependencies: - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/basex" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/pbkdf2" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - "@ethersproject/signing-key" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/wordlists" "^5.7.0" - -"@ethersproject/json-wallets@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz#5e3355287b548c32b368d91014919ebebddd5360" - integrity sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g== - dependencies: - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/hdnode" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/pbkdf2" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/random" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - aes-js "3.0.0" - scrypt-js "3.0.1" - -"@ethersproject/keccak256@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.7.0.tgz#3186350c6e1cd6aba7940384ec7d6d9db01f335a" - integrity sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg== - dependencies: - "@ethersproject/bytes" "^5.7.0" - js-sha3 "0.8.0" - -"@ethersproject/logger@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.7.0.tgz#6ce9ae168e74fecf287be17062b590852c311892" - integrity sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig== - -"@ethersproject/networks@^5.7.0": - version "5.7.1" - resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.7.1.tgz#118e1a981d757d45ccea6bb58d9fd3d9db14ead6" - integrity sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ== - dependencies: - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/pbkdf2@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz#d2267d0a1f6e123f3771007338c47cccd83d3102" - integrity sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - -"@ethersproject/properties@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.7.0.tgz#a6e12cb0439b878aaf470f1902a176033067ed30" - integrity sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw== - dependencies: - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/providers@^5.7.2": - version "5.7.2" - resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.7.2.tgz#f8b1a4f275d7ce58cf0a2eec222269a08beb18cb" - integrity sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg== - dependencies: - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/base64" "^5.7.0" - "@ethersproject/basex" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/networks" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/random" "^5.7.0" - "@ethersproject/rlp" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/web" "^5.7.0" - bech32 "1.1.4" - ws "7.4.6" - -"@ethersproject/random@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.7.0.tgz#af19dcbc2484aae078bb03656ec05df66253280c" - integrity sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/rlp@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.7.0.tgz#de39e4d5918b9d74d46de93af80b7685a9c21304" - integrity sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/sha2@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.7.0.tgz#9a5f7a7824ef784f7f7680984e593a800480c9fb" - integrity sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - hash.js "1.1.7" - -"@ethersproject/signing-key@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.7.0.tgz#06b2df39411b00bc57c7c09b01d1e41cf1b16ab3" - integrity sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - bn.js "^5.2.1" - elliptic "6.5.4" - hash.js "1.1.7" - -"@ethersproject/strings@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.7.0.tgz#54c9d2a7c57ae8f1205c88a9d3a56471e14d5ed2" - integrity sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/transactions@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.7.0.tgz#91318fc24063e057885a6af13fdb703e1f993d3b" - integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ== - dependencies: - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/rlp" "^5.7.0" - "@ethersproject/signing-key" "^5.7.0" - -"@ethersproject/wallet@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.7.0.tgz#4e5d0790d96fe21d61d38fb40324e6c7ef350b2d" - integrity sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA== - dependencies: - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/hdnode" "^5.7.0" - "@ethersproject/json-wallets" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/random" "^5.7.0" - "@ethersproject/signing-key" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/wordlists" "^5.7.0" - -"@ethersproject/web@^5.7.0": - version "5.7.1" - resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.7.1.tgz#de1f285b373149bee5928f4eb7bcb87ee5fbb4ae" - integrity sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w== - dependencies: - "@ethersproject/base64" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/wordlists@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.7.0.tgz#8fb2c07185d68c3e09eb3bfd6e779ba2774627f5" - integrity sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@fastify/busboy@^2.0.0": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.1.tgz#b9da6a878a371829a0502c9b6c1c143ef6663f4d" - integrity sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA== - -"@gar/promisify@^1.0.1", "@gar/promisify@^1.1.3": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" - integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== - -"@humanwhocodes/config-array@^0.11.14": - version "0.11.14" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.14.tgz#d78e481a039f7566ecc9660b4ea7fe6b1fec442b" - integrity sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg== - dependencies: - "@humanwhocodes/object-schema" "^2.0.2" - debug "^4.3.1" - minimatch "^3.0.5" - -"@humanwhocodes/module-importer@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" - integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== - -"@humanwhocodes/object-schema@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz#d9fae00a2d5cb40f92cfe64b47ad749fbc38f917" - integrity sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw== - -"@hutson/parse-repository-url@^3.0.0": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz#98c23c950a3d9b6c8f0daed06da6c3af06981340" - integrity sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q== - -"@isaacs/cliui@^8.0.2": - version "8.0.2" - resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" - integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== - dependencies: - string-width "^5.1.2" - string-width-cjs "npm:string-width@^4.2.0" - strip-ansi "^7.0.1" - strip-ansi-cjs "npm:strip-ansi@^6.0.1" - wrap-ansi "^8.1.0" - wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" - -"@istanbuljs/load-nyc-config@^1.0.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" - integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== - dependencies: - camelcase "^5.3.1" - find-up "^4.1.0" - get-package-type "^0.1.0" - js-yaml "^3.13.1" - resolve-from "^5.0.0" - -"@istanbuljs/schema@^0.1.2", "@istanbuljs/schema@^0.1.3": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" - integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== - -"@jest/console@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.7.0.tgz#cd4822dbdb84529265c5a2bdb529a3c9cc950ffc" - integrity sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg== - dependencies: - "@jest/types" "^29.6.3" - "@types/node" "*" - chalk "^4.0.0" - jest-message-util "^29.7.0" - jest-util "^29.7.0" - slash "^3.0.0" - -"@jest/core@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.7.0.tgz#b6cccc239f30ff36609658c5a5e2291757ce448f" - integrity sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg== - dependencies: - "@jest/console" "^29.7.0" - "@jest/reporters" "^29.7.0" - "@jest/test-result" "^29.7.0" - "@jest/transform" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/node" "*" - ansi-escapes "^4.2.1" - chalk "^4.0.0" - ci-info "^3.2.0" - exit "^0.1.2" - graceful-fs "^4.2.9" - jest-changed-files "^29.7.0" - jest-config "^29.7.0" - jest-haste-map "^29.7.0" - jest-message-util "^29.7.0" - jest-regex-util "^29.6.3" - jest-resolve "^29.7.0" - jest-resolve-dependencies "^29.7.0" - jest-runner "^29.7.0" - jest-runtime "^29.7.0" - jest-snapshot "^29.7.0" - jest-util "^29.7.0" - jest-validate "^29.7.0" - jest-watcher "^29.7.0" - micromatch "^4.0.4" - pretty-format "^29.7.0" - slash "^3.0.0" - strip-ansi "^6.0.0" - -"@jest/environment@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.7.0.tgz#24d61f54ff1f786f3cd4073b4b94416383baf2a7" - integrity sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw== - dependencies: - "@jest/fake-timers" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/node" "*" - jest-mock "^29.7.0" - -"@jest/expect-utils@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.7.0.tgz#023efe5d26a8a70f21677d0a1afc0f0a44e3a1c6" - integrity sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA== - dependencies: - jest-get-type "^29.6.3" - -"@jest/expect@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.7.0.tgz#76a3edb0cb753b70dfbfe23283510d3d45432bf2" - integrity sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ== - dependencies: - expect "^29.7.0" - jest-snapshot "^29.7.0" - -"@jest/fake-timers@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.7.0.tgz#fd91bf1fffb16d7d0d24a426ab1a47a49881a565" - integrity sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ== - dependencies: - "@jest/types" "^29.6.3" - "@sinonjs/fake-timers" "^10.0.2" - "@types/node" "*" - jest-message-util "^29.7.0" - jest-mock "^29.7.0" - jest-util "^29.7.0" - -"@jest/globals@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.7.0.tgz#8d9290f9ec47ff772607fa864ca1d5a2efae1d4d" - integrity sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ== - dependencies: - "@jest/environment" "^29.7.0" - "@jest/expect" "^29.7.0" - "@jest/types" "^29.6.3" - jest-mock "^29.7.0" - -"@jest/reporters@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.7.0.tgz#04b262ecb3b8faa83b0b3d321623972393e8f4c7" - integrity sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg== - dependencies: - "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^29.7.0" - "@jest/test-result" "^29.7.0" - "@jest/transform" "^29.7.0" - "@jest/types" "^29.6.3" - "@jridgewell/trace-mapping" "^0.3.18" - "@types/node" "*" - chalk "^4.0.0" - collect-v8-coverage "^1.0.0" - exit "^0.1.2" - glob "^7.1.3" - graceful-fs "^4.2.9" - istanbul-lib-coverage "^3.0.0" - istanbul-lib-instrument "^6.0.0" - istanbul-lib-report "^3.0.0" - istanbul-lib-source-maps "^4.0.0" - istanbul-reports "^3.1.3" - jest-message-util "^29.7.0" - jest-util "^29.7.0" - jest-worker "^29.7.0" - slash "^3.0.0" - string-length "^4.0.1" - strip-ansi "^6.0.0" - v8-to-istanbul "^9.0.1" - -"@jest/schemas@^29.6.3": - version "29.6.3" - resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" - integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== - dependencies: - "@sinclair/typebox" "^0.27.8" - -"@jest/source-map@^29.6.3": - version "29.6.3" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.6.3.tgz#d90ba772095cf37a34a5eb9413f1b562a08554c4" - integrity sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw== - dependencies: - "@jridgewell/trace-mapping" "^0.3.18" - callsites "^3.0.0" - graceful-fs "^4.2.9" - -"@jest/test-result@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.7.0.tgz#8db9a80aa1a097bb2262572686734baed9b1657c" - integrity sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA== - dependencies: - "@jest/console" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/istanbul-lib-coverage" "^2.0.0" - collect-v8-coverage "^1.0.0" - -"@jest/test-sequencer@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz#6cef977ce1d39834a3aea887a1726628a6f072ce" - integrity sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw== - dependencies: - "@jest/test-result" "^29.7.0" - graceful-fs "^4.2.9" - jest-haste-map "^29.7.0" - slash "^3.0.0" - -"@jest/transform@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.7.0.tgz#df2dd9c346c7d7768b8a06639994640c642e284c" - integrity sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw== - dependencies: - "@babel/core" "^7.11.6" - "@jest/types" "^29.6.3" - "@jridgewell/trace-mapping" "^0.3.18" - babel-plugin-istanbul "^6.1.1" - chalk "^4.0.0" - convert-source-map "^2.0.0" - fast-json-stable-stringify "^2.1.0" - graceful-fs "^4.2.9" - jest-haste-map "^29.7.0" - jest-regex-util "^29.6.3" - jest-util "^29.7.0" - micromatch "^4.0.4" - pirates "^4.0.4" - slash "^3.0.0" - write-file-atomic "^4.0.2" - -"@jest/types@^29.6.3": - version "29.6.3" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" - integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== - dependencies: - "@jest/schemas" "^29.6.3" - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^17.0.8" - chalk "^4.0.0" - -"@jridgewell/gen-mapping@^0.3.2", "@jridgewell/gen-mapping@^0.3.5": - version "0.3.5" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" - integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg== - dependencies: - "@jridgewell/set-array" "^1.2.1" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.24" - -"@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@^3.1.0": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" - integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== - -"@jridgewell/set-array@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280" - integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== - -"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": - version "1.4.15" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" - integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== - -"@jridgewell/trace-mapping@0.3.9": - version "0.3.9" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" - integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== - dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" - -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.24": - version "0.3.25" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" - integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== - dependencies: - "@jridgewell/resolve-uri" "^3.1.0" - "@jridgewell/sourcemap-codec" "^1.4.14" - -"@lerna/child-process@7.4.2": - version "7.4.2" - resolved "https://registry.yarnpkg.com/@lerna/child-process/-/child-process-7.4.2.tgz#a2fd013ac2150dc288270d3e0d0b850c06bec511" - integrity sha512-je+kkrfcvPcwL5Tg8JRENRqlbzjdlZXyaR88UcnCdNW0AJ1jX9IfHRys1X7AwSroU2ug8ESNC+suoBw1vX833Q== - dependencies: - chalk "^4.1.0" - execa "^5.0.0" - strong-log-transformer "^2.1.0" - -"@lerna/create@7.4.2": - version "7.4.2" - resolved "https://registry.yarnpkg.com/@lerna/create/-/create-7.4.2.tgz#f845fad1480e46555af98bd39af29571605dddc9" - integrity sha512-1wplFbQ52K8E/unnqB0Tq39Z4e+NEoNrpovEnl6GpsTUrC6WDp8+w0Le2uCBV0hXyemxChduCkLz4/y1H1wTeg== - dependencies: - "@lerna/child-process" "7.4.2" - "@npmcli/run-script" "6.0.2" - "@nx/devkit" ">=16.5.1 < 17" - "@octokit/plugin-enterprise-rest" "6.0.1" - "@octokit/rest" "19.0.11" - byte-size "8.1.1" - chalk "4.1.0" - clone-deep "4.0.1" - cmd-shim "6.0.1" - columnify "1.6.0" - conventional-changelog-core "5.0.1" - conventional-recommended-bump "7.0.1" - cosmiconfig "^8.2.0" - dedent "0.7.0" - execa "5.0.0" - fs-extra "^11.1.1" - get-stream "6.0.0" - git-url-parse "13.1.0" - glob-parent "5.1.2" - globby "11.1.0" - graceful-fs "4.2.11" - has-unicode "2.0.1" - ini "^1.3.8" - init-package-json "5.0.0" - inquirer "^8.2.4" - is-ci "3.0.1" - is-stream "2.0.0" - js-yaml "4.1.0" - libnpmpublish "7.3.0" - load-json-file "6.2.0" - lodash "^4.17.21" - make-dir "4.0.0" - minimatch "3.0.5" - multimatch "5.0.0" - node-fetch "2.6.7" - npm-package-arg "8.1.1" - npm-packlist "5.1.1" - npm-registry-fetch "^14.0.5" - npmlog "^6.0.2" - nx ">=16.5.1 < 17" - p-map "4.0.0" - p-map-series "2.1.0" - p-queue "6.6.2" - p-reduce "^2.1.0" - pacote "^15.2.0" - pify "5.0.0" - read-cmd-shim "4.0.0" - read-package-json "6.0.4" - resolve-from "5.0.0" - rimraf "^4.4.1" - semver "^7.3.4" - signal-exit "3.0.7" - slash "^3.0.0" - ssri "^9.0.1" - strong-log-transformer "2.1.0" - tar "6.1.11" - temp-dir "1.0.0" - upath "2.0.1" - uuid "^9.0.0" - validate-npm-package-license "^3.0.4" - validate-npm-package-name "5.0.0" - write-file-atomic "5.0.1" - write-pkg "4.0.0" - yargs "16.2.0" - yargs-parser "20.2.4" - -"@metamask/eth-sig-util@^4.0.0": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz#3ad61f6ea9ad73ba5b19db780d40d9aae5157088" - integrity sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ== - dependencies: - ethereumjs-abi "^0.6.8" - ethereumjs-util "^6.2.1" - ethjs-util "^0.1.6" - tweetnacl "^1.0.3" - tweetnacl-util "^0.15.1" - -"@noble/curves@1.2.0", "@noble/curves@~1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.2.0.tgz#92d7e12e4e49b23105a2555c6984d41733d65c35" - integrity sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw== - dependencies: - "@noble/hashes" "1.3.2" - -"@noble/curves@1.3.0", "@noble/curves@~1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.3.0.tgz#01be46da4fd195822dab821e72f71bf4aeec635e" - integrity sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA== - dependencies: - "@noble/hashes" "1.3.3" - -"@noble/hashes@1.2.0", "@noble/hashes@~1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.2.0.tgz#a3150eeb09cc7ab207ebf6d7b9ad311a9bdbed12" - integrity sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ== - -"@noble/hashes@1.3.2": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" - integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== - -"@noble/hashes@1.3.3", "@noble/hashes@~1.3.0", "@noble/hashes@~1.3.2": - version "1.3.3" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.3.tgz#39908da56a4adc270147bb07968bf3b16cfe1699" - integrity sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA== - -"@noble/secp256k1@1.7.1", "@noble/secp256k1@~1.7.0": - version "1.7.1" - resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c" - integrity sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw== - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@nomicfoundation/edr-darwin-arm64@0.2.1": - version "0.2.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.2.1.tgz#10c1a07add192583ce8b2d4cc93439f52b390a41" - integrity sha512-aMYaRaZVQ/TmyNJIoXf1bU4k0zfinaL9Sy1day4yGlL6eiQPFfRGj9W6TZaZIoYG0XTx/mQWD7dkXJ7LdrleJA== - -"@nomicfoundation/edr-darwin-x64@0.2.1": - version "0.2.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.2.1.tgz#eaa29d2ba9f91ddb5f59b872c5a54f94a6fe3095" - integrity sha512-ma0SLcjHm5L3nPHcKFJB0jv/gKGSKaxr5Z65rurX/eaYUQJ7YGMsb8er9bSCo9rjzOtxf4FoPj3grL3zGpOj8A== - -"@nomicfoundation/edr-linux-arm64-gnu@0.2.1": - version "0.2.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.2.1.tgz#8149db0d742157405effe82d485ea9bfefddc795" - integrity sha512-NX3G4pBhRitWrjSGY3HTyCq3wKSm5YqrKVOCNQGl9/jcjSovqxlgzFMiTx4YZCzGntfJ/1om9AI84OWxYJjoDw== - -"@nomicfoundation/edr-linux-arm64-musl@0.2.1": - version "0.2.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.2.1.tgz#7d53afe5607eb406d199a199d00209a6304ff07b" - integrity sha512-gdQ3QHkt9XRkdtOGQ8fMwS11MXdjLeZgLrqoial4V4qtMaamIMMhVczK+VEvUhD8p7G4BVmp6kmkvcsthmndmw== - -"@nomicfoundation/edr-linux-x64-gnu@0.2.1": - version "0.2.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.2.1.tgz#b762c95368fcb88bbbabba4d8be5380f38967413" - integrity sha512-OqabFY37vji6mYbLD9CvG28lja68czeVw58oWByIhFV3BpBu/cyP1oAbhzk3LieylujabS3Ekpvjw2Tkf0A9RQ== - -"@nomicfoundation/edr-linux-x64-musl@0.2.1": - version "0.2.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.2.1.tgz#522448c42bff7d2abd52ddcf11ae6ca3dfdd6db4" - integrity sha512-vHfFFK2EPISuQUQge+bdjXamb0EUjfl8srYSog1qfiwyLwLeuSbpyyFzDeITAgPpkkFuedTfJW553K0Hipspyg== - -"@nomicfoundation/edr-win32-arm64-msvc@0.2.1": - version "0.2.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-win32-arm64-msvc/-/edr-win32-arm64-msvc-0.2.1.tgz#ccfa443c274e49de93016a1060be810096dc6f1d" - integrity sha512-K/mui67RCKxghbSyvhvW3rvyVN1pa9M1Q9APUx1PtWjSSdXDFpqEY1NYsv2syb47Ca8ObJwVMF+LvnB6GvhUOQ== - -"@nomicfoundation/edr-win32-ia32-msvc@0.2.1": - version "0.2.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-win32-ia32-msvc/-/edr-win32-ia32-msvc-0.2.1.tgz#822b19d3e67d6dcfa5394cb6a4d55d8bab1b2f26" - integrity sha512-HHK0mXEtjvfjJrJlqcYgQCy3lZIXS1KNl2GaP8bwEIuEwx++XxXs/ThLjPepM1nhCGICij8IGy7p3KrkzRelsw== - -"@nomicfoundation/edr-win32-x64-msvc@0.2.1": - version "0.2.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.2.1.tgz#7b56ff742b2724779cc9f3385815b394f76de8df" - integrity sha512-FY4eQJdj1/y8ST0RyQycx63yr+lvdYNnUkzgWf4X+vPH1lOhXae+L2NDcNCQlTDAfQcD6yz0bkBUkLrlJ8pTww== - -"@nomicfoundation/edr@^0.2.0": - version "0.2.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr/-/edr-0.2.1.tgz#a3d2a542dcd5dc5a8d757116d52baea05f370531" - integrity sha512-Dleau3ItHJh2n85G2J6AIPBoLgu/mOWkmrh26z3VsJE2tp/e00hUk/dqz85ncsVcBYEc6/YOn/DomWu0wSF9tQ== - optionalDependencies: - "@nomicfoundation/edr-darwin-arm64" "0.2.1" - "@nomicfoundation/edr-darwin-x64" "0.2.1" - "@nomicfoundation/edr-linux-arm64-gnu" "0.2.1" - "@nomicfoundation/edr-linux-arm64-musl" "0.2.1" - "@nomicfoundation/edr-linux-x64-gnu" "0.2.1" - "@nomicfoundation/edr-linux-x64-musl" "0.2.1" - "@nomicfoundation/edr-win32-arm64-msvc" "0.2.1" - "@nomicfoundation/edr-win32-ia32-msvc" "0.2.1" - "@nomicfoundation/edr-win32-x64-msvc" "0.2.1" - -"@nomicfoundation/ethereumjs-common@4.0.4": - version "4.0.4" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.4.tgz#9901f513af2d4802da87c66d6f255b510bef5acb" - integrity sha512-9Rgb658lcWsjiicr5GzNCjI1llow/7r0k50dLL95OJ+6iZJcVbi15r3Y0xh2cIO+zgX0WIHcbzIu6FeQf9KPrg== - dependencies: - "@nomicfoundation/ethereumjs-util" "9.0.4" - -"@nomicfoundation/ethereumjs-rlp@5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.4.tgz#66c95256fc3c909f6fb18f6a586475fc9762fa30" - integrity sha512-8H1S3s8F6QueOc/X92SdrA4RDenpiAEqMg5vJH99kcQaCy/a3Q6fgseo75mgWlbanGJXSlAPtnCeG9jvfTYXlw== - -"@nomicfoundation/ethereumjs-tx@5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.4.tgz#b0ceb58c98cc34367d40a30d255d6315b2f456da" - integrity sha512-Xjv8wAKJGMrP1f0n2PeyfFCCojHd7iS3s/Ab7qzF1S64kxZ8Z22LCMynArYsVqiFx6rzYy548HNVEyI+AYN/kw== - dependencies: - "@nomicfoundation/ethereumjs-common" "4.0.4" - "@nomicfoundation/ethereumjs-rlp" "5.0.4" - "@nomicfoundation/ethereumjs-util" "9.0.4" - ethereum-cryptography "0.1.3" - -"@nomicfoundation/ethereumjs-util@9.0.4": - version "9.0.4" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.4.tgz#84c5274e82018b154244c877b76bc049a4ed7b38" - integrity sha512-sLOzjnSrlx9Bb9EFNtHzK/FJFsfg2re6bsGqinFinH1gCqVfz9YYlXiMWwDM4C/L4ywuHFCYwfKTVr/QHQcU0Q== - dependencies: - "@nomicfoundation/ethereumjs-rlp" "5.0.4" - ethereum-cryptography "0.1.3" - -"@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.1.tgz#4c858096b1c17fe58a474fe81b46815f93645c15" - integrity sha512-KcTodaQw8ivDZyF+D76FokN/HdpgGpfjc/gFCImdLUyqB6eSWVaZPazMbeAjmfhx3R0zm/NYVzxwAokFKgrc0w== - -"@nomicfoundation/solidity-analyzer-darwin-x64@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.1.tgz#6e25ccdf6e2d22389c35553b64fe6f3fdaec432c" - integrity sha512-XhQG4BaJE6cIbjAVtzGOGbK3sn1BO9W29uhk9J8y8fZF1DYz0Doj8QDMfpMu+A6TjPDs61lbsmeYodIDnfveSA== - -"@nomicfoundation/solidity-analyzer-freebsd-x64@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.1.tgz#0a224ea50317139caeebcdedd435c28a039d169c" - integrity sha512-GHF1VKRdHW3G8CndkwdaeLkVBi5A9u2jwtlS7SLhBc8b5U/GcoL39Q+1CSO3hYqePNP+eV5YI7Zgm0ea6kMHoA== - -"@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.1.tgz#dfa085d9ffab9efb2e7b383aed3f557f7687ac2b" - integrity sha512-g4Cv2fO37ZsUENQ2vwPnZc2zRenHyAxHcyBjKcjaSmmkKrFr64yvzeNO8S3GBFCo90rfochLs99wFVGT/0owpg== - -"@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.1.tgz#c9e06b5d513dd3ab02a7ac069c160051675889a4" - integrity sha512-WJ3CE5Oek25OGE3WwzK7oaopY8xMw9Lhb0mlYuJl/maZVo+WtP36XoQTb7bW/i8aAdHW5Z+BqrHMux23pvxG3w== - -"@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.1.tgz#8d328d16839e52571f72f2998c81e46bf320f893" - integrity sha512-5WN7leSr5fkUBBjE4f3wKENUy9HQStu7HmWqbtknfXkkil+eNWiBV275IOlpXku7v3uLsXTOKpnnGHJYI2qsdA== - -"@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.1.tgz#9b49d0634b5976bb5ed1604a1e1b736f390959bb" - integrity sha512-KdYMkJOq0SYPQMmErv/63CwGwMm5XHenEna9X9aB8mQmhDBrYrlAOSsIPgFCUSL0hjxE3xHP65/EPXR/InD2+w== - -"@nomicfoundation/solidity-analyzer-win32-arm64-msvc@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.1.tgz#e2867af7264ebbcc3131ef837878955dd6a3676f" - integrity sha512-VFZASBfl4qiBYwW5xeY20exWhmv6ww9sWu/krWSesv3q5hA0o1JuzmPHR4LPN6SUZj5vcqci0O6JOL8BPw+APg== - -"@nomicfoundation/solidity-analyzer-win32-ia32-msvc@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.1.tgz#0685f78608dd516c8cdfb4896ed451317e559585" - integrity sha512-JnFkYuyCSA70j6Si6cS1A9Gh1aHTEb8kOTBApp/c7NRTFGNMH8eaInKlyuuiIbvYFhlXW4LicqyYuWNNq9hkpQ== - -"@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.1.tgz#c9a44f7108646f083b82e851486e0f6aeb785836" - integrity sha512-HrVJr6+WjIXGnw3Q9u6KQcbZCtk0caVWhCdFADySvRyUxJ8PnzlaP+MhwNE8oyT8OZ6ejHBRrrgjSqDCFXGirw== - -"@nomicfoundation/solidity-analyzer@^0.1.0": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.1.tgz#f5f4d36d3f66752f59a57e7208cd856f3ddf6f2d" - integrity sha512-1LMtXj1puAxyFusBgUIy5pZk3073cNXYnXUpuNKFghHbIit/xZgbk0AokpUADbNm3gyD6bFWl3LRFh3dhVdREg== - optionalDependencies: - "@nomicfoundation/solidity-analyzer-darwin-arm64" "0.1.1" - "@nomicfoundation/solidity-analyzer-darwin-x64" "0.1.1" - "@nomicfoundation/solidity-analyzer-freebsd-x64" "0.1.1" - "@nomicfoundation/solidity-analyzer-linux-arm64-gnu" "0.1.1" - "@nomicfoundation/solidity-analyzer-linux-arm64-musl" "0.1.1" - "@nomicfoundation/solidity-analyzer-linux-x64-gnu" "0.1.1" - "@nomicfoundation/solidity-analyzer-linux-x64-musl" "0.1.1" - "@nomicfoundation/solidity-analyzer-win32-arm64-msvc" "0.1.1" - "@nomicfoundation/solidity-analyzer-win32-ia32-msvc" "0.1.1" - "@nomicfoundation/solidity-analyzer-win32-x64-msvc" "0.1.1" - -"@npmcli/fs@^1.0.0": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-1.1.1.tgz#72f719fe935e687c56a4faecf3c03d06ba593257" - integrity sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ== - dependencies: - "@gar/promisify" "^1.0.1" - semver "^7.3.5" - -"@npmcli/fs@^2.1.0": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-2.1.2.tgz#a9e2541a4a2fec2e69c29b35e6060973da79b865" - integrity sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ== - dependencies: - "@gar/promisify" "^1.1.3" - semver "^7.3.5" - -"@npmcli/fs@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-3.1.0.tgz#233d43a25a91d68c3a863ba0da6a3f00924a173e" - integrity sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w== - dependencies: - semver "^7.3.5" - -"@npmcli/git@^4.0.0": - version "4.1.0" - resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-4.1.0.tgz#ab0ad3fd82bc4d8c1351b6c62f0fa56e8fe6afa6" - integrity sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ== - dependencies: - "@npmcli/promise-spawn" "^6.0.0" - lru-cache "^7.4.4" - npm-pick-manifest "^8.0.0" - proc-log "^3.0.0" - promise-inflight "^1.0.1" - promise-retry "^2.0.1" - semver "^7.3.5" - which "^3.0.0" - -"@npmcli/installed-package-contents@^2.0.1": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@npmcli/installed-package-contents/-/installed-package-contents-2.0.2.tgz#bfd817eccd9e8df200919e73f57f9e3d9e4f9e33" - integrity sha512-xACzLPhnfD51GKvTOOuNX2/V4G4mz9/1I2MfDoye9kBM3RYe5g2YbscsaGoTlaWqkxeiapBWyseULVKpSVHtKQ== - dependencies: - npm-bundled "^3.0.0" - npm-normalize-package-bin "^3.0.0" - -"@npmcli/move-file@^1.0.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.1.2.tgz#1a82c3e372f7cae9253eb66d72543d6b8685c674" - integrity sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg== - dependencies: - mkdirp "^1.0.4" - rimraf "^3.0.2" - -"@npmcli/move-file@^2.0.0": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-2.0.1.tgz#26f6bdc379d87f75e55739bab89db525b06100e4" - integrity sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ== - dependencies: - mkdirp "^1.0.4" - rimraf "^3.0.2" - -"@npmcli/node-gyp@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz#101b2d0490ef1aa20ed460e4c0813f0db560545a" - integrity sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA== - -"@npmcli/promise-spawn@^6.0.0", "@npmcli/promise-spawn@^6.0.1": - version "6.0.2" - resolved "https://registry.yarnpkg.com/@npmcli/promise-spawn/-/promise-spawn-6.0.2.tgz#c8bc4fa2bd0f01cb979d8798ba038f314cfa70f2" - integrity sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg== - dependencies: - which "^3.0.0" - -"@npmcli/run-script@6.0.2", "@npmcli/run-script@^6.0.0": - version "6.0.2" - resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-6.0.2.tgz#a25452d45ee7f7fb8c16dfaf9624423c0c0eb885" - integrity sha512-NCcr1uQo1k5U+SYlnIrbAh3cxy+OQT1VtqiAbxdymSlptbzBb62AjH2xXgjNCoP073hoa1CfCAcwoZ8k96C4nA== - dependencies: - "@npmcli/node-gyp" "^3.0.0" - "@npmcli/promise-spawn" "^6.0.0" - node-gyp "^9.0.0" - read-package-json-fast "^3.0.0" - which "^3.0.0" - -"@nrwl/devkit@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nrwl/devkit/-/devkit-16.10.0.tgz#ac8c5b4db00f12c4b817c937be2f7c4eb8f2593c" - integrity sha512-fRloARtsDQoQgQ7HKEy0RJiusg/HSygnmg4gX/0n/Z+SUS+4KoZzvHjXc6T5ZdEiSjvLypJ+HBM8dQzIcVACPQ== - dependencies: - "@nx/devkit" "16.10.0" - -"@nrwl/tao@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-16.10.0.tgz#94642a0380709b8e387e1e33705a5a9624933375" - integrity sha512-QNAanpINbr+Pod6e1xNgFbzK1x5wmZl+jMocgiEFXZ67KHvmbD6MAQQr0MMz+GPhIu7EE4QCTLTyCEMlAG+K5Q== - dependencies: - nx "16.10.0" - tslib "^2.3.0" - -"@nx/devkit@16.10.0", "@nx/devkit@>=16.5.1 < 17": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/devkit/-/devkit-16.10.0.tgz#7e466be2dee2dcb1ccaf286786ca2a0a639aa007" - integrity sha512-IvKQqRJFDDiaj33SPfGd3ckNHhHi6ceEoqCbAP4UuMXOPPVOX6H0KVk+9tknkPb48B7jWIw6/AgOeWkBxPRO5w== - dependencies: - "@nrwl/devkit" "16.10.0" - ejs "^3.1.7" - enquirer "~2.3.6" - ignore "^5.0.4" - semver "7.5.3" - tmp "~0.2.1" - tslib "^2.3.0" - -"@nx/nx-darwin-arm64@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/nx-darwin-arm64/-/nx-darwin-arm64-16.10.0.tgz#0c73010cac7a502549483b12bad347da9014e6f1" - integrity sha512-YF+MIpeuwFkyvM5OwgY/rTNRpgVAI/YiR0yTYCZR+X3AAvP775IVlusNgQ3oedTBRUzyRnI4Tknj1WniENFsvQ== - -"@nx/nx-darwin-x64@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/nx-darwin-x64/-/nx-darwin-x64-16.10.0.tgz#2ccf270418d552fd0a8e0d6089aee4944315adaa" - integrity sha512-ypi6YxwXgb0kg2ixKXE3pwf5myVNUgWf1CsV5OzVccCM8NzheMO51KDXTDmEpXdzUsfT0AkO1sk5GZeCjhVONg== - -"@nx/nx-freebsd-x64@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/nx-freebsd-x64/-/nx-freebsd-x64-16.10.0.tgz#c3ee6914256e69493fed9355b0d6661d0e86da44" - integrity sha512-UeEYFDmdbbDkTQamqvtU8ibgu5jQLgFF1ruNb/U4Ywvwutw2d4ruOMl2e0u9hiNja9NFFAnDbvzrDcMo7jYqYw== - -"@nx/nx-linux-arm-gnueabihf@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-16.10.0.tgz#a961eccbb38acb2da7fc125b29d1fead0b39152f" - integrity sha512-WV3XUC2DB6/+bz1sx+d1Ai9q2Cdr+kTZRN50SOkfmZUQyEBaF6DRYpx/a4ahhxH3ktpNfyY8Maa9OEYxGCBkQA== - -"@nx/nx-linux-arm64-gnu@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-16.10.0.tgz#795f20072549d03822b5c4639ef438e473dbb541" - integrity sha512-aWIkOUw995V3ItfpAi5FuxQ+1e9EWLS1cjWM1jmeuo+5WtaKToJn5itgQOkvSlPz+HSLgM3VfXMvOFALNk125g== - -"@nx/nx-linux-arm64-musl@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-16.10.0.tgz#f2428ee6dbe2b2c326e8973f76c97666def33607" - integrity sha512-uO6Gg+irqpVcCKMcEPIQcTFZ+tDI02AZkqkP7koQAjniLEappd8DnUBSQdcn53T086pHpdc264X/ZEpXFfrKWQ== - -"@nx/nx-linux-x64-gnu@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-16.10.0.tgz#d36c2bcf94d49eaa24e3880ddaf6f1f617de539b" - integrity sha512-134PW/u/arNFAQKpqMJniC7irbChMPz+W+qtyKPAUXE0XFKPa7c1GtlI/wK2dvP9qJDZ6bKf0KtA0U/m2HMUOA== - -"@nx/nx-linux-x64-musl@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-16.10.0.tgz#78bd2ab97a583b3d4ea3387b67fd7b136907493c" - integrity sha512-q8sINYLdIJxK/iUx9vRk5jWAWb/2O0PAbOJFwv4qkxBv4rLoN7y+otgCZ5v0xfx/zztFgk/oNY4lg5xYjIso2Q== - -"@nx/nx-win32-arm64-msvc@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-16.10.0.tgz#ef20ec8d0c83d66e73e20df12d2c788b8f866396" - integrity sha512-moJkL9kcqxUdJSRpG7dET3UeLIciwrfP08mzBQ12ewo8K8FzxU8ZUsTIVVdNrwt01CXOdXoweGfdQLjJ4qTURA== - -"@nx/nx-win32-x64-msvc@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-16.10.0.tgz#7410a51d0f8be631eec9552f01b2e5946285927c" - integrity sha512-5iV2NKZnzxJwZZ4DM5JVbRG/nkhAbzEskKaLBB82PmYGKzaDHuMHP1lcPoD/rtYMlowZgNA/RQndfKvPBPwmXA== - -"@octokit/auth-token@^3.0.0": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-3.0.4.tgz#70e941ba742bdd2b49bdb7393e821dea8520a3db" - integrity sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ== - -"@octokit/core@^4.2.1": - version "4.2.4" - resolved "https://registry.yarnpkg.com/@octokit/core/-/core-4.2.4.tgz#d8769ec2b43ff37cc3ea89ec4681a20ba58ef907" - integrity sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ== - dependencies: - "@octokit/auth-token" "^3.0.0" - "@octokit/graphql" "^5.0.0" - "@octokit/request" "^6.0.0" - "@octokit/request-error" "^3.0.0" - "@octokit/types" "^9.0.0" - before-after-hook "^2.2.0" - universal-user-agent "^6.0.0" - -"@octokit/endpoint@^7.0.0": - version "7.0.6" - resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-7.0.6.tgz#791f65d3937555141fb6c08f91d618a7d645f1e2" - integrity sha512-5L4fseVRUsDFGR00tMWD/Trdeeihn999rTMGRMC1G/Ldi1uWlWJzI98H4Iak5DB/RVvQuyMYKqSK/R6mbSOQyg== - dependencies: - "@octokit/types" "^9.0.0" - is-plain-object "^5.0.0" - universal-user-agent "^6.0.0" - -"@octokit/graphql@^5.0.0": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-5.0.6.tgz#9eac411ac4353ccc5d3fca7d76736e6888c5d248" - integrity sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw== - dependencies: - "@octokit/request" "^6.0.0" - "@octokit/types" "^9.0.0" - universal-user-agent "^6.0.0" - -"@octokit/openapi-types@^18.0.0": - version "18.1.1" - resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-18.1.1.tgz#09bdfdabfd8e16d16324326da5148010d765f009" - integrity sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw== - -"@octokit/plugin-enterprise-rest@6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-6.0.1.tgz#e07896739618dab8da7d4077c658003775f95437" - integrity sha512-93uGjlhUD+iNg1iWhUENAtJata6w5nE+V4urXOAlIXdco6xNZtUSfYY8dzp3Udy74aqO/B5UZL80x/YMa5PKRw== - -"@octokit/plugin-paginate-rest@^6.1.2": - version "6.1.2" - resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz#f86456a7a1fe9e58fec6385a85cf1b34072341f8" - integrity sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ== - dependencies: - "@octokit/tsconfig" "^1.0.2" - "@octokit/types" "^9.2.3" - -"@octokit/plugin-request-log@^1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz#5e50ed7083a613816b1e4a28aeec5fb7f1462e85" - integrity sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA== - -"@octokit/plugin-rest-endpoint-methods@^7.1.2": - version "7.2.3" - resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.2.3.tgz#37a84b171a6cb6658816c82c4082ac3512021797" - integrity sha512-I5Gml6kTAkzVlN7KCtjOM+Ruwe/rQppp0QU372K1GP7kNOYEKe8Xn5BW4sE62JAHdwpq95OQK/qGNyKQMUzVgA== - dependencies: - "@octokit/types" "^10.0.0" - -"@octokit/request-error@^3.0.0": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-3.0.3.tgz#ef3dd08b8e964e53e55d471acfe00baa892b9c69" - integrity sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ== - dependencies: - "@octokit/types" "^9.0.0" - deprecation "^2.0.0" - once "^1.4.0" - -"@octokit/request@^6.0.0": - version "6.2.8" - resolved "https://registry.yarnpkg.com/@octokit/request/-/request-6.2.8.tgz#aaf480b32ab2b210e9dadd8271d187c93171d8eb" - integrity sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw== - dependencies: - "@octokit/endpoint" "^7.0.0" - "@octokit/request-error" "^3.0.0" - "@octokit/types" "^9.0.0" - is-plain-object "^5.0.0" - node-fetch "^2.6.7" - universal-user-agent "^6.0.0" - -"@octokit/rest@19.0.11": - version "19.0.11" - resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-19.0.11.tgz#2ae01634fed4bd1fca5b642767205ed3fd36177c" - integrity sha512-m2a9VhaP5/tUw8FwfnW2ICXlXpLPIqxtg3XcAiGMLj/Xhw3RSBfZ8le/466ktO1Gcjr8oXudGnHhxV1TXJgFxw== - dependencies: - "@octokit/core" "^4.2.1" - "@octokit/plugin-paginate-rest" "^6.1.2" - "@octokit/plugin-request-log" "^1.0.4" - "@octokit/plugin-rest-endpoint-methods" "^7.1.2" - -"@octokit/tsconfig@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@octokit/tsconfig/-/tsconfig-1.0.2.tgz#59b024d6f3c0ed82f00d08ead5b3750469125af7" - integrity sha512-I0vDR0rdtP8p2lGMzvsJzbhdOWy405HcGovrspJ8RRibHnyRgggUSNO5AIox5LmqiwmatHKYsvj6VGFHkqS7lA== - -"@octokit/types@^10.0.0": - version "10.0.0" - resolved "https://registry.yarnpkg.com/@octokit/types/-/types-10.0.0.tgz#7ee19c464ea4ada306c43f1a45d444000f419a4a" - integrity sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg== - dependencies: - "@octokit/openapi-types" "^18.0.0" - -"@octokit/types@^9.0.0", "@octokit/types@^9.2.3": - version "9.3.2" - resolved "https://registry.yarnpkg.com/@octokit/types/-/types-9.3.2.tgz#3f5f89903b69f6a2d196d78ec35f888c0013cac5" - integrity sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA== - dependencies: - "@octokit/openapi-types" "^18.0.0" - -"@parcel/watcher@2.0.4": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@parcel/watcher/-/watcher-2.0.4.tgz#f300fef4cc38008ff4b8c29d92588eced3ce014b" - integrity sha512-cTDi+FUDBIUOBKEtj+nhiJ71AZVlkAsQFuGQTun5tV9mwQBQgZvhCzG+URPQc8myeN32yRVZEfVAPCs1RW+Jvg== - dependencies: - node-addon-api "^3.2.1" - node-gyp-build "^4.3.0" - -"@particle-network/analytics@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@particle-network/analytics/-/analytics-1.0.1.tgz#b3657cf7aaea57f90a7ac2c03f72b8786c298012" - integrity sha512-ApcSMo1BXQlywO+lvOpG3Y2/SVGNCpJzXO/4e3zHzE/9j+uMehsilDzPwWQwLhrCXZYwVm7mmE71Gs36yobiNw== - dependencies: - hash.js "^1.1.7" - uuidv4 "^6.2.13" - -"@particle-network/auth@^1.2.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@particle-network/auth/-/auth-1.3.1.tgz#f9ee51749e3b10e700e0d8c51a8c0769ab0b9851" - integrity sha512-hu6ie5RjjN4X+6y/vfjyCsSX3pQuS8k8ZoMb61QWwhWsnZXKzpBUVeAEk55aGfxxXY+KfBkSmZosyaZHGoHnfw== - dependencies: - "@particle-network/analytics" "^1.0.1" - "@particle-network/chains" "*" - "@particle-network/crypto" "^1.0.1" - buffer "^6.0.3" - draggabilly "^3.0.0" - -"@particle-network/biconomy@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@particle-network/biconomy/-/biconomy-1.0.0.tgz#91f79c6341db0fc9b23d3ed9c61fbb08df727c31" - integrity sha512-MvYdTGT48WJB72SqkmZbx3NI8HdjWb8EZNKIkbddcusws/Uqy4dHV2+tP7UWup+vGltCXK/55KAdvgcwFTsZrQ== - dependencies: - axios "^1.3.6" - uuid "^8.3.2" - -"@particle-network/chains@*": - version "1.3.21" - resolved "https://registry.yarnpkg.com/@particle-network/chains/-/chains-1.3.21.tgz#82d2b098e165fc198e6e6e3e4c8b2154235e3aa1" - integrity sha512-tuUVuOPf+el+kDlHLFMyDy4IkoGjk+P3QvVrxT7WnmEma1NgWTE7RaNsniwqn6SYkAwAxksL/D9aADUXZxqPmw== - -"@particle-network/crypto@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@particle-network/crypto/-/crypto-1.0.1.tgz#26afef622a3eb906dca5c810fef8001ffee29029" - integrity sha512-GgvHmHcFiNkCLZdcJOgctSbgvs251yp+EAdUydOE3gSoIxN6KEr/Snu9DebENhd/nFb7FDk5ap0Hg49P7pj1fg== - dependencies: - crypto-js "^4.1.1" - uuidv4 "^6.2.13" - -"@particle-network/provider@^1.2.0": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@particle-network/provider/-/provider-1.3.2.tgz#68ae98cca471c7612206cb43c915719cd321fb25" - integrity sha512-3XAUMCISTMYE57LZik7PrVanLIUyyU1ufb5eHtsoQw5ORfH0IeX3E5o6x5mxtfOXKfxVQ0tsIoLRMw0jMmSDpA== - dependencies: - "@particle-network/chains" "*" - axios "^1.3.6" - uuid "^8.3.2" - -"@pkgjs/parseargs@^0.11.0": - version "0.11.0" - resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" - integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== - -"@pkgr/core@^0.1.0": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.1.tgz#1ec17e2edbec25c8306d424ecfbf13c7de1aaa31" - integrity sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA== - -"@scure/base@~1.1.0", "@scure/base@~1.1.2", "@scure/base@~1.1.4": - version "1.1.5" - resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.5.tgz#1d85d17269fe97694b9c592552dd9e5e33552157" - integrity sha512-Brj9FiG2W1MRQSTB212YVPRrcbjkv48FoZi/u4l/zds/ieRrqsh7aUf6CLwkAq61oKXr/ZlTzlY66gLIj3TFTQ== - -"@scure/bip32@1.1.5": - version "1.1.5" - resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.1.5.tgz#d2ccae16dcc2e75bc1d75f5ef3c66a338d1ba300" - integrity sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw== - dependencies: - "@noble/hashes" "~1.2.0" - "@noble/secp256k1" "~1.7.0" - "@scure/base" "~1.1.0" - -"@scure/bip32@1.3.2": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.2.tgz#90e78c027d5e30f0b22c1f8d50ff12f3fb7559f8" - integrity sha512-N1ZhksgwD3OBlwTv3R6KFEcPojl/W4ElJOeCZdi+vuI5QmTFwLq3OFf2zd2ROpKvxFdgZ6hUpb0dx9bVNEwYCA== - dependencies: - "@noble/curves" "~1.2.0" - "@noble/hashes" "~1.3.2" - "@scure/base" "~1.1.2" - -"@scure/bip32@1.3.3": - version "1.3.3" - resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.3.tgz#a9624991dc8767087c57999a5d79488f48eae6c8" - integrity sha512-LJaN3HwRbfQK0X1xFSi0Q9amqOgzQnnDngIt+ZlsBC3Bm7/nE7K0kwshZHyaru79yIVRv/e1mQAjZyuZG6jOFQ== - dependencies: - "@noble/curves" "~1.3.0" - "@noble/hashes" "~1.3.2" - "@scure/base" "~1.1.4" - -"@scure/bip39@1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.1.1.tgz#b54557b2e86214319405db819c4b6a370cf340c5" - integrity sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg== - dependencies: - "@noble/hashes" "~1.2.0" - "@scure/base" "~1.1.0" - -"@scure/bip39@1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.1.tgz#5cee8978656b272a917b7871c981e0541ad6ac2a" - integrity sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg== - dependencies: - "@noble/hashes" "~1.3.0" - "@scure/base" "~1.1.0" - -"@scure/bip39@1.2.2": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.2.tgz#f3426813f4ced11a47489cbcf7294aa963966527" - integrity sha512-HYf9TUXG80beW+hGAt3TRM8wU6pQoYur9iNypTROm42dorCGmLnFe3eWjz3gOq6G62H2WRh0FCzAR1PI+29zIA== - dependencies: - "@noble/hashes" "~1.3.2" - "@scure/base" "~1.1.4" - -"@sentry/core@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.30.0.tgz#6b203664f69e75106ee8b5a2fe1d717379b331f3" - integrity sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg== - dependencies: - "@sentry/hub" "5.30.0" - "@sentry/minimal" "5.30.0" - "@sentry/types" "5.30.0" - "@sentry/utils" "5.30.0" - tslib "^1.9.3" - -"@sentry/hub@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.30.0.tgz#2453be9b9cb903404366e198bd30c7ca74cdc100" - integrity sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ== - dependencies: - "@sentry/types" "5.30.0" - "@sentry/utils" "5.30.0" - tslib "^1.9.3" - -"@sentry/minimal@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.30.0.tgz#ce3d3a6a273428e0084adcb800bc12e72d34637b" - integrity sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw== - dependencies: - "@sentry/hub" "5.30.0" - "@sentry/types" "5.30.0" - tslib "^1.9.3" - -"@sentry/node@^5.18.1": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/node/-/node-5.30.0.tgz#4ca479e799b1021285d7fe12ac0858951c11cd48" - integrity sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg== - dependencies: - "@sentry/core" "5.30.0" - "@sentry/hub" "5.30.0" - "@sentry/tracing" "5.30.0" - "@sentry/types" "5.30.0" - "@sentry/utils" "5.30.0" - cookie "^0.4.1" - https-proxy-agent "^5.0.0" - lru_map "^0.3.3" - tslib "^1.9.3" - -"@sentry/tracing@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.30.0.tgz#501d21f00c3f3be7f7635d8710da70d9419d4e1f" - integrity sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw== - dependencies: - "@sentry/hub" "5.30.0" - "@sentry/minimal" "5.30.0" - "@sentry/types" "5.30.0" - "@sentry/utils" "5.30.0" - tslib "^1.9.3" - -"@sentry/types@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.30.0.tgz#19709bbe12a1a0115bc790b8942917da5636f402" - integrity sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw== - -"@sentry/utils@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.30.0.tgz#9a5bd7ccff85ccfe7856d493bffa64cabc41e980" - integrity sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww== - dependencies: - "@sentry/types" "5.30.0" - tslib "^1.9.3" - -"@sigstore/bundle@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@sigstore/bundle/-/bundle-1.1.0.tgz#17f8d813b09348b16eeed66a8cf1c3d6bd3d04f1" - integrity sha512-PFutXEy0SmQxYI4texPw3dd2KewuNqv7OuK1ZFtY2fM754yhvG2KdgwIhRnoEE2uHdtdGNQ8s0lb94dW9sELog== - dependencies: - "@sigstore/protobuf-specs" "^0.2.0" - -"@sigstore/protobuf-specs@^0.2.0": - version "0.2.1" - resolved "https://registry.yarnpkg.com/@sigstore/protobuf-specs/-/protobuf-specs-0.2.1.tgz#be9ef4f3c38052c43bd399d3f792c97ff9e2277b" - integrity sha512-XTWVxnWJu+c1oCshMLwnKvz8ZQJJDVOlciMfgpJBQbThVjKTCG8dwyhgLngBD2KN0ap9F/gOV8rFDEx8uh7R2A== - -"@sigstore/sign@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@sigstore/sign/-/sign-1.0.0.tgz#6b08ebc2f6c92aa5acb07a49784cb6738796f7b4" - integrity sha512-INxFVNQteLtcfGmcoldzV6Je0sbbfh9I16DM4yJPw3j5+TFP8X6uIiA18mvpEa9yyeycAKgPmOA3X9hVdVTPUA== - dependencies: - "@sigstore/bundle" "^1.1.0" - "@sigstore/protobuf-specs" "^0.2.0" - make-fetch-happen "^11.0.1" - -"@sigstore/tuf@^1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@sigstore/tuf/-/tuf-1.0.3.tgz#2a65986772ede996485728f027b0514c0b70b160" - integrity sha512-2bRovzs0nJZFlCN3rXirE4gwxCn97JNjMmwpecqlbgV9WcxX7WRuIrgzx/X7Ib7MYRbyUTpBYE0s2x6AmZXnlg== - dependencies: - "@sigstore/protobuf-specs" "^0.2.0" - tuf-js "^1.1.7" - -"@sinclair/typebox@^0.27.8": - version "0.27.8" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" - integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== - -"@sinonjs/commons@^3.0.0": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.1.tgz#1029357e44ca901a615585f6d27738dbc89084cd" - integrity sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ== - dependencies: - type-detect "4.0.8" - -"@sinonjs/fake-timers@^10.0.2": - version "10.3.0" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz#55fdff1ecab9f354019129daf4df0dd4d923ea66" - integrity sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA== - dependencies: - "@sinonjs/commons" "^3.0.0" - -"@tootallnate/once@1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" - integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== - -"@tootallnate/once@2": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" - integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== - -"@transak/transak-sdk@^1.2.3": - version "1.4.1" - resolved "https://registry.yarnpkg.com/@transak/transak-sdk/-/transak-sdk-1.4.1.tgz#90dee041b772c71c35cfb22df9ef51970b780db4" - integrity sha512-/BKzb9orz1xDxa41oOPW+4KpjSHNEXgtaFazX/aIjQbr7LLbRqfXC/IHzpPmjR9OmFm8pFhV2Y86Rg0aZt5ZUA== - dependencies: - events "^3.3.0" - query-string "^8.1.0" - -"@trufflesuite/bigint-buffer@1.1.10": - version "1.1.10" - resolved "https://registry.yarnpkg.com/@trufflesuite/bigint-buffer/-/bigint-buffer-1.1.10.tgz#a1d9ca22d3cad1a138b78baaf15543637a3e1692" - integrity sha512-pYIQC5EcMmID74t26GCC67946mgTJFiLXOT/BYozgrd4UEY2JHEGLhWi9cMiQCt5BSqFEvKkCHNnoj82SRjiEw== - dependencies: - node-gyp-build "4.4.0" - -"@trufflesuite/uws-js-unofficial@20.30.0-unofficial.0": - version "20.30.0-unofficial.0" - resolved "https://registry.yarnpkg.com/@trufflesuite/uws-js-unofficial/-/uws-js-unofficial-20.30.0-unofficial.0.tgz#2fbc2f8ef7e82fbeea6abaf7e8a9d42a02b479d3" - integrity sha512-r5X0aOQcuT6pLwTRLD+mPnAM/nlKtvIK4Z+My++A8tTOR0qTjNRx8UB8jzRj3D+p9PMAp5LnpCUUGmz7/TppwA== - dependencies: - ws "8.13.0" - optionalDependencies: - bufferutil "4.0.7" - utf-8-validate "6.0.3" - -"@tsconfig/node10@^1.0.7": - version "1.0.9" - resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" - integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== - -"@tsconfig/node12@^1.0.7": - version "1.0.11" - resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" - integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== - -"@tsconfig/node14@^1.0.0": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" - integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== - -"@tsconfig/node16@^1.0.2": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" - integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== - -"@tufjs/canonical-json@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@tufjs/canonical-json/-/canonical-json-1.0.0.tgz#eade9fd1f537993bc1f0949f3aea276ecc4fab31" - integrity sha512-QTnf++uxunWvG2z3UFNzAoQPHxnSXOwtaI3iJ+AohhV+5vONuArPjJE7aPXPVXfXJsqrVbZBu9b81AJoSd09IQ== - -"@tufjs/models@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@tufjs/models/-/models-1.0.4.tgz#5a689630f6b9dbda338d4b208019336562f176ef" - integrity sha512-qaGV9ltJP0EO25YfFUPhxRVK0evXFIAGicsVXuRim4Ed9cjPxYhNnNJ49SFmbeLgtxpslIkX317IgpfcHPVj/A== - dependencies: - "@tufjs/canonical-json" "1.0.0" - minimatch "^9.0.0" - -"@types/babel__core@^7.1.14": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" - integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== - dependencies: - "@babel/parser" "^7.20.7" - "@babel/types" "^7.20.7" - "@types/babel__generator" "*" - "@types/babel__template" "*" - "@types/babel__traverse" "*" - -"@types/babel__generator@*": - version "7.6.8" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.8.tgz#f836c61f48b1346e7d2b0d93c6dacc5b9535d3ab" - integrity sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw== - dependencies: - "@babel/types" "^7.0.0" - -"@types/babel__template@*": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f" - integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== - dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" - -"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.5.tgz#7b7502be0aa80cc4ef22978846b983edaafcd4dd" - integrity sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ== - dependencies: - "@babel/types" "^7.20.7" - -"@types/bn.js@^4.11.3": - version "4.11.6" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" - integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== - dependencies: - "@types/node" "*" - -"@types/bn.js@^5.1.0": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.5.tgz#2e0dacdcce2c0f16b905d20ff87aedbc6f7b4bf0" - integrity sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A== - dependencies: - "@types/node" "*" - -"@types/debug@^4.1.9": - version "4.1.12" - resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.12.tgz#a155f21690871953410df4b6b6f53187f0500917" - integrity sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ== - dependencies: - "@types/ms" "*" - -"@types/graceful-fs@^4.1.3": - version "4.1.9" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz#2a06bc0f68a20ab37b3e36aa238be6abdf49e8b4" - integrity sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ== - dependencies: - "@types/node" "*" - -"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": - version "2.0.6" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7" - integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w== - -"@types/istanbul-lib-report@*": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz#53047614ae72e19fc0401d872de3ae2b4ce350bf" - integrity sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA== - dependencies: - "@types/istanbul-lib-coverage" "*" - -"@types/istanbul-reports@^3.0.0": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz#0f03e3d2f670fbdac586e34b433783070cc16f54" - integrity sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ== - dependencies: - "@types/istanbul-lib-report" "*" - -"@types/jest@^29.5.4": - version "29.5.12" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.12.tgz#7f7dc6eb4cf246d2474ed78744b05d06ce025544" - integrity sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw== - dependencies: - expect "^29.0.0" - pretty-format "^29.0.0" - -"@types/json-schema@^7.0.12": - version "7.0.15" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" - integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== - -"@types/json5@^0.0.29": - version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" - integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== - -"@types/lru-cache@5.1.1", "@types/lru-cache@^5.1.0": - version "5.1.1" - resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.1.tgz#c48c2e27b65d2a153b19bfc1a317e30872e01eef" - integrity sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw== - -"@types/minimatch@^3.0.3": - version "3.0.5" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" - integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== - -"@types/minimist@^1.2.0": - version "1.2.5" - resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.5.tgz#ec10755e871497bcd83efe927e43ec46e8c0747e" - integrity sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag== - -"@types/ms@*": - version "0.7.34" - resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.34.tgz#10964ba0dee6ac4cd462e2795b6bebd407303433" - integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g== - -"@types/node@*", "@types/node@^20.11.10": - version "20.11.25" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.25.tgz#0f50d62f274e54dd7a49f7704cc16bfbcccaf49f" - integrity sha512-TBHyJxk2b7HceLVGFcpAUjsa5zIdsPWlR6XHfyGzd0SFu+/NFgQgMAl96MSDZgQDvJAvV6BKsFOrt6zIL09JDw== - dependencies: - undici-types "~5.26.4" - -"@types/normalize-package-data@^2.4.0": - version "2.4.4" - resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901" - integrity sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA== - -"@types/pbkdf2@^3.0.0": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@types/pbkdf2/-/pbkdf2-3.1.2.tgz#2dc43808e9985a2c69ff02e2d2027bd4fe33e8dc" - integrity sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew== - dependencies: - "@types/node" "*" - -"@types/secp256k1@^4.0.1": - version "4.0.6" - resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.6.tgz#d60ba2349a51c2cbc5e816dcd831a42029d376bf" - integrity sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ== - dependencies: - "@types/node" "*" - -"@types/seedrandom@3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/seedrandom/-/seedrandom-3.0.1.tgz#1254750a4fec4aff2ebec088ccd0bb02e91fedb4" - integrity sha512-giB9gzDeiCeloIXDgzFBCgjj1k4WxcDrZtGl6h1IqmUPlxF+Nx8Ve+96QCyDZ/HseB/uvDsKbpib9hU5cU53pw== - -"@types/semver@^7.5.0": - version "7.5.8" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e" - integrity sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ== - -"@types/stack-utils@^2.0.0": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" - integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== - -"@types/triple-beam@^1.3.2": - version "1.3.5" - resolved "https://registry.yarnpkg.com/@types/triple-beam/-/triple-beam-1.3.5.tgz#74fef9ffbaa198eb8b588be029f38b00299caa2c" - integrity sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw== - -"@types/uuid@8.3.4": - version "8.3.4" - resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" - integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== - -"@types/yargs-parser@*": - version "21.0.3" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" - integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== - -"@types/yargs@^17.0.8": - version "17.0.32" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.32.tgz#030774723a2f7faafebf645f4e5a48371dca6229" - integrity sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog== - dependencies: - "@types/yargs-parser" "*" - -"@typescript-eslint/eslint-plugin@^6.7.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz#30830c1ca81fd5f3c2714e524c4303e0194f9cd3" - integrity sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA== - dependencies: - "@eslint-community/regexpp" "^4.5.1" - "@typescript-eslint/scope-manager" "6.21.0" - "@typescript-eslint/type-utils" "6.21.0" - "@typescript-eslint/utils" "6.21.0" - "@typescript-eslint/visitor-keys" "6.21.0" - debug "^4.3.4" - graphemer "^1.4.0" - ignore "^5.2.4" - natural-compare "^1.4.0" - semver "^7.5.4" - ts-api-utils "^1.0.1" - -"@typescript-eslint/parser@^6.6.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.21.0.tgz#af8fcf66feee2edc86bc5d1cf45e33b0630bf35b" - integrity sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ== - dependencies: - "@typescript-eslint/scope-manager" "6.21.0" - "@typescript-eslint/types" "6.21.0" - "@typescript-eslint/typescript-estree" "6.21.0" - "@typescript-eslint/visitor-keys" "6.21.0" - debug "^4.3.4" - -"@typescript-eslint/scope-manager@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz#ea8a9bfc8f1504a6ac5d59a6df308d3a0630a2b1" - integrity sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg== - dependencies: - "@typescript-eslint/types" "6.21.0" - "@typescript-eslint/visitor-keys" "6.21.0" - -"@typescript-eslint/type-utils@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz#6473281cfed4dacabe8004e8521cee0bd9d4c01e" - integrity sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag== - dependencies: - "@typescript-eslint/typescript-estree" "6.21.0" - "@typescript-eslint/utils" "6.21.0" - debug "^4.3.4" - ts-api-utils "^1.0.1" - -"@typescript-eslint/types@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.21.0.tgz#205724c5123a8fef7ecd195075fa6e85bac3436d" - integrity sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg== - -"@typescript-eslint/typescript-estree@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz#c47ae7901db3b8bddc3ecd73daff2d0895688c46" - integrity sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ== - dependencies: - "@typescript-eslint/types" "6.21.0" - "@typescript-eslint/visitor-keys" "6.21.0" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - minimatch "9.0.3" - semver "^7.5.4" - ts-api-utils "^1.0.1" - -"@typescript-eslint/utils@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.21.0.tgz#4714e7a6b39e773c1c8e97ec587f520840cd8134" - integrity sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ== - dependencies: - "@eslint-community/eslint-utils" "^4.4.0" - "@types/json-schema" "^7.0.12" - "@types/semver" "^7.5.0" - "@typescript-eslint/scope-manager" "6.21.0" - "@typescript-eslint/types" "6.21.0" - "@typescript-eslint/typescript-estree" "6.21.0" - semver "^7.5.4" - -"@typescript-eslint/visitor-keys@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz#87a99d077aa507e20e238b11d56cc26ade45fe47" - integrity sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A== - dependencies: - "@typescript-eslint/types" "6.21.0" - eslint-visitor-keys "^3.4.1" - -"@ungap/structured-clone@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" - integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== - -"@yarnpkg/lockfile@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" - integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== - -"@yarnpkg/parsers@3.0.0-rc.46": - version "3.0.0-rc.46" - resolved "https://registry.yarnpkg.com/@yarnpkg/parsers/-/parsers-3.0.0-rc.46.tgz#03f8363111efc0ea670e53b0282cd3ef62de4e01" - integrity sha512-aiATs7pSutzda/rq8fnuPwTglyVwjM22bNnK2ZgjrpAjQHSSl3lztd2f9evst1W/qnC58DRz7T7QndUDumAR4Q== - dependencies: - js-yaml "^3.10.0" - tslib "^2.4.0" - -"@zkochan/js-yaml@0.0.6": - version "0.0.6" - resolved "https://registry.yarnpkg.com/@zkochan/js-yaml/-/js-yaml-0.0.6.tgz#975f0b306e705e28b8068a07737fa46d3fc04826" - integrity sha512-nzvgl3VfhcELQ8LyVrYOru+UtAy1nrygk2+AGbTm8a5YcO6o8lSjAT+pfg3vJWxIoZKOUhrK6UU7xW/+00kQrg== - dependencies: - argparse "^2.0.1" - -JSONStream@^1.3.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" - integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== - dependencies: - jsonparse "^1.2.0" - through ">=2.2.7 <3" - -abbrev@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - -abitype@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/abitype/-/abitype-1.0.0.tgz#237176dace81d90d018bebf3a45cb42f2a2d9e97" - integrity sha512-NMeMah//6bJ56H5XRj8QCV4AwuW6hB6zqz2LnhhLdcWVQOsXki6/Pn3APeqxCma62nXIcmZWdu1DlHWS74umVQ== - -abitype@^0.8.3: - version "0.8.11" - resolved "https://registry.yarnpkg.com/abitype/-/abitype-0.8.11.tgz#66e1cf2cbf46f48d0e57132d7c1c392447536cc1" - integrity sha512-bM4v2dKvX08sZ9IU38IN5BKmN+ZkOSd2oI4a9f0ejHYZQYV6cDr7j+d95ga0z2XHG36Y4jzoG5Z7qDqxp7fi/A== - -abstract-level@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/abstract-level/-/abstract-level-1.0.3.tgz#78a67d3d84da55ee15201486ab44c09560070741" - integrity sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA== - dependencies: - buffer "^6.0.3" - catering "^2.1.0" - is-buffer "^2.0.5" - level-supports "^4.0.0" - level-transcoder "^1.0.1" - module-error "^1.0.1" - queue-microtask "^1.2.3" - -abstract-leveldown@7.2.0, abstract-leveldown@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-7.2.0.tgz#08d19d4e26fb5be426f7a57004851b39e1795a2e" - integrity sha512-DnhQwcFEaYsvYDnACLZhMmCWd3rkOeEvglpa4q5i/5Jlm3UIsWaxVzuXvDLFCSCWRO3yy2/+V/G7FusFgejnfQ== - dependencies: - buffer "^6.0.3" - catering "^2.0.0" - is-buffer "^2.0.5" - level-concat-iterator "^3.0.0" - level-supports "^2.0.1" - queue-microtask "^1.2.3" - -acorn-jsx@^5.3.2: - version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" - integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== - -acorn-walk@^8.1.1: - version "8.3.2" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.2.tgz#7703af9415f1b6db9315d6895503862e231d34aa" - integrity sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A== - -acorn@^8.4.1, acorn@^8.9.0: - version "8.11.3" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" - integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== - -add-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" - integrity sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ== - -adm-zip@^0.4.16: - version "0.4.16" - resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.16.tgz#cf4c508fdffab02c269cbc7f471a875f05570365" - integrity sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg== - -aes-js@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" - integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw== - -agent-base@6, agent-base@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - -agentkeepalive@^4.1.3, agentkeepalive@^4.2.1: - version "4.5.0" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.5.0.tgz#2673ad1389b3c418c5a20c5d7364f93ca04be923" - integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew== - dependencies: - humanize-ms "^1.2.1" - -aggregate-error@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" - integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== - dependencies: - clean-stack "^2.0.0" - indent-string "^4.0.0" - -ajv@^6.12.4: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-align@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" - integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== - dependencies: - string-width "^4.1.0" - -ansi-colors@4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - -ansi-colors@^4.1.1: - version "4.1.3" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" - integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== - -ansi-escapes@^4.2.1, ansi-escapes@^4.3.0: - version "4.3.2" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" - integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== - dependencies: - type-fest "^0.21.3" - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-regex@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== - -ansi-sequence-parser@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz#e0aa1cdcbc8f8bb0b5bca625aac41f5f056973cf" - integrity sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg== - -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -ansi-styles@^5.0.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" - integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== - -ansi-styles@^6.1.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" - integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== - -any-promise@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" - integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== - -anymatch@^3.0.3, anymatch@~3.1.2: - version "3.1.3" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" - integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -"aproba@^1.0.3 || ^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" - integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== - -are-we-there-yet@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz#679df222b278c64f2cdba1175cdc00b0d96164bd" - integrity sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg== - dependencies: - delegates "^1.0.0" - readable-stream "^3.6.0" - -arg@^4.1.0: - version "4.1.3" - resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" - integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -args@5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/args/-/args-5.0.3.tgz#943256db85021a85684be2f0882f25d796278702" - integrity sha512-h6k/zfFgusnv3i5TU08KQkVKuCPBtL/PWQbWkHUxvJrZ2nAyeaUupneemcrgn1xmqxPQsPIzwkUhOpoqPDRZuA== - dependencies: - camelcase "5.0.0" - chalk "2.4.2" - leven "2.1.0" - mri "1.1.4" - -array-buffer-byte-length@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz#1e5583ec16763540a27ae52eed99ff899223568f" - integrity sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg== - dependencies: - call-bind "^1.0.5" - is-array-buffer "^3.0.4" - -array-differ@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-3.0.0.tgz#3cbb3d0f316810eafcc47624734237d6aee4ae6b" - integrity sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg== - -array-ify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" - integrity sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng== - -array-includes@^3.1.7: - version "3.1.7" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.7.tgz#8cd2e01b26f7a3086cbc87271593fe921c62abda" - integrity sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - is-string "^1.0.7" - -array-union@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" - integrity sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng== - dependencies: - array-uniq "^1.0.1" - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -array-uniq@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" - integrity sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q== - -array.prototype.filter@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/array.prototype.filter/-/array.prototype.filter-1.0.3.tgz#423771edeb417ff5914111fff4277ea0624c0d0e" - integrity sha512-VizNcj/RGJiUyQBgzwxzE5oHdeuXY5hSbbmKMlphj1cy1Vl7Pn2asCGbSrru6hSQjmCzqTBPVWAF/whmEOVHbw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-array-method-boxes-properly "^1.0.0" - is-string "^1.0.7" - -array.prototype.findlastindex@^1.2.3: - version "1.2.4" - resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.4.tgz#d1c50f0b3a9da191981ff8942a0aedd82794404f" - integrity sha512-hzvSHUshSpCflDR1QMUBLHGHP1VIEBegT4pix9H/Z92Xw3ySoy6c2qh7lJWTJnRJ8JCZ9bJNCgTyYaJGcJu6xQ== - dependencies: - call-bind "^1.0.5" - define-properties "^1.2.1" - es-abstract "^1.22.3" - es-errors "^1.3.0" - es-shim-unscopables "^1.0.2" - -array.prototype.flat@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz#1476217df8cff17d72ee8f3ba06738db5b387d18" - integrity sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - -array.prototype.flatmap@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz#c9a7c6831db8e719d6ce639190146c24bbd3e527" - integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - -arraybuffer.prototype.slice@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz#097972f4255e41bc3425e37dc3f6421cf9aefde6" - integrity sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A== - dependencies: - array-buffer-byte-length "^1.0.1" - call-bind "^1.0.5" - define-properties "^1.2.1" - es-abstract "^1.22.3" - es-errors "^1.2.1" - get-intrinsic "^1.2.3" - is-array-buffer "^3.0.4" - is-shared-array-buffer "^1.0.2" - -arrify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" - integrity sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA== - -arrify@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" - integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== - -async-eventemitter@0.2.4: - version "0.2.4" - resolved "https://registry.yarnpkg.com/async-eventemitter/-/async-eventemitter-0.2.4.tgz#f5e7c8ca7d3e46aab9ec40a292baf686a0bafaca" - integrity sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw== - dependencies: - async "^2.4.0" - -async@^2.4.0: - version "2.6.4" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" - integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== - dependencies: - lodash "^4.17.14" - -async@^3.2.3, async@^3.2.4: - version "3.2.5" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.5.tgz#ebd52a8fdaf7a2289a24df399f8d8485c8a46b66" - integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg== - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== - -available-typed-arrays@^1.0.6, available-typed-arrays@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846" - integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ== - dependencies: - possible-typed-array-names "^1.0.0" - -axios@^1.0.0, axios@^1.3.6: - version "1.6.7" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.7.tgz#7b48c2e27c96f9c68a2f8f31e2ab19f59b06b0a7" - integrity sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA== - dependencies: - follow-redirects "^1.15.4" - form-data "^4.0.0" - proxy-from-env "^1.1.0" - -babel-jest@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" - integrity sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg== - dependencies: - "@jest/transform" "^29.7.0" - "@types/babel__core" "^7.1.14" - babel-plugin-istanbul "^6.1.1" - babel-preset-jest "^29.6.3" - chalk "^4.0.0" - graceful-fs "^4.2.9" - slash "^3.0.0" - -babel-plugin-istanbul@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" - integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@istanbuljs/load-nyc-config" "^1.0.0" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-instrument "^5.0.4" - test-exclude "^6.0.0" - -babel-plugin-jest-hoist@^29.6.3: - version "29.6.3" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz#aadbe943464182a8922c3c927c3067ff40d24626" - integrity sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg== - dependencies: - "@babel/template" "^7.3.3" - "@babel/types" "^7.3.3" - "@types/babel__core" "^7.1.14" - "@types/babel__traverse" "^7.0.6" - -babel-preset-current-node-syntax@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" - integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== - dependencies: - "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/plugin-syntax-bigint" "^7.8.3" - "@babel/plugin-syntax-class-properties" "^7.8.3" - "@babel/plugin-syntax-import-meta" "^7.8.3" - "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.8.3" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-syntax-top-level-await" "^7.8.3" - -babel-preset-jest@^29.6.3: - version "29.6.3" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz#fa05fa510e7d493896d7b0dd2033601c840f171c" - integrity sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA== - dependencies: - babel-plugin-jest-hoist "^29.6.3" - babel-preset-current-node-syntax "^1.0.0" - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -base-x@^3.0.2: - version "3.0.9" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" - integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== - dependencies: - safe-buffer "^5.0.1" - -base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -bech32@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" - integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== - -before-after-hook@^2.2.0: - version "2.2.3" - resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.3.tgz#c51e809c81a4e354084422b9b26bad88249c517c" - integrity sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ== - -bignumber.js@^9.0.1: - version "9.1.2" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" - integrity sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug== - -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - -bl@^4.0.3, bl@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" - integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== - dependencies: - buffer "^5.5.0" - inherits "^2.0.4" - readable-stream "^3.4.0" - -blakejs@^1.1.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.2.1.tgz#5057e4206eadb4a97f7c0b6e197a505042fc3814" - integrity sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ== - -bn.js@4.11.6: - version "4.11.6" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" - integrity sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA== - -bn.js@^4.11.0, bn.js@^4.11.8, bn.js@^4.11.9: - version "4.12.0" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" - integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== - -bn.js@^5.2.0, bn.js@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" - integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== - -boxen@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" - integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== - dependencies: - ansi-align "^3.0.0" - camelcase "^6.2.0" - chalk "^4.1.0" - cli-boxes "^2.2.1" - string-width "^4.2.2" - type-fest "^0.20.2" - widest-line "^3.1.0" - wrap-ansi "^7.0.0" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== - dependencies: - balanced-match "^1.0.0" - -braces@^3.0.2, braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -brorand@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== - -browser-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== - -browserify-aes@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" - integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== - dependencies: - buffer-xor "^1.0.3" - cipher-base "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.3" - inherits "^2.0.1" - safe-buffer "^5.0.1" - -browserslist@^4.22.2: - version "4.23.0" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.0.tgz#8f3acc2bbe73af7213399430890f86c63a5674ab" - integrity sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ== - dependencies: - caniuse-lite "^1.0.30001587" - electron-to-chromium "^1.4.668" - node-releases "^2.0.14" - update-browserslist-db "^1.0.13" - -bs-logger@0.x: - version "0.2.6" - resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" - integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== - dependencies: - fast-json-stable-stringify "2.x" - -bs58@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" - integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw== - dependencies: - base-x "^3.0.2" - -bs58check@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" - integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== - dependencies: - bs58 "^4.0.0" - create-hash "^1.1.0" - safe-buffer "^5.1.2" - -bser@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" - integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== - dependencies: - node-int64 "^0.4.0" - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -buffer-reverse@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/buffer-reverse/-/buffer-reverse-1.0.1.tgz#49283c8efa6f901bc01fa3304d06027971ae2f60" - integrity sha512-M87YIUBsZ6N924W57vDwT/aOu8hw7ZgdByz6ijksLjmHJELBASmYTTlNHRgjE+pTsT9oJXGaDSgqqwfdHotDUg== - -buffer-xor@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" - integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ== - -buffer@^5.5.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" - integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.1.13" - -buffer@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" - integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.2.1" - -bufferutil@4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.5.tgz#da9ea8166911cc276bf677b8aed2d02d31f59028" - integrity sha512-HTm14iMQKK2FjFLRTM5lAVcyaUzOnqbPtesFIvREgXpJHdQm8bWS+GkQgIkfaBYRHuCnea7w8UVNfwiAQhlr9A== - dependencies: - node-gyp-build "^4.3.0" - -bufferutil@4.0.7: - version "4.0.7" - resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.7.tgz#60c0d19ba2c992dd8273d3f73772ffc894c153ad" - integrity sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw== - dependencies: - node-gyp-build "^4.3.0" - -builtins@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" - integrity sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ== - -builtins@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/builtins/-/builtins-5.0.1.tgz#87f6db9ab0458be728564fa81d876d8d74552fa9" - integrity sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ== - dependencies: - semver "^7.0.0" - -byte-size@8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-8.1.1.tgz#3424608c62d59de5bfda05d31e0313c6174842ae" - integrity sha512-tUkzZWK0M/qdoLEqikxBWe4kumyuwjl3HO6zHTr4yEI23EojPtLYXdG1+AQY7MN0cGyNDvEaJ8wiYQm6P2bPxg== - -bytes@3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" - integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== - -cacache@^15.2.0: - version "15.3.0" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.3.0.tgz#dc85380fb2f556fe3dda4c719bfa0ec875a7f1eb" - integrity sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ== - dependencies: - "@npmcli/fs" "^1.0.0" - "@npmcli/move-file" "^1.0.1" - chownr "^2.0.0" - fs-minipass "^2.0.0" - glob "^7.1.4" - infer-owner "^1.0.4" - lru-cache "^6.0.0" - minipass "^3.1.1" - minipass-collect "^1.0.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.2" - mkdirp "^1.0.3" - p-map "^4.0.0" - promise-inflight "^1.0.1" - rimraf "^3.0.2" - ssri "^8.0.1" - tar "^6.0.2" - unique-filename "^1.1.1" - -cacache@^16.1.0: - version "16.1.3" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-16.1.3.tgz#a02b9f34ecfaf9a78c9f4bc16fceb94d5d67a38e" - integrity sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ== - dependencies: - "@npmcli/fs" "^2.1.0" - "@npmcli/move-file" "^2.0.0" - chownr "^2.0.0" - fs-minipass "^2.1.0" - glob "^8.0.1" - infer-owner "^1.0.4" - lru-cache "^7.7.1" - minipass "^3.1.6" - minipass-collect "^1.0.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - mkdirp "^1.0.4" - p-map "^4.0.0" - promise-inflight "^1.0.1" - rimraf "^3.0.2" - ssri "^9.0.0" - tar "^6.1.11" - unique-filename "^2.0.0" - -cacache@^17.0.0: - version "17.1.4" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-17.1.4.tgz#b3ff381580b47e85c6e64f801101508e26604b35" - integrity sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A== - dependencies: - "@npmcli/fs" "^3.1.0" - fs-minipass "^3.0.0" - glob "^10.2.2" - lru-cache "^7.7.1" - minipass "^7.0.3" - minipass-collect "^1.0.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - p-map "^4.0.0" - ssri "^10.0.0" - tar "^6.1.11" - unique-filename "^3.0.0" - -call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" - integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== - dependencies: - es-define-property "^1.0.0" - es-errors "^1.3.0" - function-bind "^1.1.2" - get-intrinsic "^1.2.4" - set-function-length "^1.2.1" - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -camelcase-keys@^6.2.2: - version "6.2.2" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-6.2.2.tgz#5e755d6ba51aa223ec7d3d52f25778210f9dc3c0" - integrity sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg== - dependencies: - camelcase "^5.3.1" - map-obj "^4.0.0" - quick-lru "^4.0.1" - -camelcase@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42" - integrity sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA== - -camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -camelcase@^6.0.0, camelcase@^6.2.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" - integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== - -caniuse-lite@^1.0.30001587: - version "1.0.30001596" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001596.tgz#da06b79c3d9c3d9958eb307aa832ac68ead79bee" - integrity sha512-zpkZ+kEr6We7w63ORkoJ2pOfBwBkY/bJrG/UZ90qNb45Isblu8wzDgevEOrRL1r9dWayHjYiiyCMEXPn4DweGQ== - -catering@^2.0.0, catering@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/catering/-/catering-2.1.1.tgz#66acba06ed5ee28d5286133982a927de9a04b510" - integrity sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w== - -chalk@2.4.2, chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" - integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -char-regex@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" - integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== - -chardet@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" - integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== - -chokidar@3.5.3: - version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -chokidar@^3.4.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" - integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -chownr@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" - integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== - -ci-info@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" - integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== - -ci-info@^3.2.0, ci-info@^3.6.1: - version "3.9.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" - integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== - -cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" - integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -cjs-module-lexer@^1.0.0: - version "1.2.3" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" - integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== - -clean-stack@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" - integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== - -cli-boxes@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" - integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== - -cli-cursor@3.1.0, cli-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" - integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== - dependencies: - restore-cursor "^3.1.0" - -cli-highlight@^2.1.11: - version "2.1.11" - resolved "https://registry.yarnpkg.com/cli-highlight/-/cli-highlight-2.1.11.tgz#49736fa452f0aaf4fae580e30acb26828d2dc1bf" - integrity sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg== - dependencies: - chalk "^4.0.0" - highlight.js "^10.7.1" - mz "^2.4.0" - parse5 "^5.1.1" - parse5-htmlparser2-tree-adapter "^6.0.0" - yargs "^16.0.0" - -cli-spinners@2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.1.tgz#adc954ebe281c37a6319bfa401e6dd2488ffb70d" - integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g== - -cli-spinners@^2.5.0: - version "2.9.2" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41" - integrity sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg== - -cli-width@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" - integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== - -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -cliui@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" - integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.1" - wrap-ansi "^7.0.0" - -clone-deep@4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" - integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== - dependencies: - is-plain-object "^2.0.4" - kind-of "^6.0.2" - shallow-clone "^3.0.0" - -clone@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" - integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== - -cmd-shim@6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-6.0.1.tgz#a65878080548e1dca760b3aea1e21ed05194da9d" - integrity sha512-S9iI9y0nKR4hwEQsVWpyxld/6kRfGepGfzff83FcaiEBpmvlbA2nnGe7Cylgrx2f/p1P5S5wpRm9oL8z1PbS3Q== - -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== - -collect-v8-coverage@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9" - integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q== - -color-convert@^1.9.0, color-convert@^1.9.3: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - -color-name@^1.0.0, color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -color-string@^1.6.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4" - integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg== - dependencies: - color-name "^1.0.0" - simple-swizzle "^0.2.2" - -color-support@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" - integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== - -color@^3.1.3: - version "3.2.1" - resolved "https://registry.yarnpkg.com/color/-/color-3.2.1.tgz#3544dc198caf4490c3ecc9a790b54fe9ff45e164" - integrity sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA== - dependencies: - color-convert "^1.9.3" - color-string "^1.6.0" - -colorspace@1.1.x: - version "1.1.4" - resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.4.tgz#8d442d1186152f60453bf8070cd66eb364e59243" - integrity sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w== - dependencies: - color "^3.1.3" - text-hex "1.0.x" - -columnify@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.6.0.tgz#6989531713c9008bb29735e61e37acf5bd553cf3" - integrity sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q== - dependencies: - strip-ansi "^6.0.1" - wcwidth "^1.0.0" - -combined-stream@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -command-exists@^1.2.8: - version "1.2.9" - resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69" - integrity sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w== - -commander@3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" - integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== - -commander@^11.0.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-11.1.0.tgz#62fdce76006a68e5c1ab3314dc92e800eb83d906" - integrity sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ== - -commander@^2.9.0: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== - -compare-func@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/compare-func/-/compare-func-2.0.0.tgz#fb65e75edbddfd2e568554e8b5b05fff7a51fcb3" - integrity sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA== - dependencies: - array-ify "^1.0.0" - dot-prop "^5.1.0" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -concat-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-2.0.0.tgz#414cf5af790a48c60ab9be4527d56d5e41133cb1" - integrity sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.0.2" - typedarray "^0.0.6" - -concurrently@^8.2.2: - version "8.2.2" - resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-8.2.2.tgz#353141985c198cfa5e4a3ef90082c336b5851784" - integrity sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg== - dependencies: - chalk "^4.1.2" - date-fns "^2.30.0" - lodash "^4.17.21" - rxjs "^7.8.1" - shell-quote "^1.8.1" - spawn-command "0.0.2" - supports-color "^8.1.1" - tree-kill "^1.2.2" - yargs "^17.7.2" - -confusing-browser-globals@^1.0.10: - version "1.0.11" - resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz#ae40e9b57cdd3915408a2805ebd3a5585608dc81" - integrity sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA== - -console-control-strings@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== - -conventional-changelog-angular@7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz#5eec8edbff15aa9b1680a8dcfbd53e2d7eb2ba7a" - integrity sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ== - dependencies: - compare-func "^2.0.0" - -conventional-changelog-core@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/conventional-changelog-core/-/conventional-changelog-core-5.0.1.tgz#3c331b155d5b9850f47b4760aeddfc983a92ad49" - integrity sha512-Rvi5pH+LvgsqGwZPZ3Cq/tz4ty7mjijhr3qR4m9IBXNbxGGYgTVVO+duXzz9aArmHxFtwZ+LRkrNIMDQzgoY4A== - dependencies: - add-stream "^1.0.0" - conventional-changelog-writer "^6.0.0" - conventional-commits-parser "^4.0.0" - dateformat "^3.0.3" - get-pkg-repo "^4.2.1" - git-raw-commits "^3.0.0" - git-remote-origin-url "^2.0.0" - git-semver-tags "^5.0.0" - normalize-package-data "^3.0.3" - read-pkg "^3.0.0" - read-pkg-up "^3.0.0" - -conventional-changelog-preset-loader@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-3.0.0.tgz#14975ef759d22515d6eabae6396c2ae721d4c105" - integrity sha512-qy9XbdSLmVnwnvzEisjxdDiLA4OmV3o8db+Zdg4WiFw14fP3B6XNz98X0swPPpkTd/pc1K7+adKgEDM1JCUMiA== - -conventional-changelog-writer@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-6.0.1.tgz#d8d3bb5e1f6230caed969dcc762b1c368a8f7b01" - integrity sha512-359t9aHorPw+U+nHzUXHS5ZnPBOizRxfQsWT5ZDHBfvfxQOAik+yfuhKXG66CN5LEWPpMNnIMHUTCKeYNprvHQ== - dependencies: - conventional-commits-filter "^3.0.0" - dateformat "^3.0.3" - handlebars "^4.7.7" - json-stringify-safe "^5.0.1" - meow "^8.1.2" - semver "^7.0.0" - split "^1.0.1" - -conventional-commits-filter@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-3.0.0.tgz#bf1113266151dd64c49cd269e3eb7d71d7015ee2" - integrity sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q== - dependencies: - lodash.ismatch "^4.4.0" - modify-values "^1.0.1" - -conventional-commits-parser@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz#02ae1178a381304839bce7cea9da5f1b549ae505" - integrity sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg== - dependencies: - JSONStream "^1.3.5" - is-text-path "^1.0.1" - meow "^8.1.2" - split2 "^3.2.2" - -conventional-recommended-bump@7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/conventional-recommended-bump/-/conventional-recommended-bump-7.0.1.tgz#ec01f6c7f5d0e2491c2d89488b0d757393392424" - integrity sha512-Ft79FF4SlOFvX4PkwFDRnaNiIVX7YbmqGU0RwccUaiGvgp3S0a8ipR2/Qxk31vclDNM+GSdJOVs2KrsUCjblVA== - dependencies: - concat-stream "^2.0.0" - conventional-changelog-preset-loader "^3.0.0" - conventional-commits-filter "^3.0.0" - conventional-commits-parser "^4.0.0" - git-raw-commits "^3.0.0" - git-semver-tags "^5.0.0" - meow "^8.1.2" - -convert-source-map@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" - integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== - -cookie@^0.4.1: - version "0.4.2" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" - integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== - -core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== - -cosmiconfig@^8.2.0: - version "8.3.6" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3" - integrity sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA== - dependencies: - import-fresh "^3.3.0" - js-yaml "^4.1.0" - parse-json "^5.2.0" - path-type "^4.0.0" - -create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" - integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== - dependencies: - cipher-base "^1.0.1" - inherits "^2.0.1" - md5.js "^1.3.4" - ripemd160 "^2.0.1" - sha.js "^2.4.0" - -create-hmac@^1.1.4, create-hmac@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" - integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== - dependencies: - cipher-base "^1.0.3" - create-hash "^1.1.0" - inherits "^2.0.1" - ripemd160 "^2.0.0" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -create-jest@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/create-jest/-/create-jest-29.7.0.tgz#a355c5b3cb1e1af02ba177fe7afd7feee49a5320" - integrity sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q== - dependencies: - "@jest/types" "^29.6.3" - chalk "^4.0.0" - exit "^0.1.2" - graceful-fs "^4.2.9" - jest-config "^29.7.0" - jest-util "^29.7.0" - prompts "^2.0.1" - -create-require@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" - integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== - -cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -crypto-js@^4.1.1, crypto-js@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.2.0.tgz#4d931639ecdfd12ff80e8186dba6af2c2e856631" - integrity sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q== - -dargs@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/dargs/-/dargs-7.0.0.tgz#04015c41de0bcb69ec84050f3d9be0caf8d6d5cc" - integrity sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg== - -date-fns@^2.30.0: - version "2.30.0" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0" - integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw== - dependencies: - "@babel/runtime" "^7.21.0" - -dateformat@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" - integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== - -debug@4, debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -debug@^3.2.7: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -decamelize-keys@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.1.tgz#04a2d523b2f18d80d0158a43b895d56dff8d19d8" - integrity sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg== - dependencies: - decamelize "^1.1.0" - map-obj "^1.0.0" - -decamelize@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== - -decamelize@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" - integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== - -decode-uri-component@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.4.1.tgz#2ac4859663c704be22bf7db760a1494a49ab2cc5" - integrity sha512-+8VxcR21HhTy8nOt6jf20w0c9CADrw1O8d+VZ/YzzCt4bJ3uBjw+D1q2osAB8RnpwwaeYBxy0HyKQxD5JBMuuQ== - -dedent@0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" - integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== - -dedent@^1.0.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.5.1.tgz#4f3fc94c8b711e9bb2800d185cd6ad20f2a90aff" - integrity sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg== - -deep-is@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" - integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== - -deepmerge@^4.2.2: - version "4.3.1" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" - integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== - -defaults@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.4.tgz#b0b02062c1e2aa62ff5d9528f0f98baa90978d7a" - integrity sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A== - dependencies: - clone "^1.0.2" - -define-data-property@^1.0.1, define-data-property@^1.1.2, define-data-property@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" - integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== - dependencies: - es-define-property "^1.0.0" - es-errors "^1.3.0" - gopd "^1.0.1" - -define-lazy-prop@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" - integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== - -define-properties@^1.1.3, define-properties@^1.2.0, define-properties@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" - integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== - dependencies: - define-data-property "^1.0.1" - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== - -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== - -depd@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" - integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== - -deprecation@^2.0.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" - integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== - -detect-file@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" - integrity sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q== - -detect-indent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" - integrity sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g== - -detect-newline@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" - integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== - -diff-sequences@^29.6.3: - version "29.6.3" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" - integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== - -diff@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== - -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" - integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== - dependencies: - esutils "^2.0.2" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -dot-prop@^5.1.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" - integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q== - dependencies: - is-obj "^2.0.0" - -dotenv-expand@~10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-10.0.0.tgz#12605d00fb0af6d0a592e6558585784032e4ef37" - integrity sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A== - -dotenv@~16.3.1: - version "16.3.2" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.2.tgz#3cb611ce5a63002dbabf7c281bc331f69d28f03f" - integrity sha512-HTlk5nmhkm8F6JcdXvHIzaorzCoziNQT9mGxLPVXW8wJF1TiGSL60ZGB4gHWabHOaMmWmhvk2/lPHfnBiT78AQ== - -draggabilly@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/draggabilly/-/draggabilly-3.0.0.tgz#48defe10a67f346a0338caaa40c0765c4d3912d6" - integrity sha512-aEs+B6prbMZQMxc9lgTpCBfyCUhRur/VFucHhIOvlvvdARTj7TcDmX/cdOUtqbjJJUh7+agyJXR5Z6IFe1MxwQ== - dependencies: - get-size "^3.0.0" - unidragger "^3.0.0" - -duplexer@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" - integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== - -eastasianwidth@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" - integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== - -ejs@^3.1.7: - version "3.1.9" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.9.tgz#03c9e8777fe12686a9effcef22303ca3d8eeb361" - integrity sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ== - dependencies: - jake "^10.8.5" - -electron-to-chromium@^1.4.668: - version "1.4.695" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.695.tgz#1753f4017e8d7e72a1ce5058c0fc66c8b67bab8e" - integrity sha512-eMijZmeqPtm774pCZIOrfUHMs/7ls++W1sLhxwqgu8KQ8E2WmMtzwyqOMt0XXUJ3HTIPfuwlfwF+I5cwnfItBA== - -elliptic@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" - integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== - dependencies: - bn.js "^4.11.9" - brorand "^1.1.0" - hash.js "^1.0.0" - hmac-drbg "^1.0.1" - inherits "^2.0.4" - minimalistic-assert "^1.0.1" - minimalistic-crypto-utils "^1.0.1" - -elliptic@^6.5.2, elliptic@^6.5.4: - version "6.5.5" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.5.tgz#c715e09f78b6923977610d4c2346d6ce22e6dded" - integrity sha512-7EjbcmUm17NQFu4Pmgmq2olYMj8nwMnpcddByChSUjArp8F5DQWcIcpriwO4ZToLNAJig0yiyjswfyGNje/ixw== - dependencies: - bn.js "^4.11.9" - brorand "^1.1.0" - hash.js "^1.0.0" - hmac-drbg "^1.0.1" - inherits "^2.0.4" - minimalistic-assert "^1.0.1" - minimalistic-crypto-utils "^1.0.1" - -email-addresses@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/email-addresses/-/email-addresses-5.0.0.tgz#7ae9e7f58eef7d5e3e2c2c2d3ea49b78dc854fa6" - integrity sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw== - -emittery@0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.10.0.tgz#bb373c660a9d421bb44706ec4967ed50c02a8026" - integrity sha512-AGvFfs+d0JKCJQ4o01ASQLGPmSCxgfU9RFXvzPvZdjKK8oscynksuJhWrSTSw7j7Ep/sZct5b5ZhYCi8S/t0HQ== - -emittery@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" - integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -emoji-regex@^9.2.2: - version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - -enabled@2.0.x: - version "2.0.0" - resolved "https://registry.yarnpkg.com/enabled/-/enabled-2.0.0.tgz#f9dd92ec2d6f4bbc0d5d1e64e21d61cd4665e7c2" - integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ== - -encoding@^0.1.12, encoding@^0.1.13: - version "0.1.13" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" - integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== - dependencies: - iconv-lite "^0.6.2" - -end-of-stream@^1.4.1: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - -enquirer@^2.3.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.4.1.tgz#93334b3fbd74fc7097b224ab4a8fb7e40bf4ae56" - integrity sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ== - dependencies: - ansi-colors "^4.1.1" - strip-ansi "^6.0.1" - -enquirer@~2.3.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== - dependencies: - ansi-colors "^4.1.1" - -env-paths@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" - integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== - -envinfo@7.8.1: - version "7.8.1" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" - integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== - -err-code@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" - integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -es-abstract@^1.22.1, es-abstract@^1.22.3: - version "1.22.5" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.5.tgz#1417df4e97cc55f09bf7e58d1e614bc61cb8df46" - integrity sha512-oW69R+4q2wG+Hc3KZePPZxOiisRIqfKBVo/HLx94QcJeWGU/8sZhCvc829rd1kS366vlJbzBfXf9yWwf0+Ko7w== - dependencies: - array-buffer-byte-length "^1.0.1" - arraybuffer.prototype.slice "^1.0.3" - available-typed-arrays "^1.0.7" - call-bind "^1.0.7" - es-define-property "^1.0.0" - es-errors "^1.3.0" - es-set-tostringtag "^2.0.3" - es-to-primitive "^1.2.1" - function.prototype.name "^1.1.6" - get-intrinsic "^1.2.4" - get-symbol-description "^1.0.2" - globalthis "^1.0.3" - gopd "^1.0.1" - has-property-descriptors "^1.0.2" - has-proto "^1.0.3" - has-symbols "^1.0.3" - hasown "^2.0.1" - internal-slot "^1.0.7" - is-array-buffer "^3.0.4" - is-callable "^1.2.7" - is-negative-zero "^2.0.3" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.3" - is-string "^1.0.7" - is-typed-array "^1.1.13" - is-weakref "^1.0.2" - object-inspect "^1.13.1" - object-keys "^1.1.1" - object.assign "^4.1.5" - regexp.prototype.flags "^1.5.2" - safe-array-concat "^1.1.0" - safe-regex-test "^1.0.3" - string.prototype.trim "^1.2.8" - string.prototype.trimend "^1.0.7" - string.prototype.trimstart "^1.0.7" - typed-array-buffer "^1.0.2" - typed-array-byte-length "^1.0.1" - typed-array-byte-offset "^1.0.2" - typed-array-length "^1.0.5" - unbox-primitive "^1.0.2" - which-typed-array "^1.1.14" - -es-array-method-boxes-properly@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" - integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== - -es-define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" - integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== - dependencies: - get-intrinsic "^1.2.4" - -es-errors@^1.0.0, es-errors@^1.2.1, es-errors@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" - integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== - -es-set-tostringtag@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz#8bb60f0a440c2e4281962428438d58545af39777" - integrity sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ== - dependencies: - get-intrinsic "^1.2.4" - has-tostringtag "^1.0.2" - hasown "^2.0.1" - -es-shim-unscopables@^1.0.0, es-shim-unscopables@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz#1f6942e71ecc7835ed1c8a83006d8771a63a3763" - integrity sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw== - dependencies: - hasown "^2.0.0" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -esbuild-plugin-tsc@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/esbuild-plugin-tsc/-/esbuild-plugin-tsc-0.4.0.tgz#d7d516fda0e0b05c8e0b442152deebdee01ddc61" - integrity sha512-q9gWIovt1nkwchMLc2zhyksaiHOv3kDK4b0AUol8lkMCRhJ1zavgfb2fad6BKp7FT9rh/OHmEBXVjczLoi/0yw== - dependencies: - strip-comments "^2.0.1" - -esbuild@^0.19.11: - version "0.19.12" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.19.12.tgz#dc82ee5dc79e82f5a5c3b4323a2a641827db3e04" - integrity sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg== - optionalDependencies: - "@esbuild/aix-ppc64" "0.19.12" - "@esbuild/android-arm" "0.19.12" - "@esbuild/android-arm64" "0.19.12" - "@esbuild/android-x64" "0.19.12" - "@esbuild/darwin-arm64" "0.19.12" - "@esbuild/darwin-x64" "0.19.12" - "@esbuild/freebsd-arm64" "0.19.12" - "@esbuild/freebsd-x64" "0.19.12" - "@esbuild/linux-arm" "0.19.12" - "@esbuild/linux-arm64" "0.19.12" - "@esbuild/linux-ia32" "0.19.12" - "@esbuild/linux-loong64" "0.19.12" - "@esbuild/linux-mips64el" "0.19.12" - "@esbuild/linux-ppc64" "0.19.12" - "@esbuild/linux-riscv64" "0.19.12" - "@esbuild/linux-s390x" "0.19.12" - "@esbuild/linux-x64" "0.19.12" - "@esbuild/netbsd-x64" "0.19.12" - "@esbuild/openbsd-x64" "0.19.12" - "@esbuild/sunos-x64" "0.19.12" - "@esbuild/win32-arm64" "0.19.12" - "@esbuild/win32-ia32" "0.19.12" - "@esbuild/win32-x64" "0.19.12" - -escalade@^3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" - integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== - -escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== - -escape-string-regexp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" - integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== - -eslint-config-airbnb-base@15.0.0, eslint-config-airbnb-base@^15.0.0: - version "15.0.0" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz#6b09add90ac79c2f8d723a2580e07f3925afd236" - integrity sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig== - dependencies: - confusing-browser-globals "^1.0.10" - object.assign "^4.1.2" - object.entries "^1.1.5" - semver "^6.3.0" - -eslint-config-airbnb-typescript@17.1.0: - version "17.1.0" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-17.1.0.tgz#fda960eee4a510f092a9a1c139035ac588937ddc" - integrity sha512-GPxI5URre6dDpJ0CtcthSZVBAfI+Uw7un5OYNVxP2EYi3H81Jw701yFP7AU+/vCE7xBtFmjge7kfhhk4+RAiig== - dependencies: - eslint-config-airbnb-base "^15.0.0" - -eslint-config-prettier@^9.0.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz#31af3d94578645966c082fcb71a5846d3c94867f" - integrity sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw== - -eslint-import-resolver-node@^0.3.9: - version "0.3.9" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac" - integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g== - dependencies: - debug "^3.2.7" - is-core-module "^2.13.0" - resolve "^1.22.4" - -eslint-module-utils@^2.8.0: - version "2.8.1" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz#52f2404300c3bd33deece9d7372fb337cc1d7c34" - integrity sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q== - dependencies: - debug "^3.2.7" - -eslint-plugin-import@^2.28.1: - version "2.29.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz#d45b37b5ef5901d639c15270d74d46d161150643" - integrity sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw== - dependencies: - array-includes "^3.1.7" - array.prototype.findlastindex "^1.2.3" - array.prototype.flat "^1.3.2" - array.prototype.flatmap "^1.3.2" - debug "^3.2.7" - doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.9" - eslint-module-utils "^2.8.0" - hasown "^2.0.0" - is-core-module "^2.13.1" - is-glob "^4.0.3" - minimatch "^3.1.2" - object.fromentries "^2.0.7" - object.groupby "^1.0.1" - object.values "^1.1.7" - semver "^6.3.1" - tsconfig-paths "^3.15.0" - -eslint-plugin-prettier@^5.0.0: - version "5.1.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz#17cfade9e732cef32b5f5be53bd4e07afd8e67e1" - integrity sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw== - dependencies: - prettier-linter-helpers "^1.0.0" - synckit "^0.8.6" - -eslint-plugin-security@^1.7.1: - version "1.7.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-security/-/eslint-plugin-security-1.7.1.tgz#0e9c4a471f6e4d3ca16413c7a4a51f3966ba16e4" - integrity sha512-sMStceig8AFglhhT2LqlU5r+/fn9OwsA72O5bBuQVTssPCdQAOQzL+oMn/ZcpeUY6KcNfLJArgcrsSULNjYYdQ== - dependencies: - safe-regex "^2.1.1" - -eslint-scope@^7.2.2: - version "7.2.2" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" - integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== - dependencies: - esrecurse "^4.3.0" - estraverse "^5.2.0" - -eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: - version "3.4.3" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" - integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== - -eslint@^8.48.0: - version "8.57.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.0.tgz#c786a6fd0e0b68941aaf624596fb987089195668" - integrity sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.6.1" - "@eslint/eslintrc" "^2.1.4" - "@eslint/js" "8.57.0" - "@humanwhocodes/config-array" "^0.11.14" - "@humanwhocodes/module-importer" "^1.0.1" - "@nodelib/fs.walk" "^1.2.8" - "@ungap/structured-clone" "^1.2.0" - ajv "^6.12.4" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" - doctrine "^3.0.0" - escape-string-regexp "^4.0.0" - eslint-scope "^7.2.2" - eslint-visitor-keys "^3.4.3" - espree "^9.6.1" - esquery "^1.4.2" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - find-up "^5.0.0" - glob-parent "^6.0.2" - globals "^13.19.0" - graphemer "^1.4.0" - ignore "^5.2.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - is-path-inside "^3.0.3" - js-yaml "^4.1.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.1.2" - natural-compare "^1.4.0" - optionator "^0.9.3" - strip-ansi "^6.0.1" - text-table "^0.2.0" - -espree@^9.6.0, espree@^9.6.1: - version "9.6.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" - integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== - dependencies: - acorn "^8.9.0" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.4.1" - -esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -esquery@^1.4.2: - version "1.5.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" - integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^5.1.0, estraverse@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -ethereum-bloom-filters@^1.0.6: - version "1.0.10" - resolved "https://registry.yarnpkg.com/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz#3ca07f4aed698e75bd134584850260246a5fed8a" - integrity sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA== - dependencies: - js-sha3 "^0.8.0" - -ethereum-cryptography@0.1.3, ethereum-cryptography@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz#8d6143cfc3d74bf79bbd8edecdf29e4ae20dd191" - integrity sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ== - dependencies: - "@types/pbkdf2" "^3.0.0" - "@types/secp256k1" "^4.0.1" - blakejs "^1.1.0" - browserify-aes "^1.2.0" - bs58check "^2.1.2" - create-hash "^1.2.0" - create-hmac "^1.1.7" - hash.js "^1.1.7" - keccak "^3.0.0" - pbkdf2 "^3.0.17" - randombytes "^2.1.0" - safe-buffer "^5.1.2" - scrypt-js "^3.0.0" - secp256k1 "^4.0.1" - setimmediate "^1.0.5" - -ethereum-cryptography@^1.0.3: - version "1.2.0" - resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz#5ccfa183e85fdaf9f9b299a79430c044268c9b3a" - integrity sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw== - dependencies: - "@noble/hashes" "1.2.0" - "@noble/secp256k1" "1.7.1" - "@scure/bip32" "1.1.5" - "@scure/bip39" "1.1.1" - -ethereum-cryptography@^2.0.0, ethereum-cryptography@^2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-2.1.3.tgz#1352270ed3b339fe25af5ceeadcf1b9c8e30768a" - integrity sha512-BlwbIL7/P45W8FGW2r7LGuvoEZ+7PWsniMvQ4p5s2xCyw9tmaDlpfsN9HjAucbF+t/qpVHwZUisgfK24TCW8aA== - dependencies: - "@noble/curves" "1.3.0" - "@noble/hashes" "1.3.3" - "@scure/bip32" "1.3.3" - "@scure/bip39" "1.2.2" - -ethereumjs-abi@^0.6.8: - version "0.6.8" - resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz#71bc152db099f70e62f108b7cdfca1b362c6fcae" - integrity sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA== - dependencies: - bn.js "^4.11.8" - ethereumjs-util "^6.0.0" - -ethereumjs-util@^6.0.0, ethereumjs-util@^6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz#fcb4e4dd5ceacb9d2305426ab1a5cd93e3163b69" - integrity sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw== - dependencies: - "@types/bn.js" "^4.11.3" - bn.js "^4.11.0" - create-hash "^1.1.2" - elliptic "^6.5.2" - ethereum-cryptography "^0.1.3" - ethjs-util "0.1.6" - rlp "^2.2.3" - -ethjs-unit@0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699" - integrity sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw== - dependencies: - bn.js "4.11.6" - number-to-bn "1.7.0" - -ethjs-util@0.1.6, ethjs-util@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.6.tgz#f308b62f185f9fe6237132fb2a9818866a5cd536" - integrity sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w== - dependencies: - is-hex-prefixed "1.0.0" - strip-hex-prefix "1.0.0" - -ev-emitter@^2.0.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ev-emitter/-/ev-emitter-2.1.2.tgz#91737a2deae9fa95453e7e86cfae976f8c3ced38" - integrity sha512-jQ5Ql18hdCQ4qS+RCrbLfz1n+Pags27q5TwMKvZyhp5hh2UULUYZUy1keqj6k6SYsdqIYjnmz7xyyEY0V67B8Q== - -eventemitter3@^4.0.4: - version "4.0.7" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" - integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== - -eventemitter3@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" - integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== - -events@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" - integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== - -evp_bytestokey@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" - integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== - dependencies: - md5.js "^1.3.4" - safe-buffer "^5.1.1" - -execa@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.0.0.tgz#4029b0007998a841fbd1032e5f4de86a3c1e3376" - integrity sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - -execa@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - -exit@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" - integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== - -expand-tilde@^2.0.0, expand-tilde@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" - integrity sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw== - dependencies: - homedir-polyfill "^1.0.1" - -expect@^29.0.0, expect@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc" - integrity sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw== - dependencies: - "@jest/expect-utils" "^29.7.0" - jest-get-type "^29.6.3" - jest-matcher-utils "^29.7.0" - jest-message-util "^29.7.0" - jest-util "^29.7.0" - -exponential-backoff@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6" - integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw== - -external-editor@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" - integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== - dependencies: - chardet "^0.7.0" - iconv-lite "^0.4.24" - tmp "^0.0.33" - -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-diff@^1.1.2: - version "1.3.0" - resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" - integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== - -fast-glob@^3.2.9: - version "3.3.2" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" - integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== - -fastq@^1.6.0: - version "1.17.1" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" - integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== - dependencies: - reusify "^1.0.4" - -fb-watchman@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" - integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== - dependencies: - bser "2.1.1" - -fecha@^4.2.0: - version "4.2.3" - resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.3.tgz#4d9ccdbc61e8629b259fdca67e65891448d569fd" - integrity sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw== - -figures@3.2.0, figures@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" - integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== - dependencies: - escape-string-regexp "^1.0.5" - -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== - dependencies: - flat-cache "^3.0.4" - -filelist@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" - integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== - dependencies: - minimatch "^5.0.1" - -filename-reserved-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz#abf73dfab735d045440abfea2d91f389ebbfa229" - integrity sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ== - -filenamify@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-4.3.0.tgz#62391cb58f02b09971c9d4f9d63b3cf9aba03106" - integrity sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg== - dependencies: - filename-reserved-regex "^2.0.0" - strip-outer "^1.0.1" - trim-repeated "^1.0.0" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -filter-obj@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-5.1.0.tgz#5bd89676000a713d7db2e197f660274428e524ed" - integrity sha512-qWeTREPoT7I0bifpPUXtxkZJ1XJzxWtfoWWkdVGqa+eCr3SHW/Ocp89o8vLvbUuQnadybJpjOKu4V+RwO6sGng== - -find-cache-dir@^3.3.1: - version "3.3.2" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" - integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== - dependencies: - commondir "^1.0.1" - make-dir "^3.0.2" - pkg-dir "^4.1.0" - -find-node-modules@2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/find-node-modules/-/find-node-modules-2.1.3.tgz#3c976cff2ca29ee94b4f9eafc613987fc4c0ee44" - integrity sha512-UC2I2+nx1ZuOBclWVNdcnbDR5dlrOdVb7xNjmT/lHE+LsgztWks3dG7boJ37yTS/venXw84B/mAW9uHVoC5QRg== - dependencies: - findup-sync "^4.0.0" - merge "^2.1.1" - -find-up@5.0.0, find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -find-up@^2.0.0, find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ== - dependencies: - locate-path "^2.0.0" - -find-up@^4.0.0, find-up@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -findup-sync@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-4.0.0.tgz#956c9cdde804052b881b428512905c4a5f2cdef0" - integrity sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ== - dependencies: - detect-file "^1.0.0" - is-glob "^4.0.0" - micromatch "^4.0.2" - resolve-dir "^1.0.1" - -flat-cache@^3.0.4: - version "3.2.0" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" - integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== - dependencies: - flatted "^3.2.9" - keyv "^4.5.3" - rimraf "^3.0.2" - -flat@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" - integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== - -flatted@^3.2.9: - version "3.3.1" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a" - integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== - -fn.name@1.x.x: - version "1.1.0" - resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc" - integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== - -follow-redirects@^1.12.1, follow-redirects@^1.15.4: - version "1.15.5" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.5.tgz#54d4d6d062c0fa7d9d17feb008461550e3ba8020" - integrity sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw== - -for-each@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" - integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== - dependencies: - is-callable "^1.1.3" - -foreground-child@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" - integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== - dependencies: - cross-spawn "^7.0.0" - signal-exit "^4.0.1" - -form-data@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" - integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - -fp-ts@1.19.3: - version "1.19.3" - resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.3.tgz#261a60d1088fbff01f91256f91d21d0caaaaa96f" - integrity sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg== - -fp-ts@^1.0.0: - version "1.19.5" - resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.5.tgz#3da865e585dfa1fdfd51785417357ac50afc520a" - integrity sha512-wDNqTimnzs8QqpldiId9OavWK2NptormjXnRJTQecNjzwfyp6P/8s/zG8e4h3ja3oqkKaY72UlTjQYt/1yXf9A== - -fs-constants@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" - integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== - -fs-extra@^0.30.0: - version "0.30.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" - integrity sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^2.1.0" - klaw "^1.0.0" - path-is-absolute "^1.0.0" - rimraf "^2.2.8" - -fs-extra@^11.1.0, fs-extra@^11.1.1: - version "11.2.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b" - integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs-extra@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" - integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-minipass@^2.0.0, fs-minipass@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" - integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== - dependencies: - minipass "^3.0.0" - -fs-minipass@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-3.0.3.tgz#79a85981c4dc120065e96f62086bf6f9dc26cc54" - integrity sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw== - dependencies: - minipass "^7.0.3" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - -fsevents@^2.3.2, fsevents@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" - integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== - -function-bind@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" - integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== - -function.prototype.name@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz#cdf315b7d90ee77a4c6ee216c3c3362da07533fd" - integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - functions-have-names "^1.2.3" - -functions-have-names@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" - integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== - -ganache@^7.9.2: - version "7.9.2" - resolved "https://registry.yarnpkg.com/ganache/-/ganache-7.9.2.tgz#77f506ad2735dd9109696ffa1834a9dd2f806449" - integrity sha512-7gsVVDpO9AhrFyDMWWl7SpMsPpqGcnAzjxz3k32LheIPNd64p2XsY9GYRdhWmKuryb60W1iaWPZWDkFKlbRWHA== - dependencies: - "@trufflesuite/bigint-buffer" "1.1.10" - "@trufflesuite/uws-js-unofficial" "20.30.0-unofficial.0" - "@types/bn.js" "^5.1.0" - "@types/lru-cache" "5.1.1" - "@types/seedrandom" "3.0.1" - abstract-level "1.0.3" - abstract-leveldown "7.2.0" - async-eventemitter "0.2.4" - emittery "0.10.0" - keccak "3.0.2" - leveldown "6.1.0" - secp256k1 "4.0.3" - optionalDependencies: - bufferutil "4.0.5" - utf-8-validate "5.0.7" - -gauge@^4.0.3: - version "4.0.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-4.0.4.tgz#52ff0652f2bbf607a989793d53b751bef2328dce" - integrity sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg== - dependencies: - aproba "^1.0.3 || ^2.0.0" - color-support "^1.1.3" - console-control-strings "^1.1.0" - has-unicode "^2.0.1" - signal-exit "^3.0.7" - string-width "^4.2.3" - strip-ansi "^6.0.1" - wide-align "^1.1.5" - -gensync@^1.0.0-beta.2: - version "1.0.0-beta.2" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" - integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== - -get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2, get-intrinsic@^1.2.3, get-intrinsic@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" - integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== - dependencies: - es-errors "^1.3.0" - function-bind "^1.1.2" - has-proto "^1.0.1" - has-symbols "^1.0.3" - hasown "^2.0.0" - -get-package-type@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" - integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== - -get-pkg-repo@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz#75973e1c8050c73f48190c52047c4cee3acbf385" - integrity sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA== - dependencies: - "@hutson/parse-repository-url" "^3.0.0" - hosted-git-info "^4.0.0" - through2 "^2.0.0" - yargs "^16.2.0" - -get-port@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193" - integrity sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ== - -get-size@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/get-size/-/get-size-3.0.0.tgz#00e39a8042a3de237b2fcf288eaf55d3f472417c" - integrity sha512-Y8aiXLq4leR7807UY0yuKEwif5s3kbVp1nTv+i4jBeoUzByTLKkLWu/HorS6/pB+7gsB0o7OTogC8AoOOeT0Hw== - -get-stream@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.0.tgz#3e0012cb6827319da2706e601a1583e8629a6718" - integrity sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg== - -get-stream@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - -get-symbol-description@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.2.tgz#533744d5aa20aca4e079c8e5daf7fd44202821f5" - integrity sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg== - dependencies: - call-bind "^1.0.5" - es-errors "^1.3.0" - get-intrinsic "^1.2.4" - -gh-pages@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/gh-pages/-/gh-pages-6.1.1.tgz#e80af927a081cb480657fde5a0b87ea2e77d6c74" - integrity sha512-upnohfjBwN5hBP9w2dPE7HO5JJTHzSGMV1JrLrHvNuqmjoYHg6TBrCcnEoorjG/e0ejbuvnwyKMdTyM40PEByw== - dependencies: - async "^3.2.4" - commander "^11.0.0" - email-addresses "^5.0.0" - filenamify "^4.3.0" - find-cache-dir "^3.3.1" - fs-extra "^11.1.1" - globby "^6.1.0" - -git-raw-commits@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-3.0.0.tgz#5432f053a9744f67e8db03dbc48add81252cfdeb" - integrity sha512-b5OHmZ3vAgGrDn/X0kS+9qCfNKWe4K/jFnhwzVWWg0/k5eLa3060tZShrRg8Dja5kPc+YjS0Gc6y7cRr44Lpjw== - dependencies: - dargs "^7.0.0" - meow "^8.1.2" - split2 "^3.2.2" - -git-remote-origin-url@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz#5282659dae2107145a11126112ad3216ec5fa65f" - integrity sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw== - dependencies: - gitconfiglocal "^1.0.0" - pify "^2.3.0" - -git-semver-tags@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/git-semver-tags/-/git-semver-tags-5.0.1.tgz#db748aa0e43d313bf38dcd68624d8443234e1c15" - integrity sha512-hIvOeZwRbQ+7YEUmCkHqo8FOLQZCEn18yevLHADlFPZY02KJGsu5FZt9YW/lybfK2uhWFI7Qg/07LekJiTv7iA== - dependencies: - meow "^8.1.2" - semver "^7.0.0" - -git-up@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/git-up/-/git-up-7.0.0.tgz#bace30786e36f56ea341b6f69adfd83286337467" - integrity sha512-ONdIrbBCFusq1Oy0sC71F5azx8bVkvtZtMJAsv+a6lz5YAmbNnLD6HAB4gptHZVLPR8S2/kVN6Gab7lryq5+lQ== - dependencies: - is-ssh "^1.4.0" - parse-url "^8.1.0" - -git-url-parse@13.1.0: - version "13.1.0" - resolved "https://registry.yarnpkg.com/git-url-parse/-/git-url-parse-13.1.0.tgz#07e136b5baa08d59fabdf0e33170de425adf07b4" - integrity sha512-5FvPJP/70WkIprlUZ33bm4UAaFdjcLkJLpWft1BeZKqwR0uhhNGoKwlUaPtVb4LxCSQ++erHapRak9kWGj+FCA== - dependencies: - git-up "^7.0.0" - -gitconfiglocal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz#41d045f3851a5ea88f03f24ca1c6178114464b9b" - integrity sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ== - dependencies: - ini "^1.3.2" - -glob-parent@5.1.2, glob-parent@^5.1.2, glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob-parent@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" - integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== - dependencies: - is-glob "^4.0.3" - -glob@7.1.4: - version "7.1.4" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" - integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@8.1.0, glob@^8.0.1: - version "8.1.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" - integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^5.0.1" - once "^1.3.0" - -glob@^10.2.2, glob@^10.3.7: - version "10.3.10" - resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b" - integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== - dependencies: - foreground-child "^3.1.0" - jackspeak "^2.3.5" - minimatch "^9.0.1" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" - path-scurry "^1.10.1" - -glob@^7.0.3, glob@^7.1.3, glob@^7.1.4: - version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^9.2.0: - version "9.3.5" - resolved "https://registry.yarnpkg.com/glob/-/glob-9.3.5.tgz#ca2ed8ca452781a3009685607fdf025a899dfe21" - integrity sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q== - dependencies: - fs.realpath "^1.0.0" - minimatch "^8.0.2" - minipass "^4.2.4" - path-scurry "^1.6.1" - -global-modules@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" - integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== - dependencies: - global-prefix "^1.0.1" - is-windows "^1.0.1" - resolve-dir "^1.0.0" - -global-prefix@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" - integrity sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg== - dependencies: - expand-tilde "^2.0.2" - homedir-polyfill "^1.0.1" - ini "^1.3.4" - is-windows "^1.0.1" - which "^1.2.14" - -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -globals@^13.19.0: - version "13.24.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171" - integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ== - dependencies: - type-fest "^0.20.2" - -globalthis@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" - integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== - dependencies: - define-properties "^1.1.3" - -globby@11.1.0, globby@^11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" - integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.2.9" - ignore "^5.2.0" - merge2 "^1.4.1" - slash "^3.0.0" - -globby@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" - integrity sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw== - dependencies: - array-union "^1.0.1" - glob "^7.0.3" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -gopd@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" - integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== - dependencies: - get-intrinsic "^1.1.3" - -graceful-fs@4.2.11, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.6, graceful-fs@^4.2.9: - version "4.2.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" - integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== - -graphemer@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" - integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== - -handlebars@^4.7.7: - version "4.7.8" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.8.tgz#41c42c18b1be2365439188c77c6afae71c0cd9e9" - integrity sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ== - dependencies: - minimist "^1.2.5" - neo-async "^2.6.2" - source-map "^0.6.1" - wordwrap "^1.0.0" - optionalDependencies: - uglify-js "^3.1.4" - -hard-rejection@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883" - integrity sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA== - -hardhat@^2.17.3: - version "2.21.0" - resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.21.0.tgz#2e23126310a6c77cd7e149e6af1dd67626b7a74f" - integrity sha512-8DlJAVJDEVHaV1sh9FLuKLLgCFv9EAJ+M+8IbjSIPgoeNo3ss5L1HgGBMfnI88c7OzMEZkdcuyGoobFeK3Orqw== - dependencies: - "@ethersproject/abi" "^5.1.2" - "@metamask/eth-sig-util" "^4.0.0" - "@nomicfoundation/edr" "^0.2.0" - "@nomicfoundation/ethereumjs-common" "4.0.4" - "@nomicfoundation/ethereumjs-tx" "5.0.4" - "@nomicfoundation/ethereumjs-util" "9.0.4" - "@nomicfoundation/solidity-analyzer" "^0.1.0" - "@sentry/node" "^5.18.1" - "@types/bn.js" "^5.1.0" - "@types/lru-cache" "^5.1.0" - adm-zip "^0.4.16" - aggregate-error "^3.0.0" - ansi-escapes "^4.3.0" - boxen "^5.1.2" - chalk "^2.4.2" - chokidar "^3.4.0" - ci-info "^2.0.0" - debug "^4.1.1" - enquirer "^2.3.0" - env-paths "^2.2.0" - ethereum-cryptography "^1.0.3" - ethereumjs-abi "^0.6.8" - find-up "^2.1.0" - fp-ts "1.19.3" - fs-extra "^7.0.1" - glob "7.2.0" - immutable "^4.0.0-rc.12" - io-ts "1.10.4" - keccak "^3.0.2" - lodash "^4.17.11" - mnemonist "^0.38.0" - mocha "^10.0.0" - p-map "^4.0.0" - raw-body "^2.4.1" - resolve "1.17.0" - semver "^6.3.0" - solc "0.7.3" - source-map-support "^0.5.13" - stacktrace-parser "^0.1.10" - tsort "0.0.1" - undici "^5.14.0" - uuid "^8.3.2" - ws "^7.4.6" - -has-bigints@^1.0.1, has-bigints@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" - integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.1, has-property-descriptors@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" - integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== - dependencies: - es-define-property "^1.0.0" - -has-proto@^1.0.1, has-proto@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" - integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== - -has-symbols@^1.0.2, has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - -has-tostringtag@^1.0.0, has-tostringtag@^1.0.1, has-tostringtag@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" - integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== - dependencies: - has-symbols "^1.0.3" - -has-unicode@2.0.1, has-unicode@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== - -hash-base@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" - integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== - dependencies: - inherits "^2.0.4" - readable-stream "^3.6.0" - safe-buffer "^5.2.0" - -hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" - integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" - -hasown@^2.0.0, hasown@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.1.tgz#26f48f039de2c0f8d3356c223fb8d50253519faa" - integrity sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA== - dependencies: - function-bind "^1.1.2" - -he@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - -highlight.js@^10.7.1: - version "10.7.3" - resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531" - integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A== - -hmac-drbg@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== - dependencies: - hash.js "^1.0.3" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.1" - -homedir-polyfill@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" - integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== - dependencies: - parse-passwd "^1.0.0" - -hosted-git-info@^2.1.4: - version "2.8.9" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" - integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== - -hosted-git-info@^3.0.6: - version "3.0.8" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-3.0.8.tgz#6e35d4cc87af2c5f816e4cb9ce350ba87a3f370d" - integrity sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw== - dependencies: - lru-cache "^6.0.0" - -hosted-git-info@^4.0.0, hosted-git-info@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz#827b82867e9ff1c8d0c4d9d53880397d2c86d224" - integrity sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA== - dependencies: - lru-cache "^6.0.0" - -hosted-git-info@^6.0.0: - version "6.1.1" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-6.1.1.tgz#629442c7889a69c05de604d52996b74fe6f26d58" - integrity sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w== - dependencies: - lru-cache "^7.5.1" - -html-escaper@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" - integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== - -http-cache-semantics@^4.1.0, http-cache-semantics@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" - integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== - -http-errors@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" - integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== - dependencies: - depd "2.0.0" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses "2.0.1" - toidentifier "1.0.1" - -http-proxy-agent@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" - integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== - dependencies: - "@tootallnate/once" "1" - agent-base "6" - debug "4" - -http-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" - integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== - dependencies: - "@tootallnate/once" "2" - agent-base "6" - debug "4" - -https-proxy-agent@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" - integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== - dependencies: - agent-base "6" - debug "4" - -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== - -humanize-ms@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" - integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== - dependencies: - ms "^2.0.0" - -iconv-lite@0.4.24, iconv-lite@^0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -iconv-lite@^0.6.2: - version "0.6.3" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" - integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - -ieee754@^1.1.13, ieee754@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - -ignore-walk@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-5.0.1.tgz#5f199e23e1288f518d90358d461387788a154776" - integrity sha512-yemi4pMf51WKT7khInJqAvsIGzoqYXblnsz0ql8tM+yi1EKYTY1evX4NAbJrLL/Aanr2HyZeluqU+Oi7MGHokw== - dependencies: - minimatch "^5.0.1" - -ignore-walk@^6.0.0: - version "6.0.4" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-6.0.4.tgz#89950be94b4f522225eb63a13c56badb639190e9" - integrity sha512-t7sv42WkwFkyKbivUCglsQW5YWMskWtbEf4MNKX5u/CCWHKSPzN4FtBQGsQZgCLbxOzpVlcbWVK5KB3auIOjSw== - dependencies: - minimatch "^9.0.0" - -ignore@^5.0.4, ignore@^5.2.0, ignore@^5.2.4: - version "5.3.1" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" - integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== - -immutable@^4.0.0-rc.12: - version "4.3.5" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.5.tgz#f8b436e66d59f99760dc577f5c99a4fd2a5cc5a0" - integrity sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw== - -import-fresh@^3.2.1, import-fresh@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -import-local@3.1.0, import-local@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" - integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== - dependencies: - pkg-dir "^4.2.0" - resolve-cwd "^3.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== - -indent-string@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" - integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== - -infer-owner@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" - integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -ini@^1.3.2, ini@^1.3.4, ini@^1.3.8: - version "1.3.8" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" - integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== - -init-package-json@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/init-package-json/-/init-package-json-5.0.0.tgz#030cf0ea9c84cfc1b0dc2e898b45d171393e4b40" - integrity sha512-kBhlSheBfYmq3e0L1ii+VKe3zBTLL5lDCDWR+f9dLmEGSB3MqLlMlsolubSsyI88Bg6EA+BIMlomAnQ1SwgQBw== - dependencies: - npm-package-arg "^10.0.0" - promzard "^1.0.0" - read "^2.0.0" - read-package-json "^6.0.0" - semver "^7.3.5" - validate-npm-package-license "^3.0.4" - validate-npm-package-name "^5.0.0" - -inquirer@^8.2.4: - version "8.2.6" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.6.tgz#733b74888195d8d400a67ac332011b5fae5ea562" - integrity sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg== - dependencies: - ansi-escapes "^4.2.1" - chalk "^4.1.1" - cli-cursor "^3.1.0" - cli-width "^3.0.0" - external-editor "^3.0.3" - figures "^3.0.0" - lodash "^4.17.21" - mute-stream "0.0.8" - ora "^5.4.1" - run-async "^2.4.0" - rxjs "^7.5.5" - string-width "^4.1.0" - strip-ansi "^6.0.0" - through "^2.3.6" - wrap-ansi "^6.0.1" - -internal-slot@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.7.tgz#c06dcca3ed874249881007b0a5523b172a190802" - integrity sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g== - dependencies: - es-errors "^1.3.0" - hasown "^2.0.0" - side-channel "^1.0.4" - -io-ts@1.10.4: - version "1.10.4" - resolved "https://registry.yarnpkg.com/io-ts/-/io-ts-1.10.4.tgz#cd5401b138de88e4f920adbcb7026e2d1967e6e2" - integrity sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g== - dependencies: - fp-ts "^1.0.0" - -ip-address@^9.0.5: - version "9.0.5" - resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-9.0.5.tgz#117a960819b08780c3bd1f14ef3c1cc1d3f3ea5a" - integrity sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g== - dependencies: - jsbn "1.1.0" - sprintf-js "^1.1.3" - -is-array-buffer@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.4.tgz#7a1f92b3d61edd2bc65d24f130530ea93d7fae98" - integrity sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.1" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== - -is-arrayish@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" - integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== - -is-bigint@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" - integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== - dependencies: - has-bigints "^1.0.1" - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-boolean-object@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" - integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-buffer@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" - integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== - -is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" - integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== - -is-ci@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.1.tgz#db6ecbed1bd659c43dac0f45661e7674103d1867" - integrity sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ== - dependencies: - ci-info "^3.2.0" - -is-core-module@^2.13.0, is-core-module@^2.13.1, is-core-module@^2.5.0, is-core-module@^2.8.1: - version "2.13.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" - integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== - dependencies: - hasown "^2.0.0" - -is-date-object@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== - dependencies: - has-tostringtag "^1.0.0" - -is-docker@^2.0.0, is-docker@^2.1.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" - integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-generator-fn@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" - integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== - -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-hex-prefixed@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz#7d8d37e6ad77e5d127148913c573e082d777f554" - integrity sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA== - -is-interactive@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" - integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== - -is-lambda@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" - integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== - -is-negative-zero@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.3.tgz#ced903a027aca6381b777a5743069d7376a49747" - integrity sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw== - -is-number-object@^1.0.4: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" - integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== - dependencies: - has-tostringtag "^1.0.0" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-obj@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" - integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== - -is-path-inside@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" - integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== - -is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg== - -is-plain-obj@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== - -is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - -is-plain-object@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" - integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== - -is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-shared-array-buffer@^1.0.2, is-shared-array-buffer@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz#1237f1cba059cdb62431d378dcc37d9680181688" - integrity sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg== - dependencies: - call-bind "^1.0.7" - -is-ssh@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/is-ssh/-/is-ssh-1.4.0.tgz#4f8220601d2839d8fa624b3106f8e8884f01b8b2" - integrity sha512-x7+VxdxOdlV3CYpjvRLBv5Lo9OJerlYanjwFrPR9fuGPjCiNiCzFgAWpiLAohSbsnH4ZAys3SBh+hq5rJosxUQ== - dependencies: - protocols "^2.0.1" - -is-stream@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" - integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== - -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - -is-string@^1.0.5, is-string@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" - integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== - dependencies: - has-tostringtag "^1.0.0" - -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== - dependencies: - has-symbols "^1.0.2" - -is-text-path@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-1.0.1.tgz#4e1aa0fb51bfbcb3e92688001397202c1775b66e" - integrity sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w== - dependencies: - text-extensions "^1.0.0" - -is-typed-array@^1.1.13: - version "1.1.13" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.13.tgz#d6c5ca56df62334959322d7d7dd1cca50debe229" - integrity sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw== - dependencies: - which-typed-array "^1.1.14" - -is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== - -is-weakref@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" - integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== - dependencies: - call-bind "^1.0.2" - -is-windows@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== - -is-wsl@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" - integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== - dependencies: - is-docker "^2.0.0" - -isarray@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" - integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== - -isows@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/isows/-/isows-1.0.3.tgz#93c1cf0575daf56e7120bab5c8c448b0809d0d74" - integrity sha512-2cKei4vlmg2cxEjm3wVSqn8pcoRF/LX/wpifuuNquFO4SQmPwarClT+SUCA2lt+l581tTeZIPIZuIDo2jWN1fg== - -istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" - integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== - -istanbul-lib-instrument@^5.0.4: - version "5.2.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" - integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== - dependencies: - "@babel/core" "^7.12.3" - "@babel/parser" "^7.14.7" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-coverage "^3.2.0" - semver "^6.3.0" - -istanbul-lib-instrument@^6.0.0: - version "6.0.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.2.tgz#91655936cf7380e4e473383081e38478b69993b1" - integrity sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw== - dependencies: - "@babel/core" "^7.23.9" - "@babel/parser" "^7.23.9" - "@istanbuljs/schema" "^0.1.3" - istanbul-lib-coverage "^3.2.0" - semver "^7.5.4" - -istanbul-lib-report@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" - integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== - dependencies: - istanbul-lib-coverage "^3.0.0" - make-dir "^4.0.0" - supports-color "^7.1.0" - -istanbul-lib-source-maps@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" - integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== - dependencies: - debug "^4.1.1" - istanbul-lib-coverage "^3.0.0" - source-map "^0.6.1" - -istanbul-reports@^3.1.3: - version "3.1.7" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.7.tgz#daed12b9e1dca518e15c056e1e537e741280fa0b" - integrity sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g== - dependencies: - html-escaper "^2.0.0" - istanbul-lib-report "^3.0.0" - -jackspeak@^2.3.5: - version "2.3.6" - resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8" - integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== - dependencies: - "@isaacs/cliui" "^8.0.2" - optionalDependencies: - "@pkgjs/parseargs" "^0.11.0" - -jake@^10.8.5: - version "10.8.7" - resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.7.tgz#63a32821177940c33f356e0ba44ff9d34e1c7d8f" - integrity sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w== - dependencies: - async "^3.2.3" - chalk "^4.0.2" - filelist "^1.0.4" - minimatch "^3.1.2" - -jest-changed-files@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.7.0.tgz#1c06d07e77c78e1585d020424dedc10d6e17ac3a" - integrity sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w== - dependencies: - execa "^5.0.0" - jest-util "^29.7.0" - p-limit "^3.1.0" - -jest-circus@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.7.0.tgz#b6817a45fcc835d8b16d5962d0c026473ee3668a" - integrity sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw== - dependencies: - "@jest/environment" "^29.7.0" - "@jest/expect" "^29.7.0" - "@jest/test-result" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/node" "*" - chalk "^4.0.0" - co "^4.6.0" - dedent "^1.0.0" - is-generator-fn "^2.0.0" - jest-each "^29.7.0" - jest-matcher-utils "^29.7.0" - jest-message-util "^29.7.0" - jest-runtime "^29.7.0" - jest-snapshot "^29.7.0" - jest-util "^29.7.0" - p-limit "^3.1.0" - pretty-format "^29.7.0" - pure-rand "^6.0.0" - slash "^3.0.0" - stack-utils "^2.0.3" - -jest-cli@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.7.0.tgz#5592c940798e0cae677eec169264f2d839a37995" - integrity sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg== - dependencies: - "@jest/core" "^29.7.0" - "@jest/test-result" "^29.7.0" - "@jest/types" "^29.6.3" - chalk "^4.0.0" - create-jest "^29.7.0" - exit "^0.1.2" - import-local "^3.0.2" - jest-config "^29.7.0" - jest-util "^29.7.0" - jest-validate "^29.7.0" - yargs "^17.3.1" - -jest-config@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.7.0.tgz#bcbda8806dbcc01b1e316a46bb74085a84b0245f" - integrity sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ== - dependencies: - "@babel/core" "^7.11.6" - "@jest/test-sequencer" "^29.7.0" - "@jest/types" "^29.6.3" - babel-jest "^29.7.0" - chalk "^4.0.0" - ci-info "^3.2.0" - deepmerge "^4.2.2" - glob "^7.1.3" - graceful-fs "^4.2.9" - jest-circus "^29.7.0" - jest-environment-node "^29.7.0" - jest-get-type "^29.6.3" - jest-regex-util "^29.6.3" - jest-resolve "^29.7.0" - jest-runner "^29.7.0" - jest-util "^29.7.0" - jest-validate "^29.7.0" - micromatch "^4.0.4" - parse-json "^5.2.0" - pretty-format "^29.7.0" - slash "^3.0.0" - strip-json-comments "^3.1.1" - -"jest-diff@>=29.4.3 < 30", jest-diff@^29.4.1, jest-diff@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.7.0.tgz#017934a66ebb7ecf6f205e84699be10afd70458a" - integrity sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw== - dependencies: - chalk "^4.0.0" - diff-sequences "^29.6.3" - jest-get-type "^29.6.3" - pretty-format "^29.7.0" - -jest-docblock@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.7.0.tgz#8fddb6adc3cdc955c93e2a87f61cfd350d5d119a" - integrity sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g== - dependencies: - detect-newline "^3.0.0" - -jest-each@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.7.0.tgz#162a9b3f2328bdd991beaabffbb74745e56577d1" - integrity sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ== - dependencies: - "@jest/types" "^29.6.3" - chalk "^4.0.0" - jest-get-type "^29.6.3" - jest-util "^29.7.0" - pretty-format "^29.7.0" - -jest-environment-node@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.7.0.tgz#0b93e111dda8ec120bc8300e6d1fb9576e164376" - integrity sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw== - dependencies: - "@jest/environment" "^29.7.0" - "@jest/fake-timers" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/node" "*" - jest-mock "^29.7.0" - jest-util "^29.7.0" - -jest-get-type@^29.6.3: - version "29.6.3" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" - integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== - -jest-haste-map@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.7.0.tgz#3c2396524482f5a0506376e6c858c3bbcc17b104" - integrity sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA== - dependencies: - "@jest/types" "^29.6.3" - "@types/graceful-fs" "^4.1.3" - "@types/node" "*" - anymatch "^3.0.3" - fb-watchman "^2.0.0" - graceful-fs "^4.2.9" - jest-regex-util "^29.6.3" - jest-util "^29.7.0" - jest-worker "^29.7.0" - micromatch "^4.0.4" - walker "^1.0.8" - optionalDependencies: - fsevents "^2.3.2" - -jest-leak-detector@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz#5b7ec0dadfdfec0ca383dc9aa016d36b5ea4c728" - integrity sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw== - dependencies: - jest-get-type "^29.6.3" - pretty-format "^29.7.0" - -jest-matcher-utils@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz#ae8fec79ff249fd592ce80e3ee474e83a6c44f12" - integrity sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g== - dependencies: - chalk "^4.0.0" - jest-diff "^29.7.0" - jest-get-type "^29.6.3" - pretty-format "^29.7.0" - -jest-message-util@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.7.0.tgz#8bc392e204e95dfe7564abbe72a404e28e51f7f3" - integrity sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w== - dependencies: - "@babel/code-frame" "^7.12.13" - "@jest/types" "^29.6.3" - "@types/stack-utils" "^2.0.0" - chalk "^4.0.0" - graceful-fs "^4.2.9" - micromatch "^4.0.4" - pretty-format "^29.7.0" - slash "^3.0.0" - stack-utils "^2.0.3" - -jest-mock@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.7.0.tgz#4e836cf60e99c6fcfabe9f99d017f3fdd50a6347" - integrity sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw== - dependencies: - "@jest/types" "^29.6.3" - "@types/node" "*" - jest-util "^29.7.0" - -jest-pnp-resolver@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" - integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== - -jest-regex-util@^29.6.3: - version "29.6.3" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.6.3.tgz#4a556d9c776af68e1c5f48194f4d0327d24e8a52" - integrity sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg== - -jest-resolve-dependencies@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz#1b04f2c095f37fc776ff40803dc92921b1e88428" - integrity sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA== - dependencies: - jest-regex-util "^29.6.3" - jest-snapshot "^29.7.0" - -jest-resolve@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.7.0.tgz#64d6a8992dd26f635ab0c01e5eef4399c6bcbc30" - integrity sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA== - dependencies: - chalk "^4.0.0" - graceful-fs "^4.2.9" - jest-haste-map "^29.7.0" - jest-pnp-resolver "^1.2.2" - jest-util "^29.7.0" - jest-validate "^29.7.0" - resolve "^1.20.0" - resolve.exports "^2.0.0" - slash "^3.0.0" - -jest-runner@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.7.0.tgz#809af072d408a53dcfd2e849a4c976d3132f718e" - integrity sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ== - dependencies: - "@jest/console" "^29.7.0" - "@jest/environment" "^29.7.0" - "@jest/test-result" "^29.7.0" - "@jest/transform" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/node" "*" - chalk "^4.0.0" - emittery "^0.13.1" - graceful-fs "^4.2.9" - jest-docblock "^29.7.0" - jest-environment-node "^29.7.0" - jest-haste-map "^29.7.0" - jest-leak-detector "^29.7.0" - jest-message-util "^29.7.0" - jest-resolve "^29.7.0" - jest-runtime "^29.7.0" - jest-util "^29.7.0" - jest-watcher "^29.7.0" - jest-worker "^29.7.0" - p-limit "^3.1.0" - source-map-support "0.5.13" - -jest-runtime@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.7.0.tgz#efecb3141cf7d3767a3a0cc8f7c9990587d3d817" - integrity sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ== - dependencies: - "@jest/environment" "^29.7.0" - "@jest/fake-timers" "^29.7.0" - "@jest/globals" "^29.7.0" - "@jest/source-map" "^29.6.3" - "@jest/test-result" "^29.7.0" - "@jest/transform" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/node" "*" - chalk "^4.0.0" - cjs-module-lexer "^1.0.0" - collect-v8-coverage "^1.0.0" - glob "^7.1.3" - graceful-fs "^4.2.9" - jest-haste-map "^29.7.0" - jest-message-util "^29.7.0" - jest-mock "^29.7.0" - jest-regex-util "^29.6.3" - jest-resolve "^29.7.0" - jest-snapshot "^29.7.0" - jest-util "^29.7.0" - slash "^3.0.0" - strip-bom "^4.0.0" - -jest-snapshot@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.7.0.tgz#c2c574c3f51865da1bb329036778a69bf88a6be5" - integrity sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw== - dependencies: - "@babel/core" "^7.11.6" - "@babel/generator" "^7.7.2" - "@babel/plugin-syntax-jsx" "^7.7.2" - "@babel/plugin-syntax-typescript" "^7.7.2" - "@babel/types" "^7.3.3" - "@jest/expect-utils" "^29.7.0" - "@jest/transform" "^29.7.0" - "@jest/types" "^29.6.3" - babel-preset-current-node-syntax "^1.0.0" - chalk "^4.0.0" - expect "^29.7.0" - graceful-fs "^4.2.9" - jest-diff "^29.7.0" - jest-get-type "^29.6.3" - jest-matcher-utils "^29.7.0" - jest-message-util "^29.7.0" - jest-util "^29.7.0" - natural-compare "^1.4.0" - pretty-format "^29.7.0" - semver "^7.5.3" - -jest-util@^29.0.0, jest-util@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc" - integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== - dependencies: - "@jest/types" "^29.6.3" - "@types/node" "*" - chalk "^4.0.0" - ci-info "^3.2.0" - graceful-fs "^4.2.9" - picomatch "^2.2.3" - -jest-validate@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.7.0.tgz#7bf705511c64da591d46b15fce41400d52147d9c" - integrity sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw== - dependencies: - "@jest/types" "^29.6.3" - camelcase "^6.2.0" - chalk "^4.0.0" - jest-get-type "^29.6.3" - leven "^3.1.0" - pretty-format "^29.7.0" - -jest-watcher@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.7.0.tgz#7810d30d619c3a62093223ce6bb359ca1b28a2f2" - integrity sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g== - dependencies: - "@jest/test-result" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/node" "*" - ansi-escapes "^4.2.1" - chalk "^4.0.0" - emittery "^0.13.1" - jest-util "^29.7.0" - string-length "^4.0.1" - -jest-worker@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.7.0.tgz#acad073acbbaeb7262bd5389e1bcf43e10058d4a" - integrity sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw== - dependencies: - "@types/node" "*" - jest-util "^29.7.0" - merge-stream "^2.0.0" - supports-color "^8.0.0" - -jest@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest/-/jest-29.7.0.tgz#994676fc24177f088f1c5e3737f5697204ff2613" - integrity sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw== - dependencies: - "@jest/core" "^29.7.0" - "@jest/types" "^29.6.3" - import-local "^3.0.2" - jest-cli "^29.7.0" - -js-sha3@0.8.0, js-sha3@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" - integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== - -js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@4.1.0, js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -js-yaml@^3.10.0, js-yaml@^3.13.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsbn@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-1.1.0.tgz#b01307cb29b618a1ed26ec79e911f803c4da0040" - integrity sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A== - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - -json-buffer@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" - integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== - -json-parse-better-errors@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - -json-parse-even-better-errors@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - -json-parse-even-better-errors@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz#02bb29fb5da90b5444581749c22cedd3597c6cb0" - integrity sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== - -json-stringify-safe@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== - -json5@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" - integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== - dependencies: - minimist "^1.2.0" - -json5@^2.2.2, json5@^2.2.3: - version "2.2.3" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" - integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== - -jsonc-parser@3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" - integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== - -jsonc-parser@^3.2.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.1.tgz#031904571ccf929d7670ee8c547545081cb37f1a" - integrity sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA== - -jsonfile@^2.1.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" - integrity sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw== - optionalDependencies: - graceful-fs "^4.1.6" - -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg== - optionalDependencies: - graceful-fs "^4.1.6" - -jsonfile@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" - integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== - dependencies: - universalify "^2.0.0" - optionalDependencies: - graceful-fs "^4.1.6" - -jsonparse@^1.2.0, jsonparse@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" - integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== - -keccak@3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.2.tgz#4c2c6e8c54e04f2670ee49fa734eb9da152206e0" - integrity sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ== - dependencies: - node-addon-api "^2.0.0" - node-gyp-build "^4.2.0" - readable-stream "^3.6.0" - -keccak@^3.0.0, keccak@^3.0.2: - version "3.0.4" - resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.4.tgz#edc09b89e633c0549da444432ecf062ffadee86d" - integrity sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q== - dependencies: - node-addon-api "^2.0.0" - node-gyp-build "^4.2.0" - readable-stream "^3.6.0" - -keyv@^4.5.3: - version "4.5.4" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" - integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== - dependencies: - json-buffer "3.0.1" - -kind-of@^6.0.2, kind-of@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - -klaw@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" - integrity sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw== - optionalDependencies: - graceful-fs "^4.1.9" - -kleur@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" - integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== - -kuler@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3" - integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A== - -lerna-changelog@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/lerna-changelog/-/lerna-changelog-2.2.0.tgz#c43813bba81e30cdeb20aabaef4da390f0f38e41" - integrity sha512-yjYNAHrbnw8xYFKmYWJEP52Tk4xSdlNmzpYr26+3glbSGDmpe8UMo8f9DlEntjGufL+opup421oVTXcLshwAaQ== - dependencies: - chalk "^4.0.0" - cli-highlight "^2.1.11" - execa "^5.0.0" - hosted-git-info "^4.0.0" - make-fetch-happen "^9.0.0" - p-map "^3.0.0" - progress "^2.0.0" - yargs "^17.1.0" - -lerna@^7.2.0: - version "7.4.2" - resolved "https://registry.yarnpkg.com/lerna/-/lerna-7.4.2.tgz#03497125d7b7c8d463eebfe17a701b16bde2ad09" - integrity sha512-gxavfzHfJ4JL30OvMunmlm4Anw7d7Tq6tdVHzUukLdS9nWnxCN/QB21qR+VJYp5tcyXogHKbdUEGh6qmeyzxSA== - dependencies: - "@lerna/child-process" "7.4.2" - "@lerna/create" "7.4.2" - "@npmcli/run-script" "6.0.2" - "@nx/devkit" ">=16.5.1 < 17" - "@octokit/plugin-enterprise-rest" "6.0.1" - "@octokit/rest" "19.0.11" - byte-size "8.1.1" - chalk "4.1.0" - clone-deep "4.0.1" - cmd-shim "6.0.1" - columnify "1.6.0" - conventional-changelog-angular "7.0.0" - conventional-changelog-core "5.0.1" - conventional-recommended-bump "7.0.1" - cosmiconfig "^8.2.0" - dedent "0.7.0" - envinfo "7.8.1" - execa "5.0.0" - fs-extra "^11.1.1" - get-port "5.1.1" - get-stream "6.0.0" - git-url-parse "13.1.0" - glob-parent "5.1.2" - globby "11.1.0" - graceful-fs "4.2.11" - has-unicode "2.0.1" - import-local "3.1.0" - ini "^1.3.8" - init-package-json "5.0.0" - inquirer "^8.2.4" - is-ci "3.0.1" - is-stream "2.0.0" - jest-diff ">=29.4.3 < 30" - js-yaml "4.1.0" - libnpmaccess "7.0.2" - libnpmpublish "7.3.0" - load-json-file "6.2.0" - lodash "^4.17.21" - make-dir "4.0.0" - minimatch "3.0.5" - multimatch "5.0.0" - node-fetch "2.6.7" - npm-package-arg "8.1.1" - npm-packlist "5.1.1" - npm-registry-fetch "^14.0.5" - npmlog "^6.0.2" - nx ">=16.5.1 < 17" - p-map "4.0.0" - p-map-series "2.1.0" - p-pipe "3.1.0" - p-queue "6.6.2" - p-reduce "2.1.0" - p-waterfall "2.1.1" - pacote "^15.2.0" - pify "5.0.0" - read-cmd-shim "4.0.0" - read-package-json "6.0.4" - resolve-from "5.0.0" - rimraf "^4.4.1" - semver "^7.3.8" - signal-exit "3.0.7" - slash "3.0.0" - ssri "^9.0.1" - strong-log-transformer "2.1.0" - tar "6.1.11" - temp-dir "1.0.0" - typescript ">=3 < 6" - upath "2.0.1" - uuid "^9.0.0" - validate-npm-package-license "3.0.4" - validate-npm-package-name "5.0.0" - write-file-atomic "5.0.1" - write-pkg "4.0.0" - yargs "16.2.0" - yargs-parser "20.2.4" - -level-concat-iterator@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/level-concat-iterator/-/level-concat-iterator-3.1.0.tgz#5235b1f744bc34847ed65a50548aa88d22e881cf" - integrity sha512-BWRCMHBxbIqPxJ8vHOvKUsaO0v1sLYZtjN3K2iZJsRBYtp+ONsY6Jfi6hy9K3+zolgQRryhIn2NRZjZnWJ9NmQ== - dependencies: - catering "^2.1.0" - -level-supports@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-2.1.0.tgz#9af908d853597ecd592293b2fad124375be79c5f" - integrity sha512-E486g1NCjW5cF78KGPrMDRBYzPuueMZ6VBXHT6gC7A8UYWGiM14fGgp+s/L1oFfDWSPV/+SFkYCmZ0SiESkRKA== - -level-supports@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-4.0.1.tgz#431546f9d81f10ff0fea0e74533a0e875c08c66a" - integrity sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA== - -level-transcoder@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/level-transcoder/-/level-transcoder-1.0.1.tgz#f8cef5990c4f1283d4c86d949e73631b0bc8ba9c" - integrity sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w== - dependencies: - buffer "^6.0.3" - module-error "^1.0.1" - -leveldown@6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/leveldown/-/leveldown-6.1.0.tgz#7ab1297706f70c657d1a72b31b40323aa612b9ee" - integrity sha512-8C7oJDT44JXxh04aSSsfcMI8YiaGRhOFI9/pMEL7nWJLVsWajDPTRxsSHTM2WcTVY5nXM+SuRHzPPi0GbnDX+w== - dependencies: - abstract-leveldown "^7.2.0" - napi-macros "~2.0.0" - node-gyp-build "^4.3.0" - -leven@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" - integrity sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA== - -leven@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" - integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== - -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== - dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" - -libnpmaccess@7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/libnpmaccess/-/libnpmaccess-7.0.2.tgz#7f056c8c933dd9c8ba771fa6493556b53c5aac52" - integrity sha512-vHBVMw1JFMTgEk15zRsJuSAg7QtGGHpUSEfnbcRL1/gTBag9iEfJbyjpDmdJmwMhvpoLoNBtdAUCdGnaP32hhw== - dependencies: - npm-package-arg "^10.1.0" - npm-registry-fetch "^14.0.3" - -libnpmpublish@7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/libnpmpublish/-/libnpmpublish-7.3.0.tgz#2ceb2b36866d75a6cd7b4aa748808169f4d17e37" - integrity sha512-fHUxw5VJhZCNSls0KLNEG0mCD2PN1i14gH5elGOgiVnU3VgTcRahagYP2LKI1m0tFCJ+XrAm0zVYyF5RCbXzcg== - dependencies: - ci-info "^3.6.1" - normalize-package-data "^5.0.0" - npm-package-arg "^10.1.0" - npm-registry-fetch "^14.0.3" - proc-log "^3.0.0" - semver "^7.3.7" - sigstore "^1.4.0" - ssri "^10.0.1" - -lines-and-columns@^1.1.6: - version "1.2.4" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" - integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== - -lines-and-columns@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-2.0.4.tgz#d00318855905d2660d8c0822e3f5a4715855fc42" - integrity sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A== - -load-json-file@6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-6.2.0.tgz#5c7770b42cafa97074ca2848707c61662f4251a1" - integrity sha512-gUD/epcRms75Cw8RT1pUdHugZYM5ce64ucs2GEISABwkRsOQr0q2wm/MV2TKThycIe5e0ytRweW2RZxclogCdQ== - dependencies: - graceful-fs "^4.1.15" - parse-json "^5.0.0" - strip-bom "^4.0.0" - type-fest "^0.6.0" - -load-json-file@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" - integrity sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw== - dependencies: - graceful-fs "^4.1.2" - parse-json "^4.0.0" - pify "^3.0.0" - strip-bom "^3.0.0" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA== - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lodash.ismatch@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37" - integrity sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g== - -lodash.memoize@4.x: - version "4.1.2" - resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" - integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== - -lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - -lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.21: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -log-symbols@4.1.0, log-symbols@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" - -logform@^2.3.2, logform@^2.4.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/logform/-/logform-2.6.0.tgz#8c82a983f05d6eaeb2d75e3decae7a768b2bf9b5" - integrity sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ== - dependencies: - "@colors/colors" "1.6.0" - "@types/triple-beam" "^1.3.2" - fecha "^4.2.0" - ms "^2.1.1" - safe-stable-stringify "^2.3.1" - triple-beam "^1.3.0" - -lru-cache@^10.0.1, "lru-cache@^9.1.1 || ^10.0.0": - version "10.2.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.2.0.tgz#0bd445ca57363465900f4d1f9bd8db343a4d95c3" - integrity sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q== - -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== - dependencies: - yallist "^3.0.2" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -lru-cache@^7.4.4, lru-cache@^7.5.1, lru-cache@^7.7.1: - version "7.18.3" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" - integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== - -lru_map@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd" - integrity sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ== - -lunr@^2.3.9: - version "2.3.9" - resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" - integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow== - -make-dir@4.0.0, make-dir@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" - integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== - dependencies: - semver "^7.5.3" - -make-dir@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" - integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== - dependencies: - pify "^4.0.1" - semver "^5.6.0" - -make-dir@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - -make-error@1.x, make-error@^1.1.1: - version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - -make-fetch-happen@^10.0.3: - version "10.2.1" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz#f5e3835c5e9817b617f2770870d9492d28678164" - integrity sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w== - dependencies: - agentkeepalive "^4.2.1" - cacache "^16.1.0" - http-cache-semantics "^4.1.0" - http-proxy-agent "^5.0.0" - https-proxy-agent "^5.0.0" - is-lambda "^1.0.1" - lru-cache "^7.7.1" - minipass "^3.1.6" - minipass-collect "^1.0.2" - minipass-fetch "^2.0.3" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - negotiator "^0.6.3" - promise-retry "^2.0.1" - socks-proxy-agent "^7.0.0" - ssri "^9.0.0" - -make-fetch-happen@^11.0.0, make-fetch-happen@^11.0.1, make-fetch-happen@^11.1.1: - version "11.1.1" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz#85ceb98079584a9523d4bf71d32996e7e208549f" - integrity sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w== - dependencies: - agentkeepalive "^4.2.1" - cacache "^17.0.0" - http-cache-semantics "^4.1.1" - http-proxy-agent "^5.0.0" - https-proxy-agent "^5.0.0" - is-lambda "^1.0.1" - lru-cache "^7.7.1" - minipass "^5.0.0" - minipass-fetch "^3.0.0" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - negotiator "^0.6.3" - promise-retry "^2.0.1" - socks-proxy-agent "^7.0.0" - ssri "^10.0.0" - -make-fetch-happen@^9.0.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz#53085a09e7971433e6765f7971bf63f4e05cb968" - integrity sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg== - dependencies: - agentkeepalive "^4.1.3" - cacache "^15.2.0" - http-cache-semantics "^4.1.0" - http-proxy-agent "^4.0.1" - https-proxy-agent "^5.0.0" - is-lambda "^1.0.1" - lru-cache "^6.0.0" - minipass "^3.1.3" - minipass-collect "^1.0.2" - minipass-fetch "^1.3.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - negotiator "^0.6.2" - promise-retry "^2.0.1" - socks-proxy-agent "^6.0.0" - ssri "^8.0.0" - -makeerror@1.0.12: - version "1.0.12" - resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" - integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== - dependencies: - tmpl "1.0.5" - -map-obj@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" - integrity sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg== - -map-obj@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.3.0.tgz#9304f906e93faae70880da102a9f1df0ea8bb05a" - integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ== - -marked@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/marked/-/marked-4.3.0.tgz#796362821b019f734054582038b116481b456cf3" - integrity sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A== - -md5.js@^1.3.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" - integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -memorystream@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" - integrity sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw== - -meow@^8.1.2: - version "8.1.2" - resolved "https://registry.yarnpkg.com/meow/-/meow-8.1.2.tgz#bcbe45bda0ee1729d350c03cffc8395a36c4e897" - integrity sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q== - dependencies: - "@types/minimist" "^1.2.0" - camelcase-keys "^6.2.2" - decamelize-keys "^1.1.0" - hard-rejection "^2.1.0" - minimist-options "4.1.0" - normalize-package-data "^3.0.0" - read-pkg-up "^7.0.1" - redent "^3.0.0" - trim-newlines "^3.0.0" - type-fest "^0.18.0" - yargs-parser "^20.2.3" - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - -merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -merge@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/merge/-/merge-2.1.1.tgz#59ef4bf7e0b3e879186436e8481c06a6c162ca98" - integrity sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w== - -merkletreejs@^0.3.11: - version "0.3.11" - resolved "https://registry.yarnpkg.com/merkletreejs/-/merkletreejs-0.3.11.tgz#e0de05c3ca1fd368de05a12cb8efb954ef6fc04f" - integrity sha512-LJKTl4iVNTndhL+3Uz/tfkjD0klIWsHlUzgtuNnNrsf7bAlXR30m+xYB7lHr5Z/l6e/yAIsr26Dabx6Buo4VGQ== - dependencies: - bignumber.js "^9.0.1" - buffer-reverse "^1.0.1" - crypto-js "^4.2.0" - treeify "^1.1.0" - web3-utils "^1.3.4" - -micro-ftch@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/micro-ftch/-/micro-ftch-0.3.1.tgz#6cb83388de4c1f279a034fb0cf96dfc050853c5f" - integrity sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg== - -micromatch@^4.0.2, micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@^2.1.12: - version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -min-indent@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" - integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== - -minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -minimalistic-crypto-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" - integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== - -minimatch@3.0.5: - version "3.0.5" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.5.tgz#4da8f1290ee0f0f8e83d60ca69f8f134068604a3" - integrity sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw== - dependencies: - brace-expansion "^1.1.7" - -minimatch@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" - integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== - dependencies: - brace-expansion "^2.0.1" - -minimatch@9.0.3, minimatch@^9.0.0, minimatch@^9.0.1, minimatch@^9.0.3: - version "9.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" - integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== - dependencies: - brace-expansion "^2.0.1" - -minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^5.0.1: - version "5.1.6" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" - integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== - dependencies: - brace-expansion "^2.0.1" - -minimatch@^8.0.2: - version "8.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-8.0.4.tgz#847c1b25c014d4e9a7f68aaf63dedd668a626229" - integrity sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA== - dependencies: - brace-expansion "^2.0.1" - -minimist-options@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619" - integrity sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A== - dependencies: - arrify "^1.0.1" - is-plain-obj "^1.1.0" - kind-of "^6.0.3" - -minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: - version "1.2.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== - -minipass-collect@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" - integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== - dependencies: - minipass "^3.0.0" - -minipass-fetch@^1.3.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-1.4.1.tgz#d75e0091daac1b0ffd7e9d41629faff7d0c1f1b6" - integrity sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw== - dependencies: - minipass "^3.1.0" - minipass-sized "^1.0.3" - minizlib "^2.0.0" - optionalDependencies: - encoding "^0.1.12" - -minipass-fetch@^2.0.3: - version "2.1.2" - resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-2.1.2.tgz#95560b50c472d81a3bc76f20ede80eaed76d8add" - integrity sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA== - dependencies: - minipass "^3.1.6" - minipass-sized "^1.0.3" - minizlib "^2.1.2" - optionalDependencies: - encoding "^0.1.13" - -minipass-fetch@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-3.0.4.tgz#4d4d9b9f34053af6c6e597a64be8e66e42bf45b7" - integrity sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg== - dependencies: - minipass "^7.0.3" - minipass-sized "^1.0.3" - minizlib "^2.1.2" - optionalDependencies: - encoding "^0.1.13" - -minipass-flush@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" - integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== - dependencies: - minipass "^3.0.0" - -minipass-json-stream@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz#7edbb92588fbfc2ff1db2fc10397acb7b6b44aa7" - integrity sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg== - dependencies: - jsonparse "^1.3.1" - minipass "^3.0.0" - -minipass-pipeline@^1.2.2, minipass-pipeline@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" - integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== - dependencies: - minipass "^3.0.0" - -minipass-sized@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70" - integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== - dependencies: - minipass "^3.0.0" - -minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3, minipass@^3.1.6: - version "3.3.6" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" - integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== - dependencies: - yallist "^4.0.0" - -minipass@^4.2.4: - version "4.2.8" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-4.2.8.tgz#f0010f64393ecfc1d1ccb5f582bcaf45f48e1a3a" - integrity sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ== - -minipass@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" - integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== - -"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.3: - version "7.0.4" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" - integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== - -minizlib@^2.0.0, minizlib@^2.1.1, minizlib@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" - integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== - dependencies: - minipass "^3.0.0" - yallist "^4.0.0" - -mkdirp@1.0.4, mkdirp@^1.0.3, mkdirp@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - -mnemonist@^0.38.0: - version "0.38.5" - resolved "https://registry.yarnpkg.com/mnemonist/-/mnemonist-0.38.5.tgz#4adc7f4200491237fe0fa689ac0b86539685cade" - integrity sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg== - dependencies: - obliterator "^2.0.0" - -mocha@^10.0.0: - version "10.3.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.3.0.tgz#0e185c49e6dccf582035c05fa91084a4ff6e3fe9" - integrity sha512-uF2XJs+7xSLsrmIvn37i/wnc91nw7XjOQB8ccyx5aEgdnohr7n+rEiZP23WkCYHjilR6+EboEnbq/ZQDz4LSbg== - dependencies: - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.3" - debug "4.3.4" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "8.1.0" - he "1.2.0" - js-yaml "4.1.0" - log-symbols "4.1.0" - minimatch "5.0.1" - ms "2.1.3" - serialize-javascript "6.0.0" - strip-json-comments "3.1.1" - supports-color "8.1.1" - workerpool "6.2.1" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" - -modify-values@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" - integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw== - -module-error@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/module-error/-/module-error-1.0.2.tgz#8d1a48897ca883f47a45816d4fb3e3c6ba404d86" - integrity sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA== - -mri@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/mri/-/mri-1.1.4.tgz#7cb1dd1b9b40905f1fac053abe25b6720f44744a" - integrity sha512-6y7IjGPm8AzlvoUrwAaw1tLnUBudaS3752vcd8JtrpGGQn+rXIe63LFVHm/YMwtqAuh+LJPCFdlLYPWM1nYn6w== - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@2.1.3, ms@^2.0.0, ms@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -multimatch@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-5.0.0.tgz#932b800963cea7a31a033328fa1e0c3a1874dbe6" - integrity sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA== - dependencies: - "@types/minimatch" "^3.0.3" - array-differ "^3.0.0" - array-union "^2.1.0" - arrify "^2.0.1" - minimatch "^3.0.4" - -mute-stream@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" - integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== - -mute-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-1.0.0.tgz#e31bd9fe62f0aed23520aa4324ea6671531e013e" - integrity sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA== - -mz@^2.4.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" - integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== - dependencies: - any-promise "^1.0.0" - object-assign "^4.0.1" - thenify-all "^1.0.0" - -napi-macros@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.0.0.tgz#2b6bae421e7b96eb687aa6c77a7858640670001b" - integrity sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg== - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== - -negotiator@^0.6.2, negotiator@^0.6.3: - version "0.6.3" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" - integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== - -neo-async@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" - integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== - -nock@^13.2.9: - version "13.5.4" - resolved "https://registry.yarnpkg.com/nock/-/nock-13.5.4.tgz#8918f0addc70a63736170fef7106a9721e0dc479" - integrity sha512-yAyTfdeNJGGBFxWdzSKCBYxs5FxLbCg5X5Q4ets974hcQzG1+qCxvIyOo4j2Ry6MUlhWVMX4OoYDefAIIwupjw== - dependencies: - debug "^4.1.0" - json-stringify-safe "^5.0.1" - propagate "^2.0.0" - -node-addon-api@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" - integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== - -node-addon-api@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161" - integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A== - -node-fetch@2.6.7: - version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== - dependencies: - whatwg-url "^5.0.0" - -node-fetch@^2.6.7: - version "2.7.0" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" - integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== - dependencies: - whatwg-url "^5.0.0" - -node-gyp-build@4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.4.0.tgz#42e99687ce87ddeaf3a10b99dc06abc11021f3f4" - integrity sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ== - -node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: - version "4.8.0" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.0.tgz#3fee9c1731df4581a3f9ead74664369ff00d26dd" - integrity sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og== - -node-gyp@^9.0.0, node-gyp@^9.4.0: - version "9.4.1" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.4.1.tgz#8a1023e0d6766ecb52764cc3a734b36ff275e185" - integrity sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ== - dependencies: - env-paths "^2.2.0" - exponential-backoff "^3.1.1" - glob "^7.1.4" - graceful-fs "^4.2.6" - make-fetch-happen "^10.0.3" - nopt "^6.0.0" - npmlog "^6.0.0" - rimraf "^3.0.2" - semver "^7.3.5" - tar "^6.1.2" - which "^2.0.2" - -node-int64@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" - integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== - -node-machine-id@1.1.12: - version "1.1.12" - resolved "https://registry.yarnpkg.com/node-machine-id/-/node-machine-id-1.1.12.tgz#37904eee1e59b320bb9c5d6c0a59f3b469cb6267" - integrity sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ== - -node-releases@^2.0.14: - version "2.0.14" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b" - integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== - -nopt@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-6.0.0.tgz#245801d8ebf409c6df22ab9d95b65e1309cdb16d" - integrity sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g== - dependencies: - abbrev "^1.0.0" - -normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-package-data@^3.0.0, normalize-package-data@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-3.0.3.tgz#dbcc3e2da59509a0983422884cd172eefdfa525e" - integrity sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA== - dependencies: - hosted-git-info "^4.0.1" - is-core-module "^2.5.0" - semver "^7.3.4" - validate-npm-package-license "^3.0.1" - -normalize-package-data@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-5.0.0.tgz#abcb8d7e724c40d88462b84982f7cbf6859b4588" - integrity sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q== - dependencies: - hosted-git-info "^6.0.0" - is-core-module "^2.8.1" - semver "^7.3.5" - validate-npm-package-license "^3.0.4" - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -npm-bundled@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.2.tgz#944c78789bd739035b70baa2ca5cc32b8d860bc1" - integrity sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ== - dependencies: - npm-normalize-package-bin "^1.0.1" - -npm-bundled@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-3.0.0.tgz#7e8e2f8bb26b794265028491be60321a25a39db7" - integrity sha512-Vq0eyEQy+elFpzsKjMss9kxqb9tG3YHg4dsyWuUENuzvSUWe1TCnW/vV9FkhvBk/brEDoDiVd+M1Btosa6ImdQ== - dependencies: - npm-normalize-package-bin "^3.0.0" - -npm-dts@^1.3.12: - version "1.3.12" - resolved "https://registry.yarnpkg.com/npm-dts/-/npm-dts-1.3.12.tgz#e422b1188fb616f41fe5c566c3d636c1aafb2ed8" - integrity sha512-3pFsz7Gf1u0cyQE2czXt8Y0hKe6kczHxlFbVrr74xWweNUit2tCDbOcL4n6KaWxyimGNJ4gzOa8KkShFA8hrdA== - dependencies: - args "5.0.3" - find-node-modules "2.1.3" - mkdirp "1.0.4" - npm-run "5.0.1" - rimraf "3.0.2" - tmp "0.2.1" - winston "3.7.2" - -npm-install-checks@^6.0.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-6.3.0.tgz#046552d8920e801fa9f919cad569545d60e826fe" - integrity sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw== - dependencies: - semver "^7.1.1" - -npm-normalize-package-bin@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" - integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== - -npm-normalize-package-bin@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz#25447e32a9a7de1f51362c61a559233b89947832" - integrity sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ== - -npm-package-arg@8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.1.tgz#00ebf16ac395c63318e67ce66780a06db6df1b04" - integrity sha512-CsP95FhWQDwNqiYS+Q0mZ7FAEDytDZAkNxQqea6IaAFJTAY9Lhhqyl0irU/6PMc7BGfUmnsbHcqxJD7XuVM/rg== - dependencies: - hosted-git-info "^3.0.6" - semver "^7.0.0" - validate-npm-package-name "^3.0.0" - -npm-package-arg@^10.0.0, npm-package-arg@^10.1.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-10.1.0.tgz#827d1260a683806685d17193073cc152d3c7e9b1" - integrity sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA== - dependencies: - hosted-git-info "^6.0.0" - proc-log "^3.0.0" - semver "^7.3.5" - validate-npm-package-name "^5.0.0" - -npm-packlist@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-5.1.1.tgz#79bcaf22a26b6c30aa4dd66b976d69cc286800e0" - integrity sha512-UfpSvQ5YKwctmodvPPkK6Fwk603aoVsf8AEbmVKAEECrfvL8SSe1A2YIwrJ6xmTHAITKPwwZsWo7WwEbNk0kxw== - dependencies: - glob "^8.0.1" - ignore-walk "^5.0.1" - npm-bundled "^1.1.2" - npm-normalize-package-bin "^1.0.1" - -npm-packlist@^7.0.0: - version "7.0.4" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-7.0.4.tgz#033bf74110eb74daf2910dc75144411999c5ff32" - integrity sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q== - dependencies: - ignore-walk "^6.0.0" - -npm-path@^2.0.2, npm-path@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/npm-path/-/npm-path-2.0.4.tgz#c641347a5ff9d6a09e4d9bce5580c4f505278e64" - integrity sha512-IFsj0R9C7ZdR5cP+ET342q77uSRdtWOlWpih5eC+lu29tIDbNEgDbzgVJ5UFvYHWhxDZ5TFkJafFioO0pPQjCw== - dependencies: - which "^1.2.10" - -npm-pick-manifest@^8.0.0: - version "8.0.2" - resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-8.0.2.tgz#2159778d9c7360420c925c1a2287b5a884c713aa" - integrity sha512-1dKY+86/AIiq1tkKVD3l0WI+Gd3vkknVGAggsFeBkTvbhMQ1OND/LKkYv4JtXPKUJ8bOTCyLiqEg2P6QNdK+Gg== - dependencies: - npm-install-checks "^6.0.0" - npm-normalize-package-bin "^3.0.0" - npm-package-arg "^10.0.0" - semver "^7.3.5" - -npm-registry-fetch@^14.0.0, npm-registry-fetch@^14.0.3, npm-registry-fetch@^14.0.5: - version "14.0.5" - resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-14.0.5.tgz#fe7169957ba4986a4853a650278ee02e568d115d" - integrity sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA== - dependencies: - make-fetch-happen "^11.0.0" - minipass "^5.0.0" - minipass-fetch "^3.0.0" - minipass-json-stream "^1.0.1" - minizlib "^2.1.2" - npm-package-arg "^10.0.0" - proc-log "^3.0.0" - -npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - -npm-run@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/npm-run/-/npm-run-5.0.1.tgz#1baea93389b50ae25a32382c8ca322398e50cd16" - integrity sha512-s7FyRpHUgaJfzkRgOnevX8rAWWsv1dofY1XS7hliWCF6LSQh+HtDfBvpigPS1krLvXw+Fi17CYMY8mUtblnyWw== - dependencies: - minimist "^1.2.0" - npm-path "^2.0.4" - npm-which "^3.0.1" - serializerr "^1.0.3" - -npm-which@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/npm-which/-/npm-which-3.0.1.tgz#9225f26ec3a285c209cae67c3b11a6b4ab7140aa" - integrity sha512-CM8vMpeFQ7MAPin0U3wzDhSGV0hMHNwHU0wjo402IVizPDrs45jSfSuoC+wThevY88LQti8VvaAnqYAeVy3I1A== - dependencies: - commander "^2.9.0" - npm-path "^2.0.2" - which "^1.2.10" - -npmlog@^6.0.0, npmlog@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.2.tgz#c8166017a42f2dea92d6453168dd865186a70830" - integrity sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg== - dependencies: - are-we-there-yet "^3.0.0" - console-control-strings "^1.1.0" - gauge "^4.0.3" - set-blocking "^2.0.0" - -number-to-bn@1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/number-to-bn/-/number-to-bn-1.7.0.tgz#bb3623592f7e5f9e0030b1977bd41a0c53fe1ea0" - integrity sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig== - dependencies: - bn.js "4.11.6" - strip-hex-prefix "1.0.0" - -nx@16.10.0, "nx@>=16.5.1 < 17", nx@^16.8.1: - version "16.10.0" - resolved "https://registry.yarnpkg.com/nx/-/nx-16.10.0.tgz#b070461f7de0a3d7988bd78558ea84cda3543ace" - integrity sha512-gZl4iCC0Hx0Qe1VWmO4Bkeul2nttuXdPpfnlcDKSACGu3ZIo+uySqwOF8yBAxSTIf8xe2JRhgzJN1aFkuezEBg== - dependencies: - "@nrwl/tao" "16.10.0" - "@parcel/watcher" "2.0.4" - "@yarnpkg/lockfile" "^1.1.0" - "@yarnpkg/parsers" "3.0.0-rc.46" - "@zkochan/js-yaml" "0.0.6" - axios "^1.0.0" - chalk "^4.1.0" - cli-cursor "3.1.0" - cli-spinners "2.6.1" - cliui "^8.0.1" - dotenv "~16.3.1" - dotenv-expand "~10.0.0" - enquirer "~2.3.6" - figures "3.2.0" - flat "^5.0.2" - fs-extra "^11.1.0" - glob "7.1.4" - ignore "^5.0.4" - jest-diff "^29.4.1" - js-yaml "4.1.0" - jsonc-parser "3.2.0" - lines-and-columns "~2.0.3" - minimatch "3.0.5" - node-machine-id "1.1.12" - npm-run-path "^4.0.1" - open "^8.4.0" - semver "7.5.3" - string-width "^4.2.3" - strong-log-transformer "^2.1.0" - tar-stream "~2.2.0" - tmp "~0.2.1" - tsconfig-paths "^4.1.2" - tslib "^2.3.0" - v8-compile-cache "2.3.0" - yargs "^17.6.2" - yargs-parser "21.1.1" - optionalDependencies: - "@nx/nx-darwin-arm64" "16.10.0" - "@nx/nx-darwin-x64" "16.10.0" - "@nx/nx-freebsd-x64" "16.10.0" - "@nx/nx-linux-arm-gnueabihf" "16.10.0" - "@nx/nx-linux-arm64-gnu" "16.10.0" - "@nx/nx-linux-arm64-musl" "16.10.0" - "@nx/nx-linux-x64-gnu" "16.10.0" - "@nx/nx-linux-x64-musl" "16.10.0" - "@nx/nx-win32-arm64-msvc" "16.10.0" - "@nx/nx-win32-x64-msvc" "16.10.0" - -object-assign@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== - -object-inspect@^1.13.1: - version "1.13.1" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" - integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== - -object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@^4.1.2, object.assign@^4.1.5: - version "4.1.5" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0" - integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ== - dependencies: - call-bind "^1.0.5" - define-properties "^1.2.1" - has-symbols "^1.0.3" - object-keys "^1.1.1" - -object.entries@^1.1.5: - version "1.1.7" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.7.tgz#2b47760e2a2e3a752f39dd874655c61a7f03c131" - integrity sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -object.fromentries@^2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.7.tgz#71e95f441e9a0ea6baf682ecaaf37fa2a8d7e616" - integrity sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -object.groupby@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.2.tgz#494800ff5bab78fd0eff2835ec859066e00192ec" - integrity sha512-bzBq58S+x+uo0VjurFT0UktpKHOZmv4/xePiOA1nbB9pMqpGK7rUPNgf+1YC+7mE+0HzhTMqNUuCqvKhj6FnBw== - dependencies: - array.prototype.filter "^1.0.3" - call-bind "^1.0.5" - define-properties "^1.2.1" - es-abstract "^1.22.3" - es-errors "^1.0.0" - -object.values@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.7.tgz#617ed13272e7e1071b43973aa1655d9291b8442a" - integrity sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -obliterator@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/obliterator/-/obliterator-2.0.4.tgz#fa650e019b2d075d745e44f1effeb13a2adbe816" - integrity sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ== - -once@^1.3.0, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - -one-time@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/one-time/-/one-time-1.0.0.tgz#e06bc174aed214ed58edede573b433bbf827cb45" - integrity sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g== - dependencies: - fn.name "1.x.x" - -onetime@^5.1.0, onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -open@^8.4.0: - version "8.4.2" - resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" - integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== - dependencies: - define-lazy-prop "^2.0.0" - is-docker "^2.1.1" - is-wsl "^2.2.0" - -optionator@^0.9.3: - version "0.9.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" - integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== - dependencies: - "@aashutoshrathi/word-wrap" "^1.2.3" - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - -ora@^5.4.1: - version "5.4.1" - resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" - integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== - dependencies: - bl "^4.1.0" - chalk "^4.1.0" - cli-cursor "^3.1.0" - cli-spinners "^2.5.0" - is-interactive "^1.0.0" - is-unicode-supported "^0.1.0" - log-symbols "^4.1.0" - strip-ansi "^6.0.0" - wcwidth "^1.0.1" - -os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== - -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" - -p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-limit@^3.0.2, p-limit@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg== - dependencies: - p-limit "^1.1.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -p-map-series@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-map-series/-/p-map-series-2.1.0.tgz#7560d4c452d9da0c07e692fdbfe6e2c81a2a91f2" - integrity sha512-RpYIIK1zXSNEOdwxcfe7FdvGcs7+y5n8rifMhMNWvaxRNMPINJHF5GDeuVxWqnfrcHPSCnp7Oo5yNXHId9Av2Q== - -p-map@4.0.0, p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" - integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== - dependencies: - aggregate-error "^3.0.0" - -p-map@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-3.0.0.tgz#d704d9af8a2ba684e2600d9a215983d4141a979d" - integrity sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ== - dependencies: - aggregate-error "^3.0.0" - -p-pipe@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-pipe/-/p-pipe-3.1.0.tgz#48b57c922aa2e1af6a6404cb7c6bf0eb9cc8e60e" - integrity sha512-08pj8ATpzMR0Y80x50yJHn37NF6vjrqHutASaX5LiH5npS9XPvrUmscd9MF5R4fuYRHOxQR1FfMIlF7AzwoPqw== - -p-queue@6.6.2: - version "6.6.2" - resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-6.6.2.tgz#2068a9dcf8e67dd0ec3e7a2bcb76810faa85e426" - integrity sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ== - dependencies: - eventemitter3 "^4.0.4" - p-timeout "^3.2.0" - -p-reduce@2.1.0, p-reduce@^2.0.0, p-reduce@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-2.1.0.tgz#09408da49507c6c274faa31f28df334bc712b64a" - integrity sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw== - -p-timeout@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" - integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== - dependencies: - p-finally "^1.0.0" - -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww== - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -p-waterfall@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/p-waterfall/-/p-waterfall-2.1.1.tgz#63153a774f472ccdc4eb281cdb2967fcf158b2ee" - integrity sha512-RRTnDb2TBG/epPRI2yYXsimO0v3BXC8Yd3ogr1545IaqKK17VGhbWVeGGN+XfCm/08OK8635nH31c8bATkHuSw== - dependencies: - p-reduce "^2.0.0" - -pacote@^15.2.0: - version "15.2.0" - resolved "https://registry.yarnpkg.com/pacote/-/pacote-15.2.0.tgz#0f0dfcc3e60c7b39121b2ac612bf8596e95344d3" - integrity sha512-rJVZeIwHTUta23sIZgEIM62WYwbmGbThdbnkt81ravBplQv+HjyroqnLRNH2+sLJHcGZmLRmhPwACqhfTcOmnA== - dependencies: - "@npmcli/git" "^4.0.0" - "@npmcli/installed-package-contents" "^2.0.1" - "@npmcli/promise-spawn" "^6.0.1" - "@npmcli/run-script" "^6.0.0" - cacache "^17.0.0" - fs-minipass "^3.0.0" - minipass "^5.0.0" - npm-package-arg "^10.0.0" - npm-packlist "^7.0.0" - npm-pick-manifest "^8.0.0" - npm-registry-fetch "^14.0.0" - proc-log "^3.0.0" - promise-retry "^2.0.1" - read-package-json "^6.0.0" - read-package-json-fast "^3.0.0" - sigstore "^1.3.0" - ssri "^10.0.0" - tar "^6.1.11" - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw== - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - -parse-json@^5.0.0, parse-json@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" - integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== - dependencies: - "@babel/code-frame" "^7.0.0" - error-ex "^1.3.1" - json-parse-even-better-errors "^2.3.0" - lines-and-columns "^1.1.6" - -parse-passwd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" - integrity sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q== - -parse-path@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/parse-path/-/parse-path-7.0.0.tgz#605a2d58d0a749c8594405d8cc3a2bf76d16099b" - integrity sha512-Euf9GG8WT9CdqwuWJGdf3RkUcTBArppHABkO7Lm8IzRQp0e2r/kkFnmhu4TSK30Wcu5rVAZLmfPKSBBi9tWFog== - dependencies: - protocols "^2.0.0" - -parse-url@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/parse-url/-/parse-url-8.1.0.tgz#972e0827ed4b57fc85f0ea6b0d839f0d8a57a57d" - integrity sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w== - dependencies: - parse-path "^7.0.0" - -parse5-htmlparser2-tree-adapter@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6" - integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA== - dependencies: - parse5 "^6.0.1" - -parse5@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" - integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== - -parse5@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" - integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - -path-key@^3.0.0, path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-parse@^1.0.6, path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-scurry@^1.10.1, path-scurry@^1.6.1: - version "1.10.1" - resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" - integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== - dependencies: - lru-cache "^9.1.1 || ^10.0.0" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" - -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" - integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== - dependencies: - pify "^3.0.0" - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -pbkdf2@^3.0.17: - version "3.1.2" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" - integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== - dependencies: - create-hash "^1.1.2" - create-hmac "^1.1.4" - ripemd160 "^2.0.1" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== - -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -pify@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-5.0.0.tgz#1f5eca3f5e87ebec28cc6d54a0e4aaf00acc127f" - integrity sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA== - -pify@^2.0.0, pify@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg== - -pify@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" - integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== - -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw== - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== - -pirates@^4.0.4: - version "4.0.6" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" - integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== - -pkg-dir@^4.1.0, pkg-dir@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - -possible-typed-array-names@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" - integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q== - -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== - -prettier-linter-helpers@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" - integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== - dependencies: - fast-diff "^1.1.2" - -prettier@^3.0.3: - version "3.2.5" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.2.5.tgz#e52bc3090586e824964a8813b09aba6233b28368" - integrity sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A== - -pretty-format@^29.0.0, pretty-format@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" - integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== - dependencies: - "@jest/schemas" "^29.6.3" - ansi-styles "^5.0.0" - react-is "^18.0.0" - -proc-log@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-3.0.0.tgz#fb05ef83ccd64fd7b20bbe9c8c1070fc08338dd8" - integrity sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A== - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -progress@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - -promise-inflight@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" - integrity sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g== - -promise-retry@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" - integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== - dependencies: - err-code "^2.0.2" - retry "^0.12.0" - -prompts@^2.0.1: - version "2.4.2" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" - integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== - dependencies: - kleur "^3.0.3" - sisteransi "^1.0.5" - -promzard@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/promzard/-/promzard-1.0.0.tgz#3246f8e6c9895a77c0549cefb65828ac0f6c006b" - integrity sha512-KQVDEubSUHGSt5xLakaToDFrSoZhStB8dXLzk2xvwR67gJktrHFvpR63oZgHyK19WKbHFLXJqCPXdVR3aBP8Ig== - dependencies: - read "^2.0.0" - -propagate@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/propagate/-/propagate-2.0.1.tgz#40cdedab18085c792334e64f0ac17256d38f9a45" - integrity sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag== - -protochain@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/protochain/-/protochain-1.0.5.tgz#991c407e99de264aadf8f81504b5e7faf7bfa260" - integrity sha512-4hDwFSX50C4NE6f/6zg8EPr/WLPTkFPUtG0ulWZu6bwzV2hmb50fpdQLr0HiKBAUehapaFpItzWoCLjraLJhUA== - -protocols@^2.0.0, protocols@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/protocols/-/protocols-2.0.1.tgz#8f155da3fc0f32644e83c5782c8e8212ccf70a86" - integrity sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q== - -proxy-from-env@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" - integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== - -punycode@^2.1.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" - integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== - -pure-rand@^6.0.0: - version "6.0.4" - resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.0.4.tgz#50b737f6a925468679bff00ad20eade53f37d5c7" - integrity sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA== - -query-string@^8.1.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-8.2.0.tgz#f0b0ef6caa85f525dbdb745a67d3f8c08d71cc6b" - integrity sha512-tUZIw8J0CawM5wyGBiDOAp7ObdRQh4uBor/fUR9ZjmbZVvw95OD9If4w3MQxr99rg0DJZ/9CIORcpEqU5hQG7g== - dependencies: - decode-uri-component "^0.4.1" - filter-obj "^5.1.0" - split-on-first "^3.0.0" - -queue-microtask@^1.2.2, queue-microtask@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -quick-lru@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" - integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== - -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -raw-body@^2.4.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" - integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== - dependencies: - bytes "3.1.2" - http-errors "2.0.0" - iconv-lite "0.4.24" - unpipe "1.0.0" - -react-is@^18.0.0: - version "18.2.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" - integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== - -read-cmd-shim@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-4.0.0.tgz#640a08b473a49043e394ae0c7a34dd822c73b9bb" - integrity sha512-yILWifhaSEEytfXI76kB9xEEiG1AiozaCJZ83A87ytjRiN+jVibXjedjCRNjoZviinhG+4UkalO3mWTd8u5O0Q== - -read-package-json-fast@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz#394908a9725dc7a5f14e70c8e7556dff1d2b1049" - integrity sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw== - dependencies: - json-parse-even-better-errors "^3.0.0" - npm-normalize-package-bin "^3.0.0" - -read-package-json@6.0.4, read-package-json@^6.0.0: - version "6.0.4" - resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-6.0.4.tgz#90318824ec456c287437ea79595f4c2854708836" - integrity sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw== - dependencies: - glob "^10.2.2" - json-parse-even-better-errors "^3.0.0" - normalize-package-data "^5.0.0" - npm-normalize-package-bin "^3.0.0" - -read-pkg-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" - integrity sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw== - dependencies: - find-up "^2.0.0" - read-pkg "^3.0.0" - -read-pkg-up@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" - integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== - dependencies: - find-up "^4.1.0" - read-pkg "^5.2.0" - type-fest "^0.8.1" - -read-pkg@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" - integrity sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA== - dependencies: - load-json-file "^4.0.0" - normalize-package-data "^2.3.2" - path-type "^3.0.0" - -read-pkg@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" - integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== - dependencies: - "@types/normalize-package-data" "^2.4.0" - normalize-package-data "^2.5.0" - parse-json "^5.0.0" - type-fest "^0.6.0" - -read@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/read/-/read-2.1.0.tgz#69409372c54fe3381092bc363a00650b6ac37218" - integrity sha512-bvxi1QLJHcaywCAEsAk4DG3nVoqiY2Csps3qzWalhj5hFqRn1d/OixkFXtLO1PrgHUcAP0FNaSY/5GYNfENFFQ== - dependencies: - mute-stream "~1.0.0" - -readable-stream@^3.0.0, readable-stream@^3.0.2, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: - version "3.6.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readable-stream@~2.3.6: - version "2.3.8" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" - integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -redent@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" - integrity sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg== - dependencies: - indent-string "^4.0.0" - strip-indent "^3.0.0" - -regenerator-runtime@^0.14.0: - version "0.14.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" - integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== - -regexp-tree@~0.1.1: - version "0.1.27" - resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.27.tgz#2198f0ef54518ffa743fe74d983b56ffd631b6cd" - integrity sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA== - -regexp.prototype.flags@^1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz#138f644a3350f981a858c44f6bb1a61ff59be334" - integrity sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw== - dependencies: - call-bind "^1.0.6" - define-properties "^1.2.1" - es-errors "^1.3.0" - set-function-name "^2.0.1" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== - -require-from-string@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - -resolve-cwd@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" - integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== - dependencies: - resolve-from "^5.0.0" - -resolve-dir@^1.0.0, resolve-dir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" - integrity sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg== - dependencies: - expand-tilde "^2.0.0" - global-modules "^1.0.0" - -resolve-from@5.0.0, resolve-from@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" - integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve.exports@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" - integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg== - -resolve@1.17.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" - integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== - dependencies: - path-parse "^1.0.6" - -resolve@^1.10.0, resolve@^1.20.0, resolve@^1.22.4: - version "1.22.8" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" - integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== - dependencies: - is-core-module "^2.13.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -restore-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" - integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== - dependencies: - onetime "^5.1.0" - signal-exit "^3.0.2" - -retry@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" - integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rimraf@3.0.2, rimraf@^3.0.0, rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -rimraf@^2.2.8: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - -rimraf@^4.4.1: - version "4.4.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-4.4.1.tgz#bd33364f67021c5b79e93d7f4fa0568c7c21b755" - integrity sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og== - dependencies: - glob "^9.2.0" - -rimraf@^5.0.1: - version "5.0.5" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-5.0.5.tgz#9be65d2d6e683447d2e9013da2bf451139a61ccf" - integrity sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A== - dependencies: - glob "^10.3.7" - -ripemd160@^2.0.0, ripemd160@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" - integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - -rlp@^2.2.3: - version "2.2.7" - resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.7.tgz#33f31c4afac81124ac4b283e2bd4d9720b30beaf" - integrity sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ== - dependencies: - bn.js "^5.2.0" - -run-async@^2.4.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" - integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -rxjs@^7.5.5, rxjs@^7.8.1: - version "7.8.1" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" - integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== - dependencies: - tslib "^2.1.0" - -safe-array-concat@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.1.0.tgz#8d0cae9cb806d6d1c06e08ab13d847293ebe0692" - integrity sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg== - dependencies: - call-bind "^1.0.5" - get-intrinsic "^1.2.2" - has-symbols "^1.0.3" - isarray "^2.0.5" - -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-regex-test@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.3.tgz#a5b4c0f06e0ab50ea2c395c14d8371232924c377" - integrity sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw== - dependencies: - call-bind "^1.0.6" - es-errors "^1.3.0" - is-regex "^1.1.4" - -safe-regex@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-2.1.1.tgz#f7128f00d056e2fe5c11e81a1324dd974aadced2" - integrity sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A== - dependencies: - regexp-tree "~0.1.1" - -safe-stable-stringify@^2.3.1: - version "2.4.3" - resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz#138c84b6f6edb3db5f8ef3ef7115b8f55ccbf886" - integrity sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g== - -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -scrypt-js@3.0.1, scrypt-js@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" - integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== - -secp256k1@4.0.3, secp256k1@^4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.3.tgz#c4559ecd1b8d3c1827ed2d1b94190d69ce267303" - integrity sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA== - dependencies: - elliptic "^6.5.4" - node-addon-api "^2.0.0" - node-gyp-build "^4.2.0" - -"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.6.0: - version "5.7.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" - integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== - -semver@7.5.3: - version "7.5.3" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e" - integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ== - dependencies: - lru-cache "^6.0.0" - -semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: - version "6.3.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== - -semver@^7.0.0, semver@^7.1.1, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4: - version "7.6.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d" - integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== - dependencies: - lru-cache "^6.0.0" - -serialize-javascript@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== - dependencies: - randombytes "^2.1.0" - -serializerr@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/serializerr/-/serializerr-1.0.3.tgz#12d4c5aa1c3ffb8f6d1dc5f395aa9455569c3f91" - integrity sha512-yXUlHj0fjbndhACj2XWtIH5eJv7b/uadyl7CJA8b9wL5mIKm+g0/sL7rDzEmjC+k5y8ggcaP8i049F4FxA0U9Q== - dependencies: - protochain "^1.0.5" - -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== - -set-function-length@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.1.tgz#47cc5945f2c771e2cf261c6737cf9684a2a5e425" - integrity sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g== - dependencies: - define-data-property "^1.1.2" - es-errors "^1.3.0" - function-bind "^1.1.2" - get-intrinsic "^1.2.3" - gopd "^1.0.1" - has-property-descriptors "^1.0.1" - -set-function-name@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.2.tgz#16a705c5a0dc2f5e638ca96d8a8cd4e1c2b90985" - integrity sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ== - dependencies: - define-data-property "^1.1.4" - es-errors "^1.3.0" - functions-have-names "^1.2.3" - has-property-descriptors "^1.0.2" - -setimmediate@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== - -setprototypeof@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" - integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== - -sha.js@^2.4.0, sha.js@^2.4.8: - version "2.4.11" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" - integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -shallow-clone@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" - integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== - dependencies: - kind-of "^6.0.2" - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -shell-quote@^1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680" - integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA== - -shiki@^0.14.7: - version "0.14.7" - resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.14.7.tgz#c3c9e1853e9737845f1d2ef81b31bcfb07056d4e" - integrity sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg== - dependencies: - ansi-sequence-parser "^1.1.0" - jsonc-parser "^3.2.0" - vscode-oniguruma "^1.7.0" - vscode-textmate "^8.0.0" - -side-channel@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" - integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== - dependencies: - call-bind "^1.0.7" - es-errors "^1.3.0" - get-intrinsic "^1.2.4" - object-inspect "^1.13.1" - -signal-exit@3.0.7, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - -signal-exit@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" - integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== - -sigstore@^1.3.0, sigstore@^1.4.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/sigstore/-/sigstore-1.9.0.tgz#1e7ad8933aa99b75c6898ddd0eeebc3eb0d59875" - integrity sha512-0Zjz0oe37d08VeOtBIuB6cRriqXse2e8w+7yIy2XSXjshRKxbc2KkhXjL229jXSxEm7UbcjS76wcJDGQddVI9A== - dependencies: - "@sigstore/bundle" "^1.1.0" - "@sigstore/protobuf-specs" "^0.2.0" - "@sigstore/sign" "^1.0.0" - "@sigstore/tuf" "^1.0.3" - make-fetch-happen "^11.0.1" - -simple-swizzle@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" - integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg== - dependencies: - is-arrayish "^0.3.1" - -sisteransi@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" - integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== - -slash@3.0.0, slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -smart-buffer@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" - integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== - -socks-proxy-agent@^6.0.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz#2687a31f9d7185e38d530bef1944fe1f1496d6ce" - integrity sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ== - dependencies: - agent-base "^6.0.2" - debug "^4.3.3" - socks "^2.6.2" - -socks-proxy-agent@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz#dc069ecf34436621acb41e3efa66ca1b5fed15b6" - integrity sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww== - dependencies: - agent-base "^6.0.2" - debug "^4.3.3" - socks "^2.6.2" - -socks@^2.6.2: - version "2.8.1" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.1.tgz#22c7d9dd7882649043cba0eafb49ae144e3457af" - integrity sha512-B6w7tkwNid7ToxjZ08rQMT8M9BJAf8DKx8Ft4NivzH0zBUfd6jldGcisJn/RLgxcX3FPNDdNQCUEMMT79b+oCQ== - dependencies: - ip-address "^9.0.5" - smart-buffer "^4.2.0" - -solc@0.7.3: - version "0.7.3" - resolved "https://registry.yarnpkg.com/solc/-/solc-0.7.3.tgz#04646961bd867a744f63d2b4e3c0701ffdc7d78a" - integrity sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA== - dependencies: - command-exists "^1.2.8" - commander "3.0.2" - follow-redirects "^1.12.1" - fs-extra "^0.30.0" - js-sha3 "0.8.0" - memorystream "^0.3.1" - require-from-string "^2.0.0" - semver "^5.5.0" - tmp "0.0.33" - -sort-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" - integrity sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg== - dependencies: - is-plain-obj "^1.0.0" - -source-map-support@0.5.13: - version "0.5.13" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" - integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map-support@^0.5.13: - version "0.5.21" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.6.0, source-map@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -spawn-command@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2.tgz#9544e1a43ca045f8531aac1a48cb29bdae62338e" - integrity sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ== - -spdx-correct@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" - integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz#5d607d27fc806f66d7b64a766650fa890f04ed66" - integrity sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w== - -spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.17" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz#887da8aa73218e51a1d917502d79863161a93f9c" - integrity sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg== - -split-on-first@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-3.0.0.tgz#f04959c9ea8101b9b0bbf35a61b9ebea784a23e7" - integrity sha512-qxQJTx2ryR0Dw0ITYyekNQWpz6f8dGd7vffGNflQQ3Iqj9NJ6qiZ7ELpZsJ/QBhIVAiDfXdag3+Gp8RvWa62AA== - -split2@^3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/split2/-/split2-3.2.2.tgz#bf2cf2a37d838312c249c89206fd7a17dd12365f" - integrity sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg== - dependencies: - readable-stream "^3.0.0" - -split@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" - integrity sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg== - dependencies: - through "2" - -sprintf-js@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.3.tgz#4914b903a2f8b685d17fdf78a70e917e872e444a" - integrity sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA== - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== - -ssri@^10.0.0, ssri@^10.0.1: - version "10.0.5" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-10.0.5.tgz#e49efcd6e36385196cb515d3a2ad6c3f0265ef8c" - integrity sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A== - dependencies: - minipass "^7.0.3" - -ssri@^8.0.0, ssri@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" - integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== - dependencies: - minipass "^3.1.1" - -ssri@^9.0.0, ssri@^9.0.1: - version "9.0.1" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-9.0.1.tgz#544d4c357a8d7b71a19700074b6883fcb4eae057" - integrity sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q== - dependencies: - minipass "^3.1.1" - -stack-trace@0.0.x: - version "0.0.10" - resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" - integrity sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg== - -stack-utils@^2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" - integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== - dependencies: - escape-string-regexp "^2.0.0" - -stacktrace-parser@^0.1.10: - version "0.1.10" - resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a" - integrity sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg== - dependencies: - type-fest "^0.7.1" - -statuses@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" - integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== - -string-length@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" - integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== - dependencies: - char-regex "^1.0.2" - strip-ansi "^6.0.0" - -"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^5.0.1, string-width@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" - integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== - dependencies: - eastasianwidth "^0.2.0" - emoji-regex "^9.2.2" - strip-ansi "^7.0.1" - -string.prototype.trim@^1.2.8: - version "1.2.8" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz#f9ac6f8af4bd55ddfa8895e6aea92a96395393bd" - integrity sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -string.prototype.trimend@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz#1bb3afc5008661d73e2dc015cd4853732d6c471e" - integrity sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -string.prototype.trimstart@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz#d4cdb44b83a4737ffbac2d406e405d43d0184298" - integrity sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^7.0.1: - version "7.1.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" - integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== - dependencies: - ansi-regex "^6.0.1" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== - -strip-bom@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" - integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== - -strip-comments@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-comments/-/strip-comments-2.0.1.tgz#4ad11c3fbcac177a67a40ac224ca339ca1c1ba9b" - integrity sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw== - -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - -strip-hex-prefix@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz#0c5f155fef1151373377de9dbb588da05500e36f" - integrity sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A== - dependencies: - is-hex-prefixed "1.0.0" - -strip-indent@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" - integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ== - dependencies: - min-indent "^1.0.0" - -strip-json-comments@3.1.1, strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -strip-outer@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/strip-outer/-/strip-outer-1.0.1.tgz#b2fd2abf6604b9d1e6013057195df836b8a9d631" - integrity sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg== - dependencies: - escape-string-regexp "^1.0.2" - -strong-log-transformer@2.1.0, strong-log-transformer@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz#0f5ed78d325e0421ac6f90f7f10e691d6ae3ae10" - integrity sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA== - dependencies: - duplexer "^0.1.1" - minimist "^1.2.0" - through "^2.3.4" - -supports-color@8.1.1, supports-color@^8.0.0, supports-color@^8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== - -synckit@^0.8.6: - version "0.8.8" - resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.8.8.tgz#fe7fe446518e3d3d49f5e429f443cf08b6edfcd7" - integrity sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ== - dependencies: - "@pkgr/core" "^0.1.0" - tslib "^2.6.2" - -tar-stream@~2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" - integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== - dependencies: - bl "^4.0.3" - end-of-stream "^1.4.1" - fs-constants "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.1.1" - -tar@6.1.11: - version "6.1.11" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" - integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== - dependencies: - chownr "^2.0.0" - fs-minipass "^2.0.0" - minipass "^3.0.0" - minizlib "^2.1.1" - mkdirp "^1.0.3" - yallist "^4.0.0" - -tar@^6.0.2, tar@^6.1.11, tar@^6.1.2: - version "6.2.0" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.0.tgz#b14ce49a79cb1cd23bc9b016302dea5474493f73" - integrity sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ== - dependencies: - chownr "^2.0.0" - fs-minipass "^2.0.0" - minipass "^5.0.0" - minizlib "^2.1.1" - mkdirp "^1.0.3" - yallist "^4.0.0" - -temp-dir@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" - integrity sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ== - -test-exclude@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" - integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== - dependencies: - "@istanbuljs/schema" "^0.1.2" - glob "^7.1.4" - minimatch "^3.0.4" - -text-extensions@^1.0.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26" - integrity sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ== - -text-hex@1.0.x: - version "1.0.0" - resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5" - integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg== - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== - -thenify-all@^1.0.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" - integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== - dependencies: - thenify ">= 3.1.0 < 4" - -"thenify@>= 3.1.0 < 4": - version "3.3.1" - resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" - integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== - dependencies: - any-promise "^1.0.0" - -through2@^2.0.0: - version "2.0.5" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" - integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== - dependencies: - readable-stream "~2.3.6" - xtend "~4.0.1" - -through@2, "through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== - -tmp@0.0.33, tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - -tmp@0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" - integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== - dependencies: - rimraf "^3.0.0" - -tmp@~0.2.1: - version "0.2.3" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.3.tgz#eb783cc22bc1e8bebd0671476d46ea4eb32a79ae" - integrity sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w== - -tmpl@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" - integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -toidentifier@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" - integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== - -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - -tree-kill@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" - integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== - -treeify@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/treeify/-/treeify-1.1.0.tgz#4e31c6a463accd0943879f30667c4fdaff411bb8" - integrity sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A== - -trim-newlines@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144" - integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw== - -trim-repeated@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/trim-repeated/-/trim-repeated-1.0.0.tgz#e3646a2ea4e891312bf7eace6cfb05380bc01c21" - integrity sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg== - dependencies: - escape-string-regexp "^1.0.2" - -triple-beam@^1.3.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.4.1.tgz#6fde70271dc6e5d73ca0c3b24e2d92afb7441984" - integrity sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg== - -ts-api-utils@^1.0.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.2.1.tgz#f716c7e027494629485b21c0df6180f4d08f5e8b" - integrity sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA== - -ts-jest@^29.1.1: - version "29.1.2" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.1.2.tgz#7613d8c81c43c8cb312c6904027257e814c40e09" - integrity sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g== - dependencies: - bs-logger "0.x" - fast-json-stable-stringify "2.x" - jest-util "^29.0.0" - json5 "^2.2.3" - lodash.memoize "4.x" - make-error "1.x" - semver "^7.5.3" - yargs-parser "^21.0.1" - -ts-node@^10.9.1: - version "10.9.2" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.2.tgz#70f021c9e185bccdca820e26dc413805c101c71f" - integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== - dependencies: - "@cspotcode/source-map-support" "^0.8.0" - "@tsconfig/node10" "^1.0.7" - "@tsconfig/node12" "^1.0.7" - "@tsconfig/node14" "^1.0.0" - "@tsconfig/node16" "^1.0.2" - acorn "^8.4.1" - acorn-walk "^8.1.1" - arg "^4.1.0" - create-require "^1.1.0" - diff "^4.0.1" - make-error "^1.1.1" - v8-compile-cache-lib "^3.0.1" - yn "3.1.1" - -tsconfig-paths@^3.15.0: - version "3.15.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4" - integrity sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg== - dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.2" - minimist "^1.2.6" - strip-bom "^3.0.0" - -tsconfig-paths@^4.1.2: - version "4.2.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz#ef78e19039133446d244beac0fd6a1632e2d107c" - integrity sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg== - dependencies: - json5 "^2.2.2" - minimist "^1.2.6" - strip-bom "^3.0.0" - -tslib@^1.9.3: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tslib@^2.1.0, tslib@^2.3.0, tslib@^2.4.0, tslib@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" - integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== - -tsort@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/tsort/-/tsort-0.0.1.tgz#e2280f5e817f8bf4275657fd0f9aebd44f5a2786" - integrity sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw== - -tuf-js@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/tuf-js/-/tuf-js-1.1.7.tgz#21b7ae92a9373015be77dfe0cb282a80ec3bbe43" - integrity sha512-i3P9Kgw3ytjELUfpuKVDNBJvk4u5bXL6gskv572mcevPbSKCV3zt3djhmlEQ65yERjIbOSncy7U4cQJaB1CBCg== - dependencies: - "@tufjs/models" "1.0.4" - debug "^4.3.4" - make-fetch-happen "^11.1.1" - -tweetnacl-util@^0.15.1: - version "0.15.1" - resolved "https://registry.yarnpkg.com/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz#b80fcdb5c97bcc508be18c44a4be50f022eea00b" - integrity sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw== - -tweetnacl@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" - integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== - -type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== - dependencies: - prelude-ls "^1.2.1" - -type-detect@4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== - -type-fest@^0.18.0: - version "0.18.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.18.1.tgz#db4bc151a4a2cf4eebf9add5db75508db6cc841f" - integrity sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw== - -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - -type-fest@^0.21.3: - version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" - integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== - -type-fest@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.4.1.tgz#8bdf77743385d8a4f13ba95f610f5ccd68c728f8" - integrity sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw== - -type-fest@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" - integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== - -type-fest@^0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" - integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== - -type-fest@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" - integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== - -typed-array-buffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz#1867c5d83b20fcb5ccf32649e5e2fc7424474ff3" - integrity sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ== - dependencies: - call-bind "^1.0.7" - es-errors "^1.3.0" - is-typed-array "^1.1.13" - -typed-array-byte-length@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz#d92972d3cff99a3fa2e765a28fcdc0f1d89dec67" - integrity sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw== - dependencies: - call-bind "^1.0.7" - for-each "^0.3.3" - gopd "^1.0.1" - has-proto "^1.0.3" - is-typed-array "^1.1.13" - -typed-array-byte-offset@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz#f9ec1acb9259f395093e4567eb3c28a580d02063" - integrity sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA== - dependencies: - available-typed-arrays "^1.0.7" - call-bind "^1.0.7" - for-each "^0.3.3" - gopd "^1.0.1" - has-proto "^1.0.3" - is-typed-array "^1.1.13" - -typed-array-length@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.5.tgz#57d44da160296d8663fd63180a1802ebf25905d5" - integrity sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA== - dependencies: - call-bind "^1.0.7" - for-each "^0.3.3" - gopd "^1.0.1" - has-proto "^1.0.3" - is-typed-array "^1.1.13" - possible-typed-array-names "^1.0.0" - -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== - -typedoc@^0.25.7: - version "0.25.11" - resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.25.11.tgz#75080c594c1e26b7676f90faebb367fb5a32dc8d" - integrity sha512-5MbI1W/FOG6oXsd8bdssQidSTeKh8Kt3xA5uKVzI+K99uzP8EGN45uPnPvQesyaWdD+89s4wCQdtWEd8QUbiRg== - dependencies: - lunr "^2.3.9" - marked "^4.3.0" - minimatch "^9.0.3" - shiki "^0.14.7" - -"typescript@>=3 < 6", typescript@^5.3.3: - version "5.4.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.2.tgz#0ae9cebcfae970718474fe0da2c090cad6577372" - integrity sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ== - -uglify-js@^3.1.4: - version "3.17.4" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" - integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== - -unbox-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" - integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== - dependencies: - call-bind "^1.0.2" - has-bigints "^1.0.2" - has-symbols "^1.0.3" - which-boxed-primitive "^1.0.2" - -undici-types@~5.26.4: - version "5.26.5" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" - integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== - -undici@^5.14.0: - version "5.28.3" - resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.3.tgz#a731e0eff2c3fcfd41c1169a869062be222d1e5b" - integrity sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA== - dependencies: - "@fastify/busboy" "^2.0.0" - -unidragger@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/unidragger/-/unidragger-3.0.1.tgz#72b2e63f2571ca6e95a884b139dfec764e08c7f3" - integrity sha512-RngbGSwBFmqGBWjkaH+yB677uzR95blSQyxq6hYbrQCejH3Mx1nm8DVOuh3M9k2fQyTstWUG5qlgCnNqV/9jVw== - dependencies: - ev-emitter "^2.0.0" - -unique-filename@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" - integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== - dependencies: - unique-slug "^2.0.0" - -unique-filename@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-2.0.1.tgz#e785f8675a9a7589e0ac77e0b5c34d2eaeac6da2" - integrity sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A== - dependencies: - unique-slug "^3.0.0" - -unique-filename@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-3.0.0.tgz#48ba7a5a16849f5080d26c760c86cf5cf05770ea" - integrity sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g== - dependencies: - unique-slug "^4.0.0" - -unique-slug@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" - integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== - dependencies: - imurmurhash "^0.1.4" - -unique-slug@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-3.0.0.tgz#6d347cf57c8a7a7a6044aabd0e2d74e4d76dc7c9" - integrity sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w== - dependencies: - imurmurhash "^0.1.4" - -unique-slug@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-4.0.0.tgz#6bae6bb16be91351badd24cdce741f892a6532e3" - integrity sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ== - dependencies: - imurmurhash "^0.1.4" - -universal-user-agent@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.1.tgz#15f20f55da3c930c57bddbf1734c6654d5fd35aa" - integrity sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ== - -universalify@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== - -universalify@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" - integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== - -unpipe@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== - -upath@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/upath/-/upath-2.0.1.tgz#50c73dea68d6f6b990f51d279ce6081665d61a8b" - integrity sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w== - -update-browserslist-db@^1.0.13: - version "1.0.13" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" - integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg== - dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -utf-8-validate@5.0.7: - version "5.0.7" - resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.7.tgz#c15a19a6af1f7ad9ec7ddc425747ca28c3644922" - integrity sha512-vLt1O5Pp+flcArHGIyKEQq883nBt8nN8tVBcoL0qUXj2XT1n7p70yGIq2VK98I5FdZ1YHc0wk/koOnHjnXWk1Q== - dependencies: - node-gyp-build "^4.3.0" - -utf-8-validate@6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-6.0.3.tgz#7d8c936d854e86b24d1d655f138ee27d2636d777" - integrity sha512-uIuGf9TWQ/y+0Lp+KGZCMuJWc3N9BHA+l/UmHd/oUHwJJDeysyTRxNQVkbzsIWfGFbRe3OcgML/i0mvVRPOyDA== - dependencies: - node-gyp-build "^4.3.0" - -utf8@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" - integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== - -util-deprecate@^1.0.1, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== - -uuid@8.3.2, uuid@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - -uuid@^9.0.0: - version "9.0.1" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" - integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== - -uuidv4@^6.2.13: - version "6.2.13" - resolved "https://registry.yarnpkg.com/uuidv4/-/uuidv4-6.2.13.tgz#8f95ec5ef22d1f92c8e5d4c70b735d1c89572cb7" - integrity sha512-AXyzMjazYB3ovL3q051VLH06Ixj//Knx7QnUSi1T//Ie3io6CpsPu9nVMOx5MoLWh6xV0B9J0hIaxungxXUbPQ== - dependencies: - "@types/uuid" "8.3.4" - uuid "8.3.2" - -v8-compile-cache-lib@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" - integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== - -v8-compile-cache@2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - -v8-to-istanbul@^9.0.1: - version "9.2.0" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz#2ed7644a245cddd83d4e087b9b33b3e62dfd10ad" - integrity sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA== - dependencies: - "@jridgewell/trace-mapping" "^0.3.12" - "@types/istanbul-lib-coverage" "^2.0.1" - convert-source-map "^2.0.0" - -validate-npm-package-license@3.0.4, validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -validate-npm-package-name@5.0.0, validate-npm-package-name@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-5.0.0.tgz#f16afd48318e6f90a1ec101377fa0384cfc8c713" - integrity sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ== - dependencies: - builtins "^5.0.0" - -validate-npm-package-name@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" - integrity sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw== - dependencies: - builtins "^1.0.3" - -viem@^2.7.12, viem@^2.7.8: - version "2.7.20" - resolved "https://registry.yarnpkg.com/viem/-/viem-2.7.20.tgz#c0d517c3ce5a19b963d624b378d706bd3c45efc6" - integrity sha512-S31a24LWEjqXAjw1A+3/xALo+4eiYKklAjLtlLdPhA0cp+Kv6GcgruNVTktP8pKIGNYvpyQ+HA9PJyUhVXPdDw== - dependencies: - "@adraffy/ens-normalize" "1.10.0" - "@noble/curves" "1.2.0" - "@noble/hashes" "1.3.2" - "@scure/bip32" "1.3.2" - "@scure/bip39" "1.2.1" - abitype "1.0.0" - isows "1.0.3" - ws "8.13.0" - -vscode-oniguruma@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz#439bfad8fe71abd7798338d1cd3dc53a8beea94b" - integrity sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA== - -vscode-textmate@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-8.0.0.tgz#2c7a3b1163ef0441097e0b5d6389cd5504b59e5d" - integrity sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg== - -walker@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" - integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== - dependencies: - makeerror "1.0.12" - -wcwidth@^1.0.0, wcwidth@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" - integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg== - dependencies: - defaults "^1.0.3" - -web3-utils@^1.3.4: - version "1.10.4" - resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.10.4.tgz#0daee7d6841641655d8b3726baf33b08eda1cbec" - integrity sha512-tsu8FiKJLk2PzhDl9fXbGUWTkkVXYhtTA+SmEFkKft+9BgwLxfCRpU96sWv7ICC8zixBNd3JURVoiR3dUXgP8A== - dependencies: - "@ethereumjs/util" "^8.1.0" - bn.js "^5.2.1" - ethereum-bloom-filters "^1.0.6" - ethereum-cryptography "^2.1.2" - ethjs-unit "0.1.6" - number-to-bn "1.7.0" - randombytes "^2.1.0" - utf8 "3.0.0" - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - -which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" - -which-typed-array@^1.1.14: - version "1.1.14" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.14.tgz#1f78a111aee1e131ca66164d8bdc3ab062c95a06" - integrity sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg== - dependencies: - available-typed-arrays "^1.0.6" - call-bind "^1.0.5" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.1" - -which@^1.2.10, which@^1.2.14: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -which@^2.0.1, which@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -which@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/which/-/which-3.0.1.tgz#89f1cd0c23f629a8105ffe69b8172791c87b4be1" - integrity sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg== - dependencies: - isexe "^2.0.0" - -wide-align@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" - integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== - dependencies: - string-width "^1.0.2 || 2 || 3 || 4" - -widest-line@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" - integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== - dependencies: - string-width "^4.0.0" - -winston-transport@^4.5.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.7.0.tgz#e302e6889e6ccb7f383b926df6936a5b781bd1f0" - integrity sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg== - dependencies: - logform "^2.3.2" - readable-stream "^3.6.0" - triple-beam "^1.3.0" - -winston@3.7.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/winston/-/winston-3.7.2.tgz#95b4eeddbec902b3db1424932ac634f887c400b1" - integrity sha512-QziIqtojHBoyzUOdQvQiar1DH0Xp9nF1A1y7NVy2DGEsz82SBDtOalS0ulTRGVT14xPX3WRWkCsdcJKqNflKng== - dependencies: - "@dabh/diagnostics" "^2.0.2" - async "^3.2.3" - is-stream "^2.0.0" - logform "^2.4.0" - one-time "^1.0.0" - readable-stream "^3.4.0" - safe-stable-stringify "^2.3.1" - stack-trace "0.0.x" - triple-beam "^1.3.0" - winston-transport "^4.5.0" - -wordwrap@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== - -workerpool@6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" - integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== - -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^6.0.1: - version "6.2.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" - integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" - integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== - dependencies: - ansi-styles "^6.1.0" - string-width "^5.0.1" - strip-ansi "^7.0.1" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -write-file-atomic@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-5.0.1.tgz#68df4717c55c6fa4281a7860b4c2ba0a6d2b11e7" - integrity sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw== - dependencies: - imurmurhash "^0.1.4" - signal-exit "^4.0.1" - -write-file-atomic@^2.4.2: - version "2.4.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481" - integrity sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ== - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - signal-exit "^3.0.2" - -write-file-atomic@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" - integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== - dependencies: - imurmurhash "^0.1.4" - signal-exit "^3.0.7" - -write-json-file@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-3.2.0.tgz#65bbdc9ecd8a1458e15952770ccbadfcff5fe62a" - integrity sha512-3xZqT7Byc2uORAatYiP3DHUUAVEkNOswEWNs9H5KXiicRTvzYzYqKjYc4G7p+8pltvAw641lVByKVtMpf+4sYQ== - dependencies: - detect-indent "^5.0.0" - graceful-fs "^4.1.15" - make-dir "^2.1.0" - pify "^4.0.1" - sort-keys "^2.0.0" - write-file-atomic "^2.4.2" - -write-pkg@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/write-pkg/-/write-pkg-4.0.0.tgz#675cc04ef6c11faacbbc7771b24c0abbf2a20039" - integrity sha512-v2UQ+50TNf2rNHJ8NyWttfm/EJUBWMJcx6ZTYZr6Qp52uuegWw/lBkCtCbnYZEmPRNL61m+u67dAmGxo+HTULA== - dependencies: - sort-keys "^2.0.0" - type-fest "^0.4.1" - write-json-file "^3.2.0" - -ws@7.4.6: - version "7.4.6" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" - integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== - -ws@8.13.0: - version "8.13.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" - integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== - -ws@^7.4.6: - version "7.5.9" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" - integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== - -xtend@~4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yallist@^3.0.2: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - -yargs-parser@21.1.1, yargs-parser@^21.0.1, yargs-parser@^21.1.1: - version "21.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" - integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== - -yargs-parser@^20.2.2, yargs-parser@^20.2.3: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - -yargs-unparser@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" - integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== - dependencies: - camelcase "^6.0.0" - decamelize "^4.0.0" - flat "^5.0.2" - is-plain-obj "^2.1.0" - -yargs@16.2.0, yargs@^16.0.0, yargs@^16.2.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - -yargs@^17.1.0, yargs@^17.3.1, yargs@^17.6.2, yargs@^17.7.2: - version "17.7.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" - integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== - dependencies: - cliui "^8.0.1" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.3" - y18n "^5.0.5" - yargs-parser "^21.1.1" - -yn@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" - integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== - -zod@^3.22.4: - version "3.22.4" - resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.4.tgz#f31c3a9386f61b1f228af56faa9255e845cf3fff" - integrity sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==