diff --git a/.github/workflows/e2e-test.yml b/.github/workflows/api-kit-e2e-test.yml similarity index 57% rename from .github/workflows/e2e-test.yml rename to .github/workflows/api-kit-e2e-test.yml index 335e79660..b1e12d337 100644 --- a/.github/workflows/e2e-test.yml +++ b/.github/workflows/api-kit-e2e-test.yml @@ -1,4 +1,4 @@ -name: e2e Test +name: API Kit - E2E Tests on: pull_request: push: @@ -18,7 +18,15 @@ jobs: with: node-version: ${{ matrix.node-version }} cache: yarn - - run: | - yarn install --frozen-lockfile - yarn build - yarn test:ci + - name: Yarn install + run: yarn install --frozen-lockfile + + - name: Build + run: yarn build + + - name: Test + run: | + cd packages/api-kit + yarn test:ci:ethers + yarn test:ci:web3 + yarn test:ci:viem diff --git a/.github/workflows/test_contracts.yml b/.github/workflows/protocol-kit-e2e-test.yml similarity index 89% rename from .github/workflows/test_contracts.yml rename to .github/workflows/protocol-kit-e2e-test.yml index a4e296596..7e790f43f 100644 --- a/.github/workflows/test_contracts.yml +++ b/.github/workflows/protocol-kit-e2e-test.yml @@ -1,5 +1,6 @@ -name: Safe Core SDK Test - Contracts +name: Protocol Kit - E2E Tests on: + workflow_dispatch: pull_request: push: branches: @@ -11,7 +12,7 @@ jobs: strategy: matrix: node-version: [20.x] - provider: [ethers, web3] + provider: [ethers, web3, viem] contract-version: [v1.0.0, v1.1.1, v1.2.0, v1.3.0, v1.4.1] steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/test.yml b/.github/workflows/sdk-test.yml similarity index 97% rename from .github/workflows/test.yml rename to .github/workflows/sdk-test.yml index 63064b3cd..12c67aba2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/sdk-test.yml @@ -1,4 +1,4 @@ -name: Monorepo Test +name: SDK - Unit Tests on: pull_request: push: diff --git a/.gitignore b/.gitignore index 3a4aba22e..99cb3c5ef 100644 --- a/.gitignore +++ b/.gitignore @@ -54,9 +54,6 @@ cache artifacts deployments -# Typechain -typechain - openapi/ .idea diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..3af627092 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,86 @@ +# Contributing Guidelines + +First off, **thank you** for considering contributing to this project! + +## Table of contents + +- [I Have a Question](#i-have-a-question) +- [I Want to Contribute](#i-want-to-contribute) + +## I Have a Question + +See our [support guidelines](https://github.com/safe-global/safe-core-sdk/tree/main/SUPPORT.md). **Do not** use GitHub issues for general support or questions. + +## I Want to Contribute +### Legal Notice +You will need to agree to [our CLA](https://safe.global/cla) in order to be possible to consider your contribution. + +### Starting Guide + +By following the steps bellow you will understand the development process and worflow. +1. [Forking the repository](#forking-the-repository) +2. [Installing Node and Yarn](#installing-node-and-yarn) +3. [Installing dependencies](#installing-dependencies) +4. [Running the tests](#running-the-tests) +5. [Using the playground](#using-the-playground) +6. [Submitting a pull request](#submitting-a-pull-request) + +#### Forking the repository + +The first step would be to [fork the repository](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo#forking-a-repository). This will allow you to get a current copy of the repository state. Follow the steps to also clone your forked repository locally. + +For active development we use the `development` branch. Our `main` branch contains only the currently published code. All new branches should be created from `development`. + +#### Installing Node and Yarn + +The Safe{Core} SDK uses [Node](https://nodejs.org) as development environment and Yarn to manage the dependencies. You will need to make sure you are using the [latest Node LTS version](https://nodejs.org/en/about/previous-releases) and that you have available Yarn v1. + +You can check which versions you are using with: + +```bash +node -v +yarn -v +``` + +#### Installing dependencies + +The Safe{Core} SDK uses a mono-repository structure managed by [Yarn Workspaces](https://classic.yarnpkg.com/lang/en/docs/workspaces/) and [Lerna](https://lerna.js.org). From the root of the repository you will need to install the whole dependency stack and do the project build. Some packages depend on each other, so even when modifiying only one package it's better to run the full build. + +Install all dependencies and build the whole project by using the following commands at the project root. + +```bash +yarn install +yarn build +``` + +#### Running the tests + +There is already a test script that can be launched from the root of the repository and will use [Lerna](https://lerna.js.org) to run all the tests from all the packages. + +```bash +yarn test +``` + +If you would like to test individual packages, **once you make sure you did the build from the root**, you can: + +```bash +yarn test --scope= +yarn test --scope=@safe-global/protocol-kit +yarn test --scope=@safe-global/api-kit +``` + +For some packages you may need to fill a .env file with some configuration. In those packages you will be able to find a `.env.example` file specifying the necessary parameters. + +#### Using the playground + +You can use the playground section to do some manual testing using a specific Safe or configuration. The playground can be run from the root of the project as follow: + +```bash +yarn play +``` + +You can find more information about the available commands [in the specific section.](https://github.com/safe-global/safe-core-sdk/tree/main/playground) + +#### Submitting a pull request + +From the forked repository you can [open a pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request) to the original repository. Make sure to select the `safe-global:development` branch as the target branch. diff --git a/LICENSE.md b/LICENSE.md index 310e6e37c..0e923d187 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021-2023 Safe Ecosystem Foundation +Copyright (c) 2021-2024 Safe Ecosystem Foundation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/README.md b/README.md index 5a00cb4d9..33606f604 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,30 @@ ![Safe_Logos_Core_SDK_Black](https://github.com/safe-global/safe-core-sdk/assets/6764315/7202a24a-2981-4b31-9cf5-ace1c3b2c4fa) -Software developer tools that facilitate the interaction with the Safe [contracts](https://github.com/safe-global/safe-contracts) and [services](https://github.com/safe-global/safe-transaction-service). +## Table of contents + +- [About](#about) +- [Documentation](#documentation) +- [Guides](#guides) +- [Packages](#packages) +- [Need Help or Have Questions?](#need-help-or-have-questions) +- [Contributing](#contributing) +- [Playground](#playground) +- [License](#license) + +## About + +This is a mono-repository containing Javascript software developer tools that facilitate the interaction with [Safe Smart Accounts](https://github.com/safe-global/safe-smart-account) and [services](https://github.com/safe-global/safe-transaction-service). + +## Documentation + +Visit [our documentation site](https://docs.safe.global/sdk/overview) to start developing using our SDK. ## Guides | Title | Description | | ------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [Integrating the Safe Core SDK](https://github.com/safe-global/safe-core-sdk/blob/main/guides/integrating-the-safe-core-sdk.md) | This guide shows how to use the [Protocol Kit](https://github.com/safe-global/safe-core-sdk/tree/main/packages/protocol-kit) and [API Kit](https://github.com/safe-global/safe-core-sdk/tree/main/packages/api-kit). | +| [Integrating the Safe{Core} SDK](https://github.com/safe-global/safe-core-sdk/blob/main/guides/integrating-the-safe-core-sdk.md) | This guide shows how to use the [Protocol Kit](https://github.com/safe-global/safe-core-sdk/tree/main/packages/protocol-kit) and [API Kit](https://github.com/safe-global/safe-core-sdk/tree/main/packages/api-kit). | ## Packages @@ -17,10 +34,22 @@ Software developer tools that facilitate the interaction with the Safe [contract | [api-kit](https://github.com/safe-global/safe-core-sdk/tree/main/packages/api-kit) | [![NPM Version](https://badge.fury.io/js/%40safe-global%2Fapi-kit.svg)](https://badge.fury.io/js/%40safe-global%2Fapi-kit) | [Safe Transaction Service API](https://github.com/safe-global/safe-transaction-service) client library | | [auth-kit](https://github.com/safe-global/safe-core-sdk/tree/main/packages/auth-kit) | [![NPM Version](https://badge.fury.io/js/%40safe-global%2Fauth-kit.svg)](https://badge.fury.io/js/%40safe-global%2Fauth-kit) | Typescript library to create an Ethereum address and authenticating a blockchain account using an email address, social media account, or traditional crypto wallets like Metamask | | [onramp-kit](https://github.com/safe-global/safe-core-sdk/tree/main/packages/onramp-kit) | [![NPM Version](https://badge.fury.io/js/%40safe-global%2Fonramp-kit.svg)](https://badge.fury.io/js/%40safe-global%2Fonramp-kit) | Typescript library that allows users to buy cryptocurrencies using a credit card and other payment options | -| [protocol-kit](https://github.com/safe-global/safe-core-sdk/tree/main/packages/protocol-kit) | [![NPM Version](https://badge.fury.io/js/%40safe-global%2Fprotocol-kit.svg)](https://badge.fury.io/js/%40safe-global%2Fprotocol-kit) | TypeScript library that facilitates the interaction with the [Safe contracts](https://github.com/safe-global/safe-contracts) | -| [relay-kit](https://github.com/safe-global/safe-core-sdk/tree/main/packages/relay-kit) | ​​​[​![NPM Version](https://badge.fury.io/js/%40safe-global%2Frelay-kit.svg)​](https://badge.fury.io/js/%40safe-global%2Frelay-kit)​ | Library to abstract transaction fees payment (gas fees), allowing the use of native tokens or ERC-20​​ | +| [protocol-kit](https://github.com/safe-global/safe-core-sdk/tree/main/packages/protocol-kit) | [![NPM Version](https://badge.fury.io/js/%40safe-global%2Fprotocol-kit.svg)](https://badge.fury.io/js/%40safe-global%2Fprotocol-kit) | TypeScript library that facilitates the interaction with [Safe Smart Accounts](https://github.com/safe-global/safe-smart-account) | +| [relay-kit](https://github.com/safe-global/safe-core-sdk/tree/main/packages/relay-kit) | ​​​[​![NPM Version](https://badge.fury.io/js/%40safe-global%2Frelay-kit.svg)​](https://badge.fury.io/js/%40safe-global%2Frelay-kit)​ | Library that lets users to pay transaction fees (gas fees) using the native blockchain token or ERC-20 tokens.​This kit enables the use of ERC-4337 with Safe | | [safe-core-sdk-types](https://github.com/safe-global/safe-core-sdk/tree/main/packages/safe-core-sdk-types) | [![NPM Version](https://badge.fury.io/js/%40safe-global%2Fsafe-core-sdk-types.svg)](https://badge.fury.io/js/%40safe-global%2Fsafe-core-sdk-types) | Common types extracted from the [Safe Core SDK](https://github.com/safe-global/safe-core-sdk/tree/main/packages) packages | +## Need Help or Have Questions? + +If you have any doubts, questions, or need assistance, feel free to reach out! [Here you will find how to get support.](https://github.com/safe-global/safe-core-sdk/tree/main/SUPPORT.md) + +## Contributing + +If you are interested in contributing, please read the [Contributing Guidelines](https://github.com/safe-global/safe-core-sdk/tree/main/CONTRIBUTING.md) **before opening an issue or submitting a pull request**. + ## Playground -This project includes a [playground](https://github.com/safe-global/safe-core-sdk/tree/main/playground/README.md) with a few scripts that can be used as a starting point to use the Safe Core SDK. +This project includes a [playground](https://github.com/safe-global/safe-core-sdk/tree/main/playground/README.md) with a few scripts that can be used as a starting point to use the Safe{Core} SDK. + +## License + +This library is released under [MIT](https://github.com/safe-global/safe-core-sdk/tree/main/LICENSE.md). diff --git a/SUPPORT.md b/SUPPORT.md new file mode 100644 index 000000000..e09b4cadf --- /dev/null +++ b/SUPPORT.md @@ -0,0 +1,23 @@ +# Support Guidelines + +We appreciate your interest in our project. If you have questions, need help, or encounter issues, please follow these guidelines: + +1. **GitHub Issues**: **Do not** use GitHub issues for general support or questions. Issues are primarily for bug reports, feature requests, and discussions related to code changes. + +2. **Stack Exchange**: For support-related questions, we recommend using [Stack Exchange with the appropriate tags](https://ethereum.stackexchange.com/questions/tagged/safe-core). The **safe-core** tag should always be included. Many community members and experts monitor Stack Exchange and can provide timely assistance. + +3. **Search First**: Before posting a new question, search existing issues and Stack Exchange to see if your question has already been answered. You might find a solution without waiting for a response. + +4. **Be Specific**: When asking for help, provide as much context as possible. Include relevant details such as error messages, steps to reproduce, testing addresses, and the version of our project packages you're using. + +5. **Be Respectful**: Treat others with kindness and respect. We're all here to learn and help each other. + +## Getting Help + +If you need assistance, follow these steps: + +1. **Documentation**: Refer to our [project's documentation](https://docs.safe.global/sdk/overview) for usage instructions, FAQs, and troubleshooting tips. + +2. **Stack Exchange**: Search for existing answers or ask a new question on Stack Exchange. Use relevant tags as **safe-core**. + +Remember that GitHub issues are not the right place for general support. Let's keep our issue tracker focused on improving the project! 😊 diff --git a/guides/README.md b/guides/README.md index cf7ae92fc..707c9a400 100644 --- a/guides/README.md +++ b/guides/README.md @@ -6,7 +6,7 @@ Read about the basics of Safe and how it compares to other solutions [here](http ## Safe Core SDK -The [Safe Core SDK](https://github.com/safe-global/safe-core-sdk) is a monorepo that contains software developer tools that allows interaction with the [Safe contracts](https://github.com/safe-global/safe-contracts) and the [Safe Transaction Service](https://github.com/safe-global/safe-transaction-service). +The [Safe Core SDK](https://github.com/safe-global/safe-core-sdk) is a monorepo that contains software developer tools that allows interaction with [Safe Smart Accounts](https://github.com/safe-global/safe-smart-account) and the [Safe Transaction Service](https://github.com/safe-global/safe-transaction-service). In this guide we will use the following packages to deploy new Safes, create transactions, collect off-chain signatures and execute transactions: * **safe-core-sdk-types** @@ -22,7 +22,7 @@ In this guide we will use the following packages to deploy new Safes, create tra - Approve Safe transactions on-chain - Execute Safe transactions once they have the required confirmations - Check the complete [API reference](/packages/protocol-kit#api-reference) for more details. + Check the complete [API reference](https://docs.safe.global/sdk/protocol-kit/reference) for more details. * **api-kit** @@ -33,7 +33,7 @@ In this guide we will use the following packages to deploy new Safes, create tra - Get the transaction history of a Safe (and filter by pending, incoming, multisig transactions, etc.) - Get balances, list of tokens, etc. - Check the complete [API reference](/packages/api-kit#api-reference) for more details. + Check the complete [API reference](https://docs.safe.global/sdk/api-kit/reference) for more details. ## Prerequisites diff --git a/guides/integrating-the-safe-core-sdk.md b/guides/integrating-the-safe-core-sdk.md index 75f350843..d02e28c10 100644 --- a/guides/integrating-the-safe-core-sdk.md +++ b/guides/integrating-the-safe-core-sdk.md @@ -24,16 +24,14 @@ To integrate the [Safe Core SDK](https://github.com/safe-global/safe-core-sdk) i ## 2. Initialize the SDK’s -### Instantiate an EthAdapter +### Select your Ethereum `provider` and `signer` -First of all, we need to create an `EthAdapter`, which contains all the required utilities for the SDKs to interact with the blockchain. It acts as a wrapper for [web3.js](https://web3js.readthedocs.io/) or [ethers.js](https://docs.ethers.org/v6/) Ethereum libraries. +To use our kits, you need to provide an Ethereum provider and a signer. The provider is the connection to the Ethereum network, while the signer is an account that will sign the transactions (a Safe owner). When using an injected provider like MetaMask, the signer is the account selected in the wallet. -Depending on the library used by the Dapp, there are two options: +In the examples below, you can see `provider` and `signer` properties, which represent: -- [Create an `EthersAdapter` instance](https://github.com/safe-global/safe-core-sdk/tree/main/packages/protocol-kit/src/adapters/ethers) -- [Create a `Web3Adapter` instance](https://github.com/safe-global/safe-core-sdk/tree/main/packages/protocol-kit/src/adapters/web3) - -Once the instance of `EthersAdapter` or `Web3Adapter` is created, it can be used in the SDK initialization. +- `provider`: You can provide an EIP-1193 compatible provider or an HTTP/WebSocket RPC URL. +- `signer`: This is an optional parameter. It should be the provider's address you want to use or a private key. If not set, it will try to fetch a connected account from the provider. ### Initialize the Safe API Kit @@ -42,13 +40,13 @@ As stated in the introduction, the [Safe API Kit](https://github.com/safe-global ```js import SafeApiKit from '@safe-global/api-kit' -const safeService = new SafeApiKit({ chainId }) +const apiKit = new SafeApiKit({ chainId }) ``` Using the `chainId` is enough for chains where Safe runs a Transaction Service. For those chains where Safe doesn't run a service, use the `txServiceUrl` parameter to set the custom service endpoint. ```js -const safeService = new SafeApiKit({ +const apiKit = new SafeApiKit({ chainId, txServiceUrl: 'https://txServiceUrl.com' }) @@ -59,9 +57,9 @@ const safeService = new SafeApiKit({ ```js import Safe, { SafeFactory } from '@safe-global/protocol-kit' -const safeFactory = await SafeFactory.create({ ethAdapter }) +const safeFactory = await SafeFactory.init({ provider, signer }) -const safeSdk = await Safe.create({ ethAdapter, safeAddress }) +const protocolKit = await Safe.init({ provider, signer, safeAddress }) ``` There are two versions of the Safe contracts: [Safe.sol](https://github.com/safe-global/safe-contracts/blob/v1.4.1/contracts/Safe.sol) that does not trigger events in order to save gas and [SafeL2.sol](https://github.com/safe-global/safe-contracts/blob/v1.4.1/contracts/SafeL2.sol) that does, which is more appropriate for L2 networks. @@ -69,17 +67,18 @@ There are two versions of the Safe contracts: [Safe.sol](https://github.com/safe By default `Safe.sol` will be only used on Ethereum Mainnet. For the rest of the networks where the Safe contracts are already deployed, the `SafeL2.sol` contract will be used unless you add the property `isL1SafeSingleton` to force the use of the `Safe.sol` contract. ```js -const safeFactory = await SafeFactory.create({ ethAdapter, isL1SafeSingleton: true }) +const safeFactory = await SafeFactory.init({ provider, signer, isL1SafeSingleton: true }) -const safeSdk = await Safe.create({ ethAdapter, safeAddress, isL1SafeSingleton: true }) +const protocolKit = await Safe.init({ provider, signer, safeAddress, isL1SafeSingleton: true }) ``` If the Safe contracts are not deployed to your current network, the property `contractNetworks` will be required to point to the addresses of the Safe contracts previously deployed by you. ```js -import { ContractNetworksConfig } from '@safe-global/protocol-kit' +import { ContractNetworksConfig, SafeProvider } from '@safe-global/protocol-kit' -const chainId = await ethAdapter.getChainId() +const safeProvider = new SafeProvider({ provider, signer }) +const chainId = await safeProvider.getChainId() const contractNetworks: ContractNetworksConfig = { [chainId]: { safeSingletonAddress: '', @@ -101,16 +100,16 @@ const contractNetworks: ContractNetworksConfig = { } } -const safeFactory = await SafeFactory.create({ ethAdapter, contractNetworks }) +const safeFactory = await SafeFactory.init({ provider, signer, contractNetworks }) -const safeSdk = await Safe.create({ ethAdapter, safeAddress, contractNetworks }) +const protocolKit = await Safe.init({ provider, signer, safeAddress, contractNetworks }) ``` The `SafeFactory` constructor also accepts the property `safeVersion` to specify the Safe contract version that will be deployed. This string can take the values `1.0.0`, `1.1.1`, `1.2.0`, `1.3.0` or `1.4.1`. If not specified, the `DEFAULT_SAFE_VERSION` value will be used. ```js const safeVersion = 'X.Y.Z' -const safeFactory = await SafeFactory.create({ ethAdapter, safeVersion }) +const safeFactory = await SafeFactory.init({ provider, signer, safeVersion }) ``` ## 3. Deploy a new Safe @@ -127,7 +126,7 @@ const safeAccountConfig: SafeAccountConfig = { threshold: 2, // ... (optional params) } -const safeSdk = await safeFactory.deploySafe({ safeAccountConfig }) +const protocolKit = await safeFactory.deploySafe({ safeAccountConfig }) ``` Calling the method `deploySafe` will deploy the desired Safe and return a Protocol Kit initialized instance ready to be used. Check the [API Reference](https://github.com/safe-global/safe-core-sdk/tree/main/packages/protocol-kit#deploysafe) for more details on additional configuration parameters and callbacks. @@ -140,42 +139,42 @@ This method takes an array of `MetaTransactionData` objects that represent the i When the array contains only one transaction, it is not wrapped in the MultiSend. - ```js - import { SafeTransactionOptionalProps } from '@safe-global/protocol-kit' - import { MetaTransactionData } from '@safe-global/safe-core-sdk-types' - - const transactions: MetaTransactionData[] = [ - { - to, - data, - value, - operation - }, - { - to, - data, - value, - operation - } - // ... - ] - - const options: SafeTransactionOptionalProps = { - safeTxGas, // Optional - baseGas, // Optional - gasPrice, // Optional - gasToken, // Optional - refundReceiver, // Optional - nonce // Optional +```js +import { SafeTransactionOptionalProps } from '@safe-global/protocol-kit' +import { MetaTransactionData } from '@safe-global/safe-core-sdk-types' + +const transactions: MetaTransactionData[] = [ + { + to, + data, + value, + operation + }, + { + to, + data, + value, + operation } + // ... +] + +const options: SafeTransactionOptionalProps = { + safeTxGas, // Optional + baseGas, // Optional + gasPrice, // Optional + gasToken, // Optional + refundReceiver, // Optional + nonce // Optional +} - const safeTransaction = await safeSdk.createTransaction({ transactions, options }) - ``` +const safeTransaction = await protocolKit.createTransaction({ transactions, options }) +``` We can specify the `nonce` of our Safe transaction as long as it is not lower than the current Safe nonce. If multiple transactions are created but not executed they will share the same `nonce` if no `nonce` is specified, validating the first executed transaction and invalidating all the rest. We can prevent this by calling the method `getNextNonce` from the Safe API Kit instance. This method takes all queued/pending transactions into account when calculating the next nonce, creating a unique one for all different transactions. ```js -const nonce = await safeService.getNextNonce(safeAddress) +const nonce = await apiKit.getNextNonce(safeAddress) ``` ## 5. Propose the transaction to the service @@ -190,9 +189,9 @@ Once we have the Safe transaction object we can share it with the other owners o - `origin`: Optional string that allows to provide more information about the app proposing the transaction. ```js -const safeTxHash = await safeSdk.getTransactionHash(safeTransaction) -const senderSignature = await safeSdk.signHash(safeTxHash) -await safeService.proposeTransaction({ +const safeTxHash = await protocolKit.getTransactionHash(safeTransaction) +const senderSignature = await protocolKit.signHash(safeTxHash) +await apiKit.proposeTransaction({ safeAddress, safeTransactionData: safeTransaction.data, safeTxHash, @@ -209,13 +208,13 @@ The transaction is then available on the Safe Transaction Service and the owners Get a list of pending transactions: ```js -const pendingTxs = await safeService.getPendingTransactions(safeAddress) +const pendingTxs = await apiKit.getPendingTransactions(safeAddress) ``` Get a specific transaction given its Safe transaction hash: ```js -const tx = await safeService.getTransaction(safeTxHash) +const tx = await apiKit.getTransaction(safeTxHash) ``` The retrieved transaction will have this type: @@ -271,8 +270,8 @@ The owners of the Safe can now sign the transaction obtained from the Safe Trans // transaction: SafeMultisigTransactionResponse const hash = transaction.safeTxHash -let signature = await safeSdk.signHash(hash) -await safeService.confirmTransaction(hash, signature.data) +let signature = await protocolKit.signHash(hash) +await apiKit.confirmTransaction(hash, signature.data) ``` ## 8. Execute the transaction @@ -282,15 +281,15 @@ Once there are enough confirmations in the service the transaction is ready to b The method `executeTransaction` accepts an instance of the class `SafeTransaction` so the transaction needs to be transformed from the type `SafeMultisigTransactionResponse`. ```js -const safeTransaction = await safeService.getTransaction(...) -const executeTxResponse = await safeSdk.executeTransaction(safeTransaction) +const safeTransaction = await apiKit.getTransaction(...) +const executeTxResponse = await protocolKit.executeTransaction(safeTransaction) const receipt = executeTxResponse.transactionResponse && (await executeTxResponse.transactionResponse.wait()) ``` Optionally, the `isValidTransaction` method, that returns a boolean value, could be called right before the `executeTransaction` method to check if the transaction will be executed successfully or not. ```js -const isValidTx = await safeSdk.isValidTransaction(safeTransaction) +const isValidTx = await protocolKit.isValidTransaction(safeTransaction) ``` ## 9. Interface checks diff --git a/package.json b/package.json index 60111881e..a482596b3 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,6 @@ "build": "lerna run build --stream", "lint:check": "eslint './packages/**/*.{js,jsx,ts,tsx}'", "test": "FORCE_COLOR=1 lerna run test --stream", - "test:ci": "FORCE_COLOR=1 lerna run test:ci --stream", "play": "ts-node ./playground/config/run.ts", "format": "lerna run format && prettier --write \"playground/**/*.ts\"", "prepare": "husky install" @@ -20,20 +19,20 @@ "author": "Safe (https://safe.global)", "license": "MIT", "devDependencies": { - "@types/jest": "^29.5.11", + "@types/jest": "^29.5.12", "@types/node": "^18.18.8", "@typescript-eslint/eslint-plugin": "^6.15.0", "@typescript-eslint/parser": "^6.15.0", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", - "eslint-plugin-prettier": "^5.0.1", + "eslint-plugin-prettier": "^5.1.3", "husky": "^8.0.3", "jest": "^29.7.0", "lerna": "^7.4.2", "lint-staged": "^14.0.1", - "prettier": "^3.1.1", + "prettier": "^3.2.5", "rimraf": "^3.0.2", - "ts-jest": "^29.1.1", + "ts-jest": "^29.1.2", "ts-node": "^10.9.2", "tsc-alias": "^1.8.8", "typescript": "^5.3.3" diff --git a/packages/account-abstraction-kit/README.md b/packages/account-abstraction-kit/README.md index 6daf9d034..63b7f496f 100644 --- a/packages/account-abstraction-kit/README.md +++ b/packages/account-abstraction-kit/README.md @@ -9,36 +9,27 @@ Description TBD ## Table of contents - [Installation](#installation) -- [Build](#build) -- [Initialization](#initialization) +- [Need Help or Have Questions?](#need-help-or-have-questions) +- [Contributing](#contributing) - [License](#license) -## Installation +## Installation Install the package with yarn or npm: ```bash -yarn install -npm install +yarn add @safe-global/account-abstraction-kit-poc +npm install @safe-global/account-abstraction-kit-poc ``` -## Build +## Need Help or Have Questions? -Build the package with yarn or npm: +If you have any doubts, questions, or need assistance, feel free to reach out! [Here you will find how to get support.](https://github.com/safe-global/safe-core-sdk/tree/main/SUPPORT.md) -```bash -yarn build -npm run build -``` - -## Initialization +## Contributing -Initialization TBD - -```js - -``` +Please read our [contribution guidelines](https://github.com/safe-global/safe-core-sdk/tree/main/CONTRIBUTING.md) before submitting any changes. We appreciate your help! 🙌 ## License -This library is [released under MIT](https://github.com/safe-global/account-abstraction-sdk/blob/main/LICENSE.md). +This library is [released under MIT](https://github.com/safe-global/safe-core-sdk/blob/main/LICENSE.md). diff --git a/packages/account-abstraction-kit/jest.config.js b/packages/account-abstraction-kit/jest.config.js index 44aaa1c09..069f7c520 100644 --- a/packages/account-abstraction-kit/jest.config.js +++ b/packages/account-abstraction-kit/jest.config.js @@ -5,7 +5,6 @@ const config = { '^.+\\.ts?$': 'ts-jest' }, moduleNameMapper: { - '^@safe-global/protocol-kit/typechain/(.*)$': '/../protocol-kit/typechain/$1', '^@safe-global/protocol-kit/(.*)$': '/../protocol-kit/src/$1', '^@safe-global/relay-kit/(.*)$': '/../relay-kit/src/$1', '^@safe-global/account-abstraction-kit-poc/(.*)$': '/src/$1' diff --git a/packages/account-abstraction-kit/package.json b/packages/account-abstraction-kit/package.json index 53119ba28..f059602be 100644 --- a/packages/account-abstraction-kit/package.json +++ b/packages/account-abstraction-kit/package.json @@ -1,6 +1,6 @@ { "name": "@safe-global/account-abstraction-kit-poc", - "version": "2.1.1", + "version": "3.0.0-alpha.0", "description": "Safe Account Abstraction Kit PoC", "main": "dist/src/index.js", "typings": "dist/src/index.d.ts", @@ -34,8 +34,8 @@ "access": "public" }, "dependencies": { - "@safe-global/protocol-kit": "^3.1.1", - "@safe-global/relay-kit": "^2.1.1", - "@safe-global/safe-core-sdk-types": "^4.1.1" + "@safe-global/protocol-kit": "^4.0.0-alpha.0", + "@safe-global/relay-kit": "^3.0.0-alpha.0", + "@safe-global/safe-core-sdk-types": "^5.0.0-alpha.0" } } diff --git a/packages/account-abstraction-kit/src/AccountAbstraction.test.ts b/packages/account-abstraction-kit/src/AccountAbstraction.test.ts index a33980e39..512e128ec 100644 --- a/packages/account-abstraction-kit/src/AccountAbstraction.test.ts +++ b/packages/account-abstraction-kit/src/AccountAbstraction.test.ts @@ -1,6 +1,6 @@ -import Safe, { predictSafeAddress } from '@safe-global/protocol-kit' +import Safe, { predictSafeAddress, SafeProvider } from '@safe-global/protocol-kit' import { GelatoRelayPack } from '@safe-global/relay-kit' -import { EthAdapter, SafeTransaction } from '@safe-global/safe-core-sdk-types' +import { SafeTransaction } from '@safe-global/safe-core-sdk-types' import AccountAbstraction from './AccountAbstraction' jest.mock('@safe-global/protocol-kit') @@ -9,68 +9,73 @@ jest.mock('@safe-global/relay-kit') const GelatoRelayPackMock = GelatoRelayPack as jest.MockedClass const predictSafeAddressMock = predictSafeAddress as jest.MockedFunction const SafeMock = Safe as jest.MockedClass +const SafeProviderMock = SafeProvider as jest.MockedClass describe('AccountAbstraction', () => { - const ethersAdapter = { - getSignerAddress: jest.fn(), - isContractDeployed: jest.fn(), - getChainId: jest.fn() + const provider = { + request: jest.fn() } + const signerAddress = '0xSignerAddress' const predictSafeAddress = '0xPredictSafeAddressMock' beforeEach(() => { jest.clearAllMocks() - ethersAdapter.getSignerAddress.mockResolvedValue(signerAddress) predictSafeAddressMock.mockResolvedValue(predictSafeAddress) + SafeProviderMock.prototype.getSignerAddress.mockResolvedValue(signerAddress) }) describe('init', () => { - const accountAbstraction = new AccountAbstraction(ethersAdapter as unknown as EthAdapter) + const accountAbstraction = new AccountAbstraction({ provider, signer: signerAddress }) it('should initialize a Safe instance with its address if contract is deployed already', async () => { - ethersAdapter.isContractDeployed.mockResolvedValueOnce(true) + SafeProviderMock.prototype.isContractDeployed.mockResolvedValueOnce(true) await accountAbstraction.init() - expect(ethersAdapter.getSignerAddress).toHaveBeenCalledTimes(1) + expect(SafeProviderMock.prototype.getSignerAddress).toHaveBeenCalledTimes(1) expect(predictSafeAddressMock).toHaveBeenCalledTimes(1) - expect(predictSafeAddressMock).toHaveBeenCalledWith({ - ethAdapter: ethersAdapter, - safeAccountConfig: { owners: ['0xSignerAddress'], threshold: 1 } - }) - expect(SafeMock.create).toHaveBeenCalledTimes(1) - expect(SafeMock.create).toHaveBeenCalledWith({ - ethAdapter: ethersAdapter, - safeAddress: predictSafeAddress - }) + expect(predictSafeAddressMock).toHaveBeenCalledWith( + expect.objectContaining({ + safeAccountConfig: { owners: ['0xSignerAddress'], threshold: 1 } + }) + ) + expect(SafeMock.init).toHaveBeenCalledTimes(1) + expect(SafeMock.init).toHaveBeenCalledWith( + expect.objectContaining({ + safeAddress: predictSafeAddress + }) + ) }) it('should initialize a Safe instance with a config if contract is NOT deployed yet', async () => { - ethersAdapter.isContractDeployed.mockResolvedValueOnce(false) + SafeProviderMock.prototype.isContractDeployed.mockResolvedValueOnce(false) await accountAbstraction.init() - expect(ethersAdapter.getSignerAddress).toHaveBeenCalledTimes(1) + expect(SafeProviderMock.prototype.getSignerAddress).toHaveBeenCalledTimes(1) expect(predictSafeAddressMock).toHaveBeenCalledTimes(1) - expect(predictSafeAddressMock).toHaveBeenCalledWith({ - ethAdapter: ethersAdapter, - safeAccountConfig: { owners: ['0xSignerAddress'], threshold: 1 } - }) - expect(SafeMock.create).toHaveBeenCalledTimes(1) - expect(SafeMock.create).toHaveBeenCalledWith({ - ethAdapter: ethersAdapter, - predictedSafe: { safeAccountConfig: { owners: ['0xSignerAddress'], threshold: 1 } } - }) + expect(predictSafeAddressMock).toHaveBeenCalledWith( + expect.objectContaining({ + safeAccountConfig: { owners: ['0xSignerAddress'], threshold: 1 } + }) + ) + expect(SafeMock.init).toHaveBeenCalledTimes(1) + expect(SafeMock.init).toHaveBeenCalledWith( + expect.objectContaining({ + predictedSafe: { safeAccountConfig: { owners: ['0xSignerAddress'], threshold: 1 } } + }) + ) }) it('should throw an error if the provider has not a signer', async () => { - ethersAdapter.getSignerAddress.mockResolvedValueOnce(undefined) + SafeProviderMock.prototype.getSignerAddress.mockResolvedValueOnce(undefined) expect(accountAbstraction.init()).rejects.toThrow( - `There's no signer in the provided EthAdapter` + `There's no signer available with the provided config (provider, signer)` ) - expect(SafeMock.create).not.toHaveBeenCalled() + + expect(SafeMock.init).not.toHaveBeenCalled() }) }) @@ -83,7 +88,7 @@ describe('AccountAbstraction', () => { } const initAccountAbstraction = async () => { - const accountAbstraction = new AccountAbstraction(ethersAdapter as unknown as EthAdapter) + const accountAbstraction = new AccountAbstraction({ provider }) await accountAbstraction.init() return accountAbstraction } @@ -92,7 +97,7 @@ describe('AccountAbstraction', () => { beforeEach(async () => { jest.clearAllMocks() - SafeMock.create = () => Promise.resolve(safeInstanceMock as unknown as Safe) + SafeMock.init = () => Promise.resolve(safeInstanceMock as unknown as Safe) accountAbstraction = await initAccountAbstraction() }) @@ -107,7 +112,7 @@ describe('AccountAbstraction', () => { }) it('should not be called if the protocol-kit is not initialized', async () => { - const accountAbstraction = new AccountAbstraction(ethersAdapter as unknown as EthAdapter) + const accountAbstraction = new AccountAbstraction({ provider }) expect(accountAbstraction.protocolKit).toBe(undefined) expect(safeInstanceMock.getNonce).not.toHaveBeenCalled() }) @@ -124,7 +129,7 @@ describe('AccountAbstraction', () => { }) it('should not be called if the protocol-kit is not initialized', async () => { - const accountAbstraction = new AccountAbstraction(ethersAdapter as unknown as EthAdapter) + const accountAbstraction = new AccountAbstraction({ provider }) expect(accountAbstraction.protocolKit).toBe(undefined) expect(safeInstanceMock.getAddress).not.toHaveBeenCalled() }) @@ -139,7 +144,7 @@ describe('AccountAbstraction', () => { }) it('should not be called if the protocol-kit is not initialized', async () => { - const accountAbstraction = new AccountAbstraction(ethersAdapter as unknown as EthAdapter) + const accountAbstraction = new AccountAbstraction({ provider }) expect(accountAbstraction.protocolKit).toBe(undefined) expect(safeInstanceMock.isSafeDeployed).not.toHaveBeenCalled() }) @@ -181,7 +186,7 @@ describe('AccountAbstraction', () => { }) it('should throw if the protocol-kit is not initialized', async () => { - const accountAbstraction = new AccountAbstraction(ethersAdapter as unknown as EthAdapter) + const accountAbstraction = new AccountAbstraction({ provider }) accountAbstraction.setRelayKit( new GelatoRelayPack({ protocolKit: accountAbstraction.protocolKit }) ) @@ -196,7 +201,7 @@ describe('AccountAbstraction', () => { }) it('should throw if relay-kit is not initialized', async () => { - const accountAbstraction = new AccountAbstraction(ethersAdapter as unknown as EthAdapter) + const accountAbstraction = new AccountAbstraction({ provider }) await accountAbstraction.init() expect(accountAbstraction.relayTransaction(transactionsMock, optionsMock)).rejects.toThrow( diff --git a/packages/account-abstraction-kit/src/AccountAbstraction.ts b/packages/account-abstraction-kit/src/AccountAbstraction.ts index f8ec011ee..dbde9a422 100644 --- a/packages/account-abstraction-kit/src/AccountAbstraction.ts +++ b/packages/account-abstraction-kit/src/AccountAbstraction.ts @@ -1,9 +1,13 @@ -import Safe, { SafeAccountConfig, predictSafeAddress } from '@safe-global/protocol-kit' +import Safe, { + SafeAccountConfig, + predictSafeAddress, + SafeProviderConfig, + SafeProvider +} from '@safe-global/protocol-kit' import { RelayKitBasePack } from '@safe-global/relay-kit' import { MetaTransactionData, MetaTransactionOptions, - EthAdapter, SafeTransaction } from '@safe-global/safe-core-sdk-types' @@ -14,21 +18,24 @@ import { class AccountAbstraction { protocolKit!: Safe relayKit?: RelayKitBasePack - #ethAdapter: EthAdapter + #provider: SafeProviderConfig['provider'] + #signer?: SafeProviderConfig['signer'] /** * @constructor - * @param ethAdapter The EthAdapter instance to be used by the Account Abstraction (e.g. EthersAdapter) + * @param config The SafeProviderConfig */ - constructor(ethAdapter: EthAdapter) { - this.#ethAdapter = ethAdapter + constructor({ provider, signer }: SafeProviderConfig) { + this.#provider = provider + this.#signer = signer } #initializeProtocolKit = async () => { - const signer = await this.#ethAdapter.getSignerAddress() + const safeProvider = new SafeProvider({ provider: this.#provider, signer: this.#signer }) + const signer = await safeProvider.getSignerAddress() if (!signer) { - throw new Error("There's no signer in the provided EthAdapter") + throw new Error("There's no signer available with the provided config (provider, signer)") } const owners = [signer] @@ -40,18 +47,23 @@ class AccountAbstraction { } const safeAddress = await predictSafeAddress({ - ethAdapter: this.#ethAdapter, - chainId: await this.#ethAdapter.getChainId(), + safeProvider, + chainId: await safeProvider.getChainId(), safeAccountConfig }) - const isSafeDeployed = await this.#ethAdapter.isContractDeployed(safeAddress) + const isSafeDeployed = await safeProvider.isContractDeployed(safeAddress) if (isSafeDeployed) { - this.protocolKit = await Safe.create({ ethAdapter: this.#ethAdapter, safeAddress }) + this.protocolKit = await Safe.init({ + provider: this.#provider, + signer: this.#signer, + safeAddress + }) } else { - this.protocolKit = await Safe.create({ - ethAdapter: this.#ethAdapter, + this.protocolKit = await Safe.init({ + provider: this.#provider, + signer: this.#signer, predictedSafe: { safeAccountConfig } }) } diff --git a/packages/api-kit/LICENSE.md b/packages/api-kit/LICENSE.md index 310e6e37c..0e923d187 100644 --- a/packages/api-kit/LICENSE.md +++ b/packages/api-kit/LICENSE.md @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021-2023 Safe Ecosystem Foundation +Copyright (c) 2021-2024 Safe Ecosystem Foundation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/packages/api-kit/README.md b/packages/api-kit/README.md index ee6e8a97c..f64afb150 100644 --- a/packages/api-kit/README.md +++ b/packages/api-kit/README.md @@ -8,306 +8,46 @@ Software development kit that facilitates the interaction with the [Safe Transac ## Table of contents +- [Documentation](#documentation) - [Installation](#installation) -- [Build](#build) -- [Tests](#tests) -- [Initialization](#initialization) -- [API Reference](#api-reference) +- [Quick Start](#quick-start) +- [Need Help or Have Questions?](#need-help-or-have-questions) +- [Contributing](#contributing) - [License](#license) -- [Contributors](#contributors) -## Installation +## Documentation -Install the package with yarn or npm: - -```bash -yarn install -npm install -``` - -## Build - -Build the package with yarn or npm: - -```bash -yarn build -npm run build -``` +Head to the [API Kit docs](https://docs.safe.global/sdk/api-kit) to learn more about how to use this SDK. -## Tests +## Installation -Create a `.env` file with environment variables. You can use the `.env.example` file as a reference. - -Test the package with yarn or npm: +Install the package with yarn or npm: ```bash -yarn test -npm run test +yarn add @safe-global/api-kit +npm install @safe-global/api-kit ``` -## Initialization - -### Initialize the SafeApiKit +## Quick Start ```js import SafeApiKit from '@safe-global/api-kit' -const safeService = new SafeApiKit({ +const apiKit = new SafeApiKit({ chainId: 1n, // Optional. txServiceUrl must be used to set a custom service. For example on chains where Safe doesn't run services. txServiceUrl: 'https://safe-transaction-mainnet.safe.global' }) ``` -## API Reference - -### getServiceInfo - -Returns the information and configuration of the service. - -```js -const serviceInfo: SafeServiceInfoResponse = await safeService.getServiceInfo() -``` - -### getServiceSingletonsInfo - -Returns the list of Safe singleton copies. - -```js -const singletons: SafeSingletonResponse = await safeService.getServiceSingletonsInfo() -``` - -### decodeData - -Decodes the specified Safe transaction data. - -```js -const decodedData = await safeService.decodeData(data) -``` - -### getSafesByOwner - -Returns the list of Safes where the address provided is an owner. - -```js -const safes: OwnerResponse = await safeService.getSafesByOwner(ownerAddress) -``` - -### getSafesByModule - -Returns the list of Safes where the module address provided is enabled. - -```js -const safes: ModulesResponse = await getSafesByModule(moduleAddress) -``` - -### getTransaction - -Returns all the information of a Safe transaction. - -```js -const tx: SafeMultisigTransactionResponse = await safeService.getTransaction(safeTxHash) -``` - -### getTransactionConfirmations - -Returns the list of confirmations for a given a Safe transaction. - -```js -const confirmations: SafeMultisigConfirmationListResponse = - await safeService.getTransactionConfirmations(safeTxHash) -``` - -### confirmTransaction - -Adds a confirmation for a Safe transaction. - -```js -const signature: SignatureResponse = await safeService.confirmTransaction(safeTxHash, signature) -``` - -### getSafeInfo - -Returns the information and configuration of the provided Safe address. - -```js -const safeInfo: SafeInfoResponse = await safeService.getSafeInfo(safeAddress) -``` - -### getSafeDelegates - -Returns the list of delegates for a given Safe address. - -```js -const delegateConfig: GetSafeDelegateProps = { - safeAddress, // Optional - delegateAddress, // Optional - delegatorAddress, // Optional - label, // Optional - limit, // Optional - offset // Optional -} -const delegates: SafeDelegateListResponse = await safeService.getSafeDelegates(delegateConfig) -``` - -### addSafeDelegate - -Adds a new delegate for a given Safe address. - -```js -const delegateConfig: AddSafeDelegateProps = { - safeAddress, // Optional - delegateAddress, - delegatorAddress, - label, - signer -} -await safeService.addSafeDelegate(delegateConfig) -``` - -### removeSafeDelegate - -Removes a delegate for a given Safe address. - -```js -const delegateConfig: DeleteSafeDelegateProps = { - delegateAddress, - delegatorAddress, - signer -} -await safeService.removeSafeDelegate(delegateConfig) -``` - -### getSafeCreationInfo - -Returns the creation information of a Safe. - -```js -const safeCreationInfo: SafeCreationInfoResponse = await safeService.getSafeCreationInfo( - safeAddress -) -``` - -### estimateSafeTransaction - -Estimates the safeTxGas for a given Safe multi-signature transaction. - -```js -const estimateTx: SafeMultisigTransactionEstimateResponse = - await safeService.estimateSafeTransaction(safeAddress, safeTransaction) -``` - -### proposeTransaction - -Creates a new multi-signature transaction and stores it in the Safe Transaction Service. - -```js -const transactionConfig: ProposeTransactionProps = { - safeAddress, - safeTxHash, - safeTransactionData, - senderAddress, - senderSignature, - origin -} -await safeService.proposeTransaction(transactionConfig) -``` - -### getIncomingTransactions - -Returns the history of incoming transactions of a Safe account. - -```js -const incomingTxs: TransferListResponse = await safeService.getIncomingTransactions(safeAddress) -``` - -### getModuleTransactions - -Returns the history of module transactions of a Safe account. - -```js -const moduleTxs: SafeModuleTransactionListResponse = await safeService.getModuleTransactions( - safeAddress -) -``` - -### getMultisigTransactions - -Returns the history of multi-signature transactions of a Safe account. - -```js -const multisigTxs: SafeMultisigTransactionListResponse = await safeService.getMultisigTransactions( - safeAddress -) -``` - -### getPendingTransactions - -Returns the list of multi-signature transactions that are waiting for the confirmation of the Safe owners. +## Need Help or Have Questions? -```js -const pendingTxs: SafeMultisigTransactionListResponse = await safeService.getPendingTransactions( - safeAddress -) -``` - -```js -const pendingTxs: SafeMultisigTransactionListResponse = await safeService.getPendingTransactions( - safeAddress, - currentNonce -) -``` - -### getAllTransactions - -Returns a list of transactions for a Safe. The list has different structures depending on the transaction type. - -```js -const allTxs: SafeMultisigTransactionListResponse = await safeService.getAllTransactions( - safeAddress -) -``` - -```js -const allTxsOptions: AllTransactionsOptions = { - executed, - queued, - trusted -} -const allTxs: SafeMultisigTransactionListResponse = await safeService.getAllTransactions( - safeAddress, - allTxsOptions -) -``` - -### getNextNonce - -Returns the right nonce to propose a new transaction right after the last pending transaction. - -```js -const nextNonce = await safeService.getNextNonce(safeAddress) -``` - -### getTokenList - -Returns the list of all the ERC20 tokens handled by the Safe. - -```js -const tokens: TokenInfoListResponse = await safeService.getTokenList() -``` - -### getToken - -Returns the information of a given ERC20 token. - -```js -const token: TokenInfoResponse = await safeService.getToken(tokenAddress) -``` +If you have any doubts, questions, or need assistance, feel free to reach out! [Here you will find how to get support.](https://github.com/safe-global/safe-core-sdk/tree/main/SUPPORT.md) -## License +## Contributing -This library is released under MIT. +Please read our [contribution guidelines](https://github.com/safe-global/safe-core-sdk/tree/main/CONTRIBUTING.md) before submitting any changes. We appreciate your help! 🙌 -## Contributors +## License -- Germán Martínez ([germartinez](https://github.com/germartinez)) +This library is [released under MIT](https://github.com/safe-global/safe-core-sdk/blob/main/LICENSE.md). diff --git a/packages/api-kit/hardhat.config.ts b/packages/api-kit/hardhat.config.ts index 894ebfeb3..6525853ab 100644 --- a/packages/api-kit/hardhat.config.ts +++ b/packages/api-kit/hardhat.config.ts @@ -1,5 +1,4 @@ import '@nomicfoundation/hardhat-ethers' -import '@nomiclabs/hardhat-web3' import dotenv from 'dotenv' import { HardhatUserConfig, HttpNetworkUserConfig } from 'hardhat/types' import yargs from 'yargs' @@ -41,7 +40,7 @@ const config: HardhatUserConfig = { }, sepolia: { ...sharedNetworkConfig, - url: 'https://rpc.ankr.com/eth_sepolia' + url: 'https://sepolia.gateway.tenderly.co' } }, //@ts-expect-error Type not found diff --git a/packages/api-kit/package.json b/packages/api-kit/package.json index 848edfefa..18d6a688f 100644 --- a/packages/api-kit/package.json +++ b/packages/api-kit/package.json @@ -1,6 +1,6 @@ { "name": "@safe-global/api-kit", - "version": "2.3.2", + "version": "2.3.2-alpha.0", "description": "Safe API Kit", "main": "dist/src/index.js", "typings": "dist/src/index.d.ts", @@ -13,9 +13,11 @@ "scripts": { "test:web3": "export TESTS_PATH=tests/endpoint && export ETH_LIB=web3 && nyc hardhat test", "test:ethers": "export TESTS_PATH=tests/endpoint && export ETH_LIB=ethers && nyc --reporter=lcov hardhat test", + "test:viem": "export TESTS_PATH=tests/endpoint && export ETH_LIB=viem && nyc hardhat test", "test": "yarn test:ethers", "test:ci:web3": "export TESTS_PATH=tests/e2e && export ETH_LIB=web3 && nyc hardhat test", "test:ci:ethers": "export TESTS_PATH=tests/e2e && export ETH_LIB=ethers && nyc --reporter=lcov hardhat test", + "test:ci:viem": "export TESTS_PATH=tests/e2e && export ETH_LIB=viem && nyc --reporter=lcov hardhat test", "test:ci": "yarn test:ci:ethers", "format:check": "prettier --check \"*/**/*.{js,json,md,ts}\"", "format": "prettier --write \"*/**/*.{js,json,md,ts}\"", @@ -37,27 +39,28 @@ "homepage": "https://github.com/safe-global/safe-core-sdk#readme", "devDependencies": { "@nomicfoundation/hardhat-ethers": "^3.0.5", - "@nomiclabs/hardhat-web3": "^2.0.0", - "@types/chai": "^4.3.11", + "@types/chai": "^4.3.16", "@types/chai-as-promised": "^7.1.8", "@types/mocha": "^10.0.6", - "@types/node-fetch": "^2.6.9", + "@types/node-fetch": "^2.6.11", "@types/sinon-chai": "^3.2.11", "@types/yargs": "^17.0.32", "chai": "^4.3.10", "chai-as-promised": "^7.1.1", "hardhat": "^2.19.3", "mocha": "^10.2.0", - "semver": "^7.5.4", + "semver": "^7.6.1", "sinon": "^14.0.2", "sinon-chai": "^3.7.0", "tsconfig-paths": "^4.2.0", + "viem": "^2.10.2", + "web3": "^4.7.0", "yargs": "^17.7.2" }, "dependencies": { - "@safe-global/protocol-kit": "^3.1.1", - "@safe-global/safe-core-sdk-types": "^4.1.1", - "ethers": "^6.7.1", + "@safe-global/protocol-kit": "^4.0.0-alpha.0", + "@safe-global/safe-core-sdk-types": "^5.0.0-alpha.0", + "ethers": "^6.12.1", "node-fetch": "^2.7.0" } } diff --git a/packages/api-kit/tests/e2e/addMessage.test.ts b/packages/api-kit/tests/e2e/addMessage.test.ts index bcfc944b2..ca1fa483a 100644 --- a/packages/api-kit/tests/e2e/addMessage.test.ts +++ b/packages/api-kit/tests/e2e/addMessage.test.ts @@ -1,14 +1,14 @@ import Safe from '@safe-global/protocol-kit' -import { EthAdapter } from '@safe-global/safe-core-sdk-types' import SafeApiKit from '@safe-global/api-kit/index' import chai from 'chai' import chaiAsPromised from 'chai-as-promised' -import { getServiceClient } from '../utils/setupServiceClient' +import { getKits } from '../utils/setupKits' chai.use(chaiAsPromised) +const PRIVATE_KEY = '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676' + let safeApiKit: SafeApiKit -let ethAdapter: EthAdapter let protocolKit: Safe const generateRandomUUID = (): string => { @@ -24,14 +24,10 @@ const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78' describe('addMessage', () => { before(async () => { - ;({ safeApiKit, ethAdapter } = await getServiceClient( - '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676' - )) - - protocolKit = await Safe.create({ - ethAdapter, - safeAddress - }) + ;({ safeApiKit, protocolKit } = await getKits({ + safeAddress, + signer: PRIVATE_KEY + })) }) it('should fail if safeAddress is empty or invalid', async () => { diff --git a/packages/api-kit/tests/e2e/addMessageSignature.test.ts b/packages/api-kit/tests/e2e/addMessageSignature.test.ts index 2a7d74581..b4b5cad94 100644 --- a/packages/api-kit/tests/e2e/addMessageSignature.test.ts +++ b/packages/api-kit/tests/e2e/addMessageSignature.test.ts @@ -5,18 +5,21 @@ import Safe, { SigningMethod, buildContractSignature } from '@safe-global/protocol-kit' -import { EthAdapter, SafeMessage } from '@safe-global/safe-core-sdk-types' +import { SafeMessage } from '@safe-global/safe-core-sdk-types' import SafeApiKit from '@safe-global/api-kit/index' import chai from 'chai' import chaiAsPromised from 'chai-as-promised' -import { getServiceClient } from '../utils/setupServiceClient' +import { getKits } from '../utils/setupKits' chai.use(chaiAsPromised) -let safeApiKit1: SafeApiKit +const PRIVATE_KEY_1 = '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676' +const PRIVATE_KEY_2 = '0xb88ad5789871315d0dab6fc5961d6714f24f35a6393f13a6f426dfecfc00ab44' + +let safeApiKit: SafeApiKit let protocolKit: Safe -let ethAdapter1: EthAdapter -let ethAdapter2: EthAdapter +const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78' +const signerSafeAddress = '0xDa8dd250065F19f7A29564396D7F13230b9fC5A3' const generateRandomUUID = (): string => { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => { @@ -27,74 +30,63 @@ const generateRandomUUID = (): string => { } const generateMessage = () => `${generateRandomUUID()}: I am the owner of the safe` -const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78' -const signerSafeAddress = '0xDa8dd250065F19f7A29564396D7F13230b9fC5A3' describe('addMessageSignature', () => { before(async () => { - ;({ safeApiKit: safeApiKit1, ethAdapter: ethAdapter1 } = await getServiceClient( - '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676' - )) - ;({ ethAdapter: ethAdapter2 } = await getServiceClient( - '0xb88ad5789871315d0dab6fc5961d6714f24f35a6393f13a6f426dfecfc00ab44' - )) + ;({ safeApiKit, protocolKit } = await getKits({ + safeAddress, + signer: PRIVATE_KEY_1 + })) }) it('should fail if safeAddress is empty', async () => { await chai - .expect(safeApiKit1.addMessageSignature('', '0x')) + .expect(safeApiKit.addMessageSignature('', '0x')) .to.be.rejectedWith('Invalid messageHash or signature') }) it('should fail if signature is empty', async () => { await chai - .expect(safeApiKit1.addMessageSignature(safeAddress, '')) + .expect(safeApiKit.addMessageSignature(safeAddress, '')) .to.be.rejectedWith('Invalid messageHash or signature') }) describe('when adding a new message', () => { - beforeEach(async () => { - protocolKit = await Safe.create({ - ethAdapter: ethAdapter1, - safeAddress - }) - }) - it('should allow to add a confirmation signature using the EIP-712', async () => { const rawMessage: string = generateMessage() let safeMessage: SafeMessage = protocolKit.createMessage(rawMessage) safeMessage = await protocolKit.signMessage(safeMessage, 'eth_sign') - let signerAddress = (await ethAdapter1.getSignerAddress()) || '0x' + let signerAddress = (await protocolKit.getSafeProvider().getSignerAddress()) || '0x' await chai.expect( - safeApiKit1.addMessage(safeAddress, { + safeApiKit.addMessage(safeAddress, { message: rawMessage, signature: safeMessage.getSignature(signerAddress)?.data || '0x' }) ).to.be.fulfilled - protocolKit = await protocolKit.connect({ ethAdapter: ethAdapter2 }) + protocolKit = await protocolKit.connect({ signer: PRIVATE_KEY_2 }) safeMessage = await protocolKit.signMessage(safeMessage, 'eth_signTypedData_v4') const safeMessageHash = await protocolKit.getSafeMessageHash(hashSafeMessage(rawMessage)) - signerAddress = (await ethAdapter2.getSignerAddress()) || '0x' + signerAddress = (await protocolKit.getSafeProvider().getSignerAddress()) || '0x' await chai.expect( - safeApiKit1.addMessageSignature( + safeApiKit.addMessageSignature( safeMessageHash, safeMessage.getSignature(signerAddress)?.data || '0x' ) ).to.be.fulfilled - const confirmedMessage = await safeApiKit1.getMessage(safeMessageHash) + const confirmedMessage = await safeApiKit.getMessage(safeMessageHash) chai.expect(confirmedMessage.confirmations.length).to.eq(2) }) it('should allow to add a confirmation signature using a Safe signer', async () => { protocolKit = await protocolKit.connect({ - ethAdapter: ethAdapter1, + signer: PRIVATE_KEY_1, safeAddress }) @@ -104,18 +96,18 @@ describe('addMessageSignature', () => { let safeMessage: SafeMessage = protocolKit.createMessage(rawMessage) safeMessage = await protocolKit.signMessage(safeMessage, 'eth_sign') - const signerAddress = (await ethAdapter1.getSignerAddress()) || '0x' + const signerAddress = (await protocolKit.getSafeProvider().getSignerAddress()) || '0x' const ethSig = safeMessage.getSignature(signerAddress) as EthSafeSignature await chai.expect( - safeApiKit1.addMessage(safeAddress, { + safeApiKit.addMessage(safeAddress, { message: rawMessage, signature: buildSignatureBytes([ethSig]) }) ).to.be.fulfilled protocolKit = await protocolKit.connect({ - ethAdapter: ethAdapter1, + signer: PRIVATE_KEY_1, safeAddress: signerSafeAddress }) let signerSafeMessage = protocolKit.createMessage(rawMessage) @@ -126,7 +118,7 @@ describe('addMessageSignature', () => { ) protocolKit = await protocolKit.connect({ - ethAdapter: ethAdapter2, + signer: PRIVATE_KEY_2, safeAddress: signerSafeAddress }) signerSafeMessage = await protocolKit.signMessage( @@ -141,7 +133,7 @@ describe('addMessageSignature', () => { ) protocolKit = await protocolKit.connect({ - ethAdapter: ethAdapter1, + signer: PRIVATE_KEY_1, safeAddress }) @@ -156,10 +148,10 @@ describe('addMessageSignature', () => { const contractSig = buildSignatureBytes([signerSafeSig]) - await chai.expect(safeApiKit1.addMessageSignature(safeMessageHash, contractSig)).to.be + await chai.expect(safeApiKit.addMessageSignature(safeMessageHash, contractSig)).to.be .fulfilled - const confirmedMessage = await safeApiKit1.getMessage(safeMessageHash) + const confirmedMessage = await safeApiKit.getMessage(safeMessageHash) chai.expect(confirmedMessage.confirmations.length).to.eq(2) }) }) diff --git a/packages/api-kit/tests/e2e/addSafeDelegate.test.ts b/packages/api-kit/tests/e2e/addSafeDelegate.test.ts index d91efe0ce..f791c14fd 100644 --- a/packages/api-kit/tests/e2e/addSafeDelegate.test.ts +++ b/packages/api-kit/tests/e2e/addSafeDelegate.test.ts @@ -1,25 +1,26 @@ -import { Signer } from 'ethers' +import { ethers, Signer } from 'ethers' import SafeApiKit, { AddSafeDelegateProps } from '@safe-global/api-kit/index' import chai from 'chai' import chaiAsPromised from 'chai-as-promised' import config from '../utils/config' -import { getServiceClient } from '../utils/setupServiceClient' +import { getApiKit } from '../utils/setupKits' chai.use(chaiAsPromised) +const PRIVATE_KEY_1 = '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676' +const PRIVATE_KEY_2 = '0xb0057716d5917badaf911b193b12b910811c1497b5bada8d7711f758981c3773' + let safeApiKit: SafeApiKit let signer: Signer describe('addSafeDelegate', () => { before(async () => { - ;({ safeApiKit, signer } = await getServiceClient( - '0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d', - 'https://safe-transaction-sepolia.staging.5afe.dev/api' - )) + safeApiKit = getApiKit('https://safe-transaction-sepolia.staging.5afe.dev/api') + signer = new ethers.Wallet(PRIVATE_KEY_1) }) it('should fail if Label is empty', async () => { - const delegateAddress = '0xe4bb611E4e4164D54Ad7361B9d58b0A1eBD462B8' + const delegateAddress = '0x9cCBDE03eDd71074ea9c49e413FA9CDfF16D263B' const delegatorAddress = await signer.getAddress() const delegateConfig: AddSafeDelegateProps = { delegateAddress, @@ -61,8 +62,8 @@ describe('addSafeDelegate', () => { }) it('should fail if Safe address is not checksummed', async () => { - const safeAddress = '0xe4bb611E4e4164D54Ad7361B9d58b0A1eBD462B8'.toLowerCase() - const delegateAddress = '0xe4bb611E4e4164D54Ad7361B9d58b0A1eBD462B8' + const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78'.toLowerCase() + const delegateAddress = '0x9cCBDE03eDd71074ea9c49e413FA9CDfF16D263B' const delegatorAddress = await signer.getAddress() const delegateConfig: AddSafeDelegateProps = { safeAddress, @@ -77,8 +78,8 @@ describe('addSafeDelegate', () => { }) it('should fail if Safe delegate address is not checksummed', async () => { - const safeAddress = '0xe4bb611E4e4164D54Ad7361B9d58b0A1eBD462B8' - const delegateAddress = '0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0'.toLowerCase() + const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78' + const delegateAddress = '0x9cCBDE03eDd71074ea9c49e413FA9CDfF16D263B'.toLowerCase() const delegatorAddress = await signer.getAddress() const delegateConfig: AddSafeDelegateProps = { safeAddress, @@ -93,8 +94,8 @@ describe('addSafeDelegate', () => { }) it('should fail if Safe delegator address is not checksummed', async () => { - const safeAddress = '0xe4bb611E4e4164D54Ad7361B9d58b0A1eBD462B8' - const delegateAddress = '0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0' + const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78' + const delegateAddress = '0x9cCBDE03eDd71074ea9c49e413FA9CDfF16D263B' const delegatorAddress = (await signer.getAddress()).toLowerCase() const delegateConfig: AddSafeDelegateProps = { safeAddress, @@ -125,18 +126,15 @@ describe('addSafeDelegate', () => { }) it('should fail if the signer is not an owner of the Safe', async () => { - const { safeApiKit, signer } = await getServiceClient( - '0xb0057716d5917badaf911b193b12b910811c1497b5bada8d7711f758981c3773', - 'https://safe-transaction-sepolia.staging.5afe.dev/api' - ) - const safeAddress = '0xe4bb611E4e4164D54Ad7361B9d58b0A1eBD462B8' - const delegateAddress = '0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0' - const delegatorAddress = await signer.getAddress() + const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78' + const delegateAddress = '0x9cCBDE03eDd71074ea9c49e413FA9CDfF16D263B' + const nonOwnerSigner = new ethers.Wallet(PRIVATE_KEY_2) + const delegatorAddress = await nonOwnerSigner.getAddress() const delegateConfig: AddSafeDelegateProps = { safeAddress, delegateAddress, delegatorAddress, - signer, + signer: nonOwnerSigner, label: 'Label' } await chai @@ -147,8 +145,8 @@ describe('addSafeDelegate', () => { }) it('should add a new delegate', async () => { - const safeAddress = '0xe4bb611E4e4164D54Ad7361B9d58b0A1eBD462B8' - const delegateAddress = '0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0' + const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78' + const delegateAddress = '0x9cCBDE03eDd71074ea9c49e413FA9CDfF16D263B' const delegatorAddress = await signer.getAddress() const delegateConfig: AddSafeDelegateProps = { safeAddress, @@ -198,7 +196,7 @@ describe('addSafeDelegate', () => { }) it('should add a new delegate EIP-3770', async () => { - const safeAddress = '0xe4bb611E4e4164D54Ad7361B9d58b0A1eBD462B8' + const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78' const eip3770SafeAddress = `${config.EIP_3770_PREFIX}:${safeAddress}` const delegateAddress = '0x9cCBDE03eDd71074ea9c49e413FA9CDfF16D263B' const eip3770DelegateAddress = `${config.EIP_3770_PREFIX}:${delegateAddress}` diff --git a/packages/api-kit/tests/e2e/confirmTransaction.test.ts b/packages/api-kit/tests/e2e/confirmTransaction.test.ts index 0be972545..c2878e7f5 100644 --- a/packages/api-kit/tests/e2e/confirmTransaction.test.ts +++ b/packages/api-kit/tests/e2e/confirmTransaction.test.ts @@ -4,37 +4,29 @@ import Safe, { SigningMethod, buildContractSignature } from '@safe-global/protocol-kit' -import { EthAdapter, SafeTransactionDataPartial } from '@safe-global/safe-core-sdk-types' +import { SafeTransactionDataPartial } from '@safe-global/safe-core-sdk-types' import SafeApiKit from '@safe-global/api-kit/index' import chai from 'chai' import chaiAsPromised from 'chai-as-promised' -import { getServiceClient } from '../utils/setupServiceClient' +import { getKits } from '../utils/setupKits' chai.use(chaiAsPromised) -let safeApiKit1: SafeApiKit +const PRIVATE_KEY_1 = '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676' +const PRIVATE_KEY_2 = '0xb88ad5789871315d0dab6fc5961d6714f24f35a6393f13a6f426dfecfc00ab44' + +let safeApiKit: SafeApiKit let protocolKit: Safe -let ethAdapter1: EthAdapter -let ethAdapter2: EthAdapter const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78' const signerSafeAddress = '0xDa8dd250065F19f7A29564396D7F13230b9fC5A3' describe('proposeTransaction', () => { before(async () => { - ;({ safeApiKit: safeApiKit1, ethAdapter: ethAdapter1 } = await getServiceClient( - '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676' - )) - ;({ ethAdapter: ethAdapter2 } = await getServiceClient( - '0xb88ad5789871315d0dab6fc5961d6714f24f35a6393f13a6f426dfecfc00ab44' - )) - }) - - beforeEach(async () => { - protocolKit = await Safe.create({ - ethAdapter: ethAdapter1, + ;({ safeApiKit, protocolKit } = await getKits({ + signer: PRIVATE_KEY_1, safeAddress - }) + })) }) it('should allow to create and confirm transactions signature using a Safe signer', async () => { @@ -50,7 +42,7 @@ describe('proposeTransaction', () => { // EOA signature tx = await protocolKit.signTransaction(tx) - const signerAddress = (await ethAdapter1.getSignerAddress()) || '0x' + const signerAddress = (await protocolKit.getSafeProvider().getSignerAddress()) || '0x' const ethSig = tx.getSignature(signerAddress) as EthSafeSignature const txOptions = { @@ -61,11 +53,11 @@ describe('proposeTransaction', () => { senderSignature: buildSignatureBytes([ethSig]) } - await chai.expect(safeApiKit1.proposeTransaction(txOptions)).to.be.fulfilled + await chai.expect(safeApiKit.proposeTransaction(txOptions)).to.be.fulfilled // Signer Safe signature protocolKit = await protocolKit.connect({ - ethAdapter: ethAdapter1, + signer: PRIVATE_KEY_1, safeAddress: signerSafeAddress }) @@ -79,7 +71,7 @@ describe('proposeTransaction', () => { ) protocolKit = await protocolKit.connect({ - ethAdapter: ethAdapter2, + signer: PRIVATE_KEY_2, safeAddress: signerSafeAddress }) signerSafeTx = await protocolKit.signTransaction( @@ -94,7 +86,7 @@ describe('proposeTransaction', () => { ) protocolKit = await protocolKit.connect({ - ethAdapter: ethAdapter1, + signer: PRIVATE_KEY_1, safeAddress }) @@ -103,9 +95,9 @@ describe('proposeTransaction', () => { // chai.expect(isValidSignature).to.be.true const contractSig = buildSignatureBytes([signerSafeSig]) - await chai.expect(safeApiKit1.confirmTransaction(txHash, contractSig)).to.be.fulfilled + await chai.expect(safeApiKit.confirmTransaction(txHash, contractSig)).to.be.fulfilled - const confirmedMessage = await safeApiKit1.getTransaction(txHash) - chai.expect(confirmedMessage.confirmations.length).to.eq(2) + const confirmedMessage = await safeApiKit.getTransaction(txHash) + chai.expect(confirmedMessage?.confirmations?.length).to.eq(2) }) }) diff --git a/packages/api-kit/tests/e2e/decodeData.test.ts b/packages/api-kit/tests/e2e/decodeData.test.ts index e383ab7b0..7d96a5548 100644 --- a/packages/api-kit/tests/e2e/decodeData.test.ts +++ b/packages/api-kit/tests/e2e/decodeData.test.ts @@ -1,7 +1,7 @@ import chai from 'chai' import chaiAsPromised from 'chai-as-promised' import SafeApiKit from '@safe-global/api-kit/index' -import { getServiceClient } from '../utils/setupServiceClient' +import { getApiKit } from '../utils/setupKits' chai.use(chaiAsPromised) @@ -9,9 +9,7 @@ let safeApiKit: SafeApiKit describe('decodeData', () => { before(async () => { - ;({ safeApiKit } = await getServiceClient( - '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676' - )) + safeApiKit = getApiKit() }) it('should fail if data is empty', async () => { diff --git a/packages/api-kit/tests/e2e/getIncomingTransactions.test.ts b/packages/api-kit/tests/e2e/getIncomingTransactions.test.ts index e0a7dd7be..85c9b1ef8 100644 --- a/packages/api-kit/tests/e2e/getIncomingTransactions.test.ts +++ b/packages/api-kit/tests/e2e/getIncomingTransactions.test.ts @@ -2,7 +2,7 @@ import chai from 'chai' import chaiAsPromised from 'chai-as-promised' import SafeApiKit from '@safe-global/api-kit/index' import config from '../utils/config' -import { getServiceClient } from '../utils/setupServiceClient' +import { getApiKit } from '../utils/setupKits' chai.use(chaiAsPromised) @@ -10,9 +10,7 @@ let safeApiKit: SafeApiKit describe('getIncomingTransactions', () => { before(async () => { - ;({ safeApiKit } = await getServiceClient( - '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676' - )) + safeApiKit = getApiKit() }) it('should fail if Safe address is empty', async () => { diff --git a/packages/api-kit/tests/e2e/getMessage.test.ts b/packages/api-kit/tests/e2e/getMessage.test.ts index 527fb6c3a..7a310372c 100644 --- a/packages/api-kit/tests/e2e/getMessage.test.ts +++ b/packages/api-kit/tests/e2e/getMessage.test.ts @@ -1,7 +1,7 @@ import SafeApiKit from '@safe-global/api-kit/index' import chai from 'chai' import chaiAsPromised from 'chai-as-promised' -import { getServiceClient } from '../utils/setupServiceClient' +import { getApiKit } from '../utils/setupKits' chai.use(chaiAsPromised) @@ -10,9 +10,7 @@ const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78' describe('getMessages', () => { before(async () => { - ;({ safeApiKit } = await getServiceClient( - '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676' - )) + safeApiKit = getApiKit() }) it('should fail if safeAddress is empty', async () => { diff --git a/packages/api-kit/tests/e2e/getMessages.test.ts b/packages/api-kit/tests/e2e/getMessages.test.ts index 2826f4b76..ec4768d5a 100644 --- a/packages/api-kit/tests/e2e/getMessages.test.ts +++ b/packages/api-kit/tests/e2e/getMessages.test.ts @@ -1,7 +1,7 @@ import SafeApiKit from '@safe-global/api-kit/index' import chai from 'chai' import chaiAsPromised from 'chai-as-promised' -import { getServiceClient } from '../utils/setupServiceClient' +import { getApiKit } from '../utils/setupKits' chai.use(chaiAsPromised) @@ -10,9 +10,7 @@ const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78' describe('getMessages', () => { before(async () => { - ;({ safeApiKit } = await getServiceClient( - '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676' - )) + safeApiKit = getApiKit() }) it('should fail if safeAddress is empty or invalid', async () => { diff --git a/packages/api-kit/tests/e2e/getMultisigTransactions.test.ts b/packages/api-kit/tests/e2e/getMultisigTransactions.test.ts index d1b1590ff..d617831a0 100644 --- a/packages/api-kit/tests/e2e/getMultisigTransactions.test.ts +++ b/packages/api-kit/tests/e2e/getMultisigTransactions.test.ts @@ -2,7 +2,7 @@ import chai from 'chai' import chaiAsPromised from 'chai-as-promised' import SafeApiKit from '@safe-global/api-kit/index' import config from '../utils/config' -import { getServiceClient } from '../utils/setupServiceClient' +import { getApiKit } from '../utils/setupKits' chai.use(chaiAsPromised) @@ -10,9 +10,7 @@ let safeApiKit: SafeApiKit describe('getMultisigTransactions', () => { before(async () => { - ;({ safeApiKit } = await getServiceClient( - '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676' - )) + safeApiKit = getApiKit() }) it('should fail if Safe address is empty', async () => { @@ -41,8 +39,8 @@ describe('getMultisigTransactions', () => { const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78' // Safe with multisig transactions const safeMultisigTransactionListResponse = await safeApiKit.getMultisigTransactions(safeAddress) - chai.expect(safeMultisigTransactionListResponse.count).to.be.equal(18) - chai.expect(safeMultisigTransactionListResponse.results.length).to.be.equal(18) + chai.expect(safeMultisigTransactionListResponse.count).to.be.equal(22) + chai.expect(safeMultisigTransactionListResponse.results.length).to.be.equal(22) safeMultisigTransactionListResponse.results.map((transaction) => { chai.expect(transaction.safe).to.be.equal(safeAddress) }) @@ -53,8 +51,8 @@ describe('getMultisigTransactions', () => { const eip3770SafeAddress = `${config.EIP_3770_PREFIX}:${safeAddress}` const safeMultisigTransactionListResponse = await safeApiKit.getMultisigTransactions(eip3770SafeAddress) - chai.expect(safeMultisigTransactionListResponse.count).to.be.equal(18) - chai.expect(safeMultisigTransactionListResponse.results.length).to.be.equal(18) + chai.expect(safeMultisigTransactionListResponse.count).to.be.equal(22) + chai.expect(safeMultisigTransactionListResponse.results.length).to.be.equal(22) safeMultisigTransactionListResponse.results.map((transaction) => { chai.expect(transaction.safe).to.be.equal(safeAddress) }) diff --git a/packages/api-kit/tests/e2e/getNextNonce.test.ts b/packages/api-kit/tests/e2e/getNextNonce.test.ts index 4120a13a5..029ac5af3 100644 --- a/packages/api-kit/tests/e2e/getNextNonce.test.ts +++ b/packages/api-kit/tests/e2e/getNextNonce.test.ts @@ -2,16 +2,14 @@ import chai from 'chai' import chaiAsPromised from 'chai-as-promised' import SafeApiKit from '@safe-global/api-kit/index' import config from '../utils/config' -import { getServiceClient } from '../utils/setupServiceClient' +import { getApiKit } from '../utils/setupKits' chai.use(chaiAsPromised) let safeApiKit: SafeApiKit describe('getNextNonce', () => { before(async () => { - ;({ safeApiKit } = await getServiceClient( - '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676' - )) + safeApiKit = getApiKit() }) it('should fail if Safe address is empty', async () => { @@ -24,14 +22,14 @@ describe('getNextNonce', () => { it('should return the next Safe nonce when there are pending transactions', async () => { const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78' const nextNonce = await safeApiKit.getNextNonce(safeAddress) - chai.expect(nextNonce).to.be.equal(11) + chai.expect(nextNonce).to.be.equal(13) }) it('should return the next Safe nonce when there are pending transactions EIP-3770', async () => { const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78' const eip3770SafeAddress = `${config.EIP_3770_PREFIX}:${safeAddress}` const nextNonce = await safeApiKit.getNextNonce(eip3770SafeAddress) - chai.expect(nextNonce).to.be.equal(11) + chai.expect(nextNonce).to.be.equal(13) }) it('should return the next Safe nonce when there are no pending transactions', async () => { diff --git a/packages/api-kit/tests/e2e/getPendingTransactions.test.ts b/packages/api-kit/tests/e2e/getPendingTransactions.test.ts index 53a7f3388..e8d4e3938 100644 --- a/packages/api-kit/tests/e2e/getPendingTransactions.test.ts +++ b/packages/api-kit/tests/e2e/getPendingTransactions.test.ts @@ -2,7 +2,7 @@ import chai from 'chai' import chaiAsPromised from 'chai-as-promised' import SafeApiKit from '@safe-global/api-kit/index' import config from '../utils/config' -import { getServiceClient } from '../utils/setupServiceClient' +import { getApiKit } from '../utils/setupKits' chai.use(chaiAsPromised) @@ -10,9 +10,7 @@ let safeApiKit: SafeApiKit describe('getPendingTransactions', () => { before(async () => { - ;({ safeApiKit } = await getServiceClient( - '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676' - )) + safeApiKit = getApiKit() }) it('should fail if safeAddress is empty', async () => { diff --git a/packages/api-kit/tests/e2e/getSafeDelegates.test.ts b/packages/api-kit/tests/e2e/getSafeDelegates.test.ts index fae2bf610..936518536 100644 --- a/packages/api-kit/tests/e2e/getSafeDelegates.test.ts +++ b/packages/api-kit/tests/e2e/getSafeDelegates.test.ts @@ -1,21 +1,21 @@ -import { Signer } from 'ethers' +import { ethers, Signer } from 'ethers' import SafeApiKit, { DeleteSafeDelegateProps } from '@safe-global/api-kit/index' import chai from 'chai' import chaiAsPromised from 'chai-as-promised' import config from '../utils/config' -import { getServiceClient } from '../utils/setupServiceClient' +import { getApiKit } from '../utils/setupKits' chai.use(chaiAsPromised) +const PRIVATE_KEY = '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676' + let safeApiKit: SafeApiKit let signer: Signer describe('getSafeDelegates', () => { before(async () => { - ;({ safeApiKit, signer } = await getServiceClient( - '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676', - 'https://safe-transaction-sepolia.staging.5afe.dev/api' - )) + safeApiKit = getApiKit('https://safe-transaction-sepolia.staging.5afe.dev/api') + signer = new ethers.Wallet(PRIVATE_KEY) }) it('should fail if Safe address is empty', async () => { diff --git a/packages/api-kit/tests/e2e/getSafeInfo.test.ts b/packages/api-kit/tests/e2e/getSafeInfo.test.ts index 7434099ba..a6621ef3b 100644 --- a/packages/api-kit/tests/e2e/getSafeInfo.test.ts +++ b/packages/api-kit/tests/e2e/getSafeInfo.test.ts @@ -2,7 +2,7 @@ import SafeApiKit from '@safe-global/api-kit/index' import chai from 'chai' import chaiAsPromised from 'chai-as-promised' import config from '../utils/config' -import { getServiceClient } from '../utils/setupServiceClient' +import { getApiKit } from '../utils/setupKits' chai.use(chaiAsPromised) @@ -10,9 +10,7 @@ let safeApiKit: SafeApiKit describe('getSafeInfo', () => { before(async () => { - ;({ safeApiKit } = await getServiceClient( - '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676' - )) + safeApiKit = getApiKit() }) it('should fail if Safe address is empty', async () => { diff --git a/packages/api-kit/tests/e2e/getSafesByModule.test.ts b/packages/api-kit/tests/e2e/getSafesByModule.test.ts index 21bcbdfd5..856d96563 100644 --- a/packages/api-kit/tests/e2e/getSafesByModule.test.ts +++ b/packages/api-kit/tests/e2e/getSafesByModule.test.ts @@ -2,7 +2,7 @@ import chai from 'chai' import chaiAsPromised from 'chai-as-promised' import SafeApiKit from '@safe-global/api-kit/index' import config from '../utils/config' -import { getServiceClient } from '../utils/setupServiceClient' +import { getApiKit } from '../utils/setupKits' chai.use(chaiAsPromised) @@ -11,9 +11,7 @@ const goerliSpendingLimitModule = '0xCFbFaC74C26F8647cBDb8c5caf80BB5b32E43134' describe('getSafesByModule', () => { before(async () => { - ;({ safeApiKit } = await getServiceClient( - '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676' - )) + safeApiKit = getApiKit() }) it('should fail if module address is empty', async () => { diff --git a/packages/api-kit/tests/e2e/getSafesByOwner.test.ts b/packages/api-kit/tests/e2e/getSafesByOwner.test.ts index 33e00c5c7..ffc356748 100644 --- a/packages/api-kit/tests/e2e/getSafesByOwner.test.ts +++ b/packages/api-kit/tests/e2e/getSafesByOwner.test.ts @@ -2,7 +2,7 @@ import chai from 'chai' import chaiAsPromised from 'chai-as-promised' import SafeApiKit from '@safe-global/api-kit/index' import config from '../utils/config' -import { getServiceClient } from '../utils/setupServiceClient' +import { getApiKit } from '../utils/setupKits' chai.use(chaiAsPromised) @@ -10,9 +10,7 @@ let safeApiKit: SafeApiKit describe('getSafesByOwner', () => { before(async () => { - ;({ safeApiKit } = await getServiceClient( - '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676' - )) + safeApiKit = getApiKit() }) it('should fail if owner address is empty', async () => { diff --git a/packages/api-kit/tests/e2e/getServiceInfo.test.ts b/packages/api-kit/tests/e2e/getServiceInfo.test.ts index e63c41dde..7074ff3d3 100644 --- a/packages/api-kit/tests/e2e/getServiceInfo.test.ts +++ b/packages/api-kit/tests/e2e/getServiceInfo.test.ts @@ -1,14 +1,12 @@ import { expect } from 'chai' import SafeApiKit from '@safe-global/api-kit/index' -import { getServiceClient } from '../utils/setupServiceClient' +import { getApiKit } from '../utils/setupKits' let safeApiKit: SafeApiKit describe('getServiceInfo', () => { before(async () => { - ;({ safeApiKit } = await getServiceClient( - '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676' - )) + safeApiKit = getApiKit() }) it('should return the Safe info', async () => { diff --git a/packages/api-kit/tests/e2e/getServiceSingletonsInfo.test.ts b/packages/api-kit/tests/e2e/getServiceSingletonsInfo.test.ts index cd4d48e5b..0c518db85 100644 --- a/packages/api-kit/tests/e2e/getServiceSingletonsInfo.test.ts +++ b/packages/api-kit/tests/e2e/getServiceSingletonsInfo.test.ts @@ -1,15 +1,13 @@ import chai from 'chai' import SafeApiKit from '@safe-global/api-kit/index' import semverSatisfies from 'semver/functions/satisfies' -import { getServiceClient } from '../utils/setupServiceClient' +import { getApiKit } from '../utils/setupKits' let safeApiKit: SafeApiKit describe('getServiceSingletonsInfo', () => { before(async () => { - ;({ safeApiKit } = await getServiceClient( - '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676' - )) + safeApiKit = getApiKit() }) it('should call getServiceSingletonsInfo', async () => { diff --git a/packages/api-kit/tests/e2e/getToken.test.ts b/packages/api-kit/tests/e2e/getToken.test.ts index 693f37ca7..cd1c20046 100644 --- a/packages/api-kit/tests/e2e/getToken.test.ts +++ b/packages/api-kit/tests/e2e/getToken.test.ts @@ -2,7 +2,7 @@ import chai from 'chai' import chaiAsPromised from 'chai-as-promised' import SafeApiKit from '@safe-global/api-kit/index' import config from '../utils/config' -import { getServiceClient } from '../utils/setupServiceClient' +import { getApiKit } from '../utils/setupKits' chai.use(chaiAsPromised) @@ -10,9 +10,7 @@ let safeApiKit: SafeApiKit describe('getToken', () => { before(async () => { - ;({ safeApiKit } = await getServiceClient( - '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676' - )) + safeApiKit = getApiKit() }) it('should fail if token address is empty', async () => { diff --git a/packages/api-kit/tests/e2e/getTokenList.test.ts b/packages/api-kit/tests/e2e/getTokenList.test.ts index 6115f76d5..c1e3bc68e 100644 --- a/packages/api-kit/tests/e2e/getTokenList.test.ts +++ b/packages/api-kit/tests/e2e/getTokenList.test.ts @@ -1,14 +1,12 @@ import chai from 'chai' import SafeApiKit from '@safe-global/api-kit/index' -import { getServiceClient } from '../utils/setupServiceClient' +import { getApiKit } from '../utils/setupKits' let safeApiKit: SafeApiKit describe('getTokenList', () => { before(async () => { - ;({ safeApiKit } = await getServiceClient( - '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676' - )) + safeApiKit = getApiKit() }) it('should return an array of tokens', async () => { diff --git a/packages/api-kit/tests/e2e/getTransaction.test.ts b/packages/api-kit/tests/e2e/getTransaction.test.ts index 50e39a98b..7d459fb3c 100644 --- a/packages/api-kit/tests/e2e/getTransaction.test.ts +++ b/packages/api-kit/tests/e2e/getTransaction.test.ts @@ -1,7 +1,7 @@ import chai from 'chai' import chaiAsPromised from 'chai-as-promised' import SafeApiKit from '@safe-global/api-kit/index' -import { getServiceClient } from '../utils/setupServiceClient' +import { getApiKit } from '../utils/setupKits' chai.use(chaiAsPromised) @@ -9,9 +9,7 @@ let safeApiKit: SafeApiKit describe('getTransaction', () => { before(async () => { - ;({ safeApiKit } = await getServiceClient( - '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676' - )) + safeApiKit = getApiKit() }) it('should fail if safeTxHash is empty', async () => { diff --git a/packages/api-kit/tests/e2e/getTransactionConfirmations.test.ts b/packages/api-kit/tests/e2e/getTransactionConfirmations.test.ts index 5c8103fff..ecd877baa 100644 --- a/packages/api-kit/tests/e2e/getTransactionConfirmations.test.ts +++ b/packages/api-kit/tests/e2e/getTransactionConfirmations.test.ts @@ -1,7 +1,7 @@ import chai from 'chai' import chaiAsPromised from 'chai-as-promised' import SafeApiKit from '@safe-global/api-kit/index' -import { getServiceClient } from '../utils/setupServiceClient' +import { getApiKit } from '../utils/setupKits' chai.use(chaiAsPromised) @@ -9,9 +9,7 @@ let safeApiKit: SafeApiKit describe('getTransactionConfirmations', () => { before(async () => { - ;({ safeApiKit } = await getServiceClient( - '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676' - )) + safeApiKit = getApiKit() }) it('should fail if safeTxHash is empty', async () => { @@ -21,8 +19,8 @@ describe('getTransactionConfirmations', () => { .to.be.rejectedWith('Invalid safeTxHash') }) - it.skip('should return an empty array if the safeTxHash is not found', async () => { - const safeTxHash = '0x' + it('should return an empty array if the safeTxHash is not found', async () => { + const safeTxHash = '0x317834aea988fd3cfa54fd8b2be2c96b4fd70a14d8c9470a7110576b01e6480b' const transactionConfirmations = await safeApiKit.getTransactionConfirmations(safeTxHash) chai.expect(transactionConfirmations.count).to.be.equal(0) chai.expect(transactionConfirmations.results.length).to.be.equal(0) diff --git a/packages/api-kit/tests/e2e/removeSafeDelegate.test.ts b/packages/api-kit/tests/e2e/removeSafeDelegate.test.ts index b25073046..cb04880b2 100644 --- a/packages/api-kit/tests/e2e/removeSafeDelegate.test.ts +++ b/packages/api-kit/tests/e2e/removeSafeDelegate.test.ts @@ -1,21 +1,21 @@ -import { Signer } from 'ethers' +import { ethers, Signer } from 'ethers' import SafeApiKit, { DeleteSafeDelegateProps } from '@safe-global/api-kit/index' import chai from 'chai' import chaiAsPromised from 'chai-as-promised' import config from '../utils/config' -import { getServiceClient } from '../utils/setupServiceClient' +import { getApiKit } from '../utils/setupKits' chai.use(chaiAsPromised) +const PRIVATE_KEY = '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676' + let safeApiKit: SafeApiKit let signer: Signer describe('removeSafeDelegate', () => { before(async () => { - ;({ safeApiKit, signer } = await getServiceClient( - '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676', - 'https://safe-transaction-sepolia.staging.5afe.dev/api' - )) + safeApiKit = getApiKit('https://safe-transaction-sepolia.staging.5afe.dev/api') + signer = new ethers.Wallet(PRIVATE_KEY) }) it('should fail if Safe delegate address is empty', async () => { diff --git a/packages/api-kit/tests/endpoint/index.test.ts b/packages/api-kit/tests/endpoint/index.test.ts index ce34ba1d6..b9a72297e 100644 --- a/packages/api-kit/tests/endpoint/index.test.ts +++ b/packages/api-kit/tests/endpoint/index.test.ts @@ -7,19 +7,20 @@ import SafeApiKit, { } from '@safe-global/api-kit/index' import * as httpRequests from '@safe-global/api-kit/utils/httpRequests' import Safe from '@safe-global/protocol-kit' -import { EthAdapter } from '@safe-global/safe-core-sdk-types' import chai from 'chai' import chaiAsPromised from 'chai-as-promised' import sinon from 'sinon' import sinonChai from 'sinon-chai' import config from '../utils/config' -import { getServiceClient } from '../utils/setupServiceClient' +import { getApiKit, getKits } from '../utils/setupKits' import { signDelegate } from '@safe-global/api-kit/utils/signDelegate' chai.use(chaiAsPromised) chai.use(sinonChai) -const chainId = '0xaa36a7' +const PRIVATE_KEY_1 = '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676' + +const chainId = 11155111n const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78' const eip3770SafeAddress = `${config.EIP_3770_PREFIX}:${safeAddress}` const randomAddress = '0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0' @@ -30,22 +31,18 @@ const tokenAddress = '0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14' const eip3770TokenAddress = `${config.EIP_3770_PREFIX}:${tokenAddress}` const safeTxHash = '0x317834aea988fd3cfa54fd8b2be2c96b4fd70a14d8c9470a7110576b01e6480a' const txServiceBaseUrl = 'https://safe-transaction-sepolia.safe.global/api' -const provider = getDefaultProvider(config.JSON_RPC) -const signer = new Wallet( - '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676', - provider -) -let ethAdapter: EthAdapter +const defaultProvider = getDefaultProvider(config.JSON_RPC) +const signer = new Wallet(PRIVATE_KEY_1, defaultProvider) + +let protocolKit: Safe let safeApiKit: SafeApiKit let delegatorAddress: string let eip3770DelegatorAddress: string describe('Endpoint tests', () => { before(async () => { - ;({ safeApiKit, ethAdapter } = await getServiceClient( - '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676' - )) - delegatorAddress = await signer.getAddress() + ;({ safeApiKit, protocolKit } = await getKits({ signer: PRIVATE_KEY_1, safeAddress })) + delegatorAddress = (await protocolKit.getSafeProvider().getSignerAddress()) || '0x' eip3770DelegatorAddress = `${config.EIP_3770_PREFIX}:${delegatorAddress}` }) @@ -360,12 +357,11 @@ describe('Endpoint tests', () => { } const origin = 'Safe Core SDK: Safe API Kit' const signerAddress = await signer.getAddress() - const safeSdk = await Safe.create({ ethAdapter, safeAddress }) - const safeTransaction = await safeSdk.createTransaction({ + const safeTransaction = await protocolKit.createTransaction({ transactions: [safeTransactionData], options }) - const senderSignature = await safeSdk.signHash(safeTxHash) + const senderSignature = await protocolKit.signHash(safeTxHash) await chai .expect( safeApiKit.proposeTransaction({ @@ -409,12 +405,11 @@ describe('Endpoint tests', () => { } const origin = 'Safe Core SDK: Safe API Kit' const signerAddress = await signer.getAddress() - const safeSdk = await Safe.create({ ethAdapter, safeAddress }) - const safeTransaction = await safeSdk.createTransaction({ + const safeTransaction = await protocolKit.createTransaction({ transactions: [safeTransactionData], options }) - const senderSignature = await safeSdk.signHash(safeTxHash) + const senderSignature = await protocolKit.signHash(safeTxHash) await chai .expect( safeApiKit.proposeTransaction({ @@ -647,12 +642,9 @@ describe('Endpoint tests', () => { const txServiceUrl = 'http://my-custom-tx-service.com/api' it('should can instantiate the SafeApiKit with a custom endpoint', async () => { - ;({ safeApiKit } = await getServiceClient( - '0x83a415ca62e11f5fa5567e98450d0f82ae19ff36ef876c10a8d448c788a53676', - txServiceUrl - )) + const apiKit = getApiKit(txServiceUrl) - await chai.expect(safeApiKit.getServiceInfo()).to.be.fulfilled + await chai.expect(apiKit.getServiceInfo()).to.be.fulfilled chai.expect(fetchData).to.have.been.calledWith({ url: `${txServiceUrl}/v1/about`, diff --git a/packages/api-kit/tests/utils/config.ts b/packages/api-kit/tests/utils/config.ts index abf3c2180..e8486dfe6 100644 --- a/packages/api-kit/tests/utils/config.ts +++ b/packages/api-kit/tests/utils/config.ts @@ -1,6 +1,6 @@ const config = { CHAIN_ID: 11155111n, - JSON_RPC: 'https://rpc.ankr.com/eth_sepolia', + JSON_RPC: 'https://sepolia.gateway.tenderly.co', EIP_3770_PREFIX: 'sep' } diff --git a/packages/api-kit/tests/utils/setupEthAdapter.ts b/packages/api-kit/tests/utils/setupEthAdapter.ts deleted file mode 100644 index 83b7b3132..000000000 --- a/packages/api-kit/tests/utils/setupEthAdapter.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { AbstractSigner, Provider } from 'ethers' -import { EthAdapter } from '@safe-global/safe-core-sdk-types' -import { - EthersAdapter, - EthersAdapterConfig, - Web3Adapter, - Web3AdapterConfig -} from '@safe-global/protocol-kit' -import { ethers, web3 } from 'hardhat' - -export async function getEthAdapter( - signerOrProvider: AbstractSigner | Provider -): Promise { - let ethAdapter: EthAdapter - switch (process.env.ETH_LIB) { - case 'web3': - const signerAddress = - signerOrProvider instanceof AbstractSigner ? await signerOrProvider.getAddress() : undefined - - const web3AdapterConfig: Web3AdapterConfig = { - web3, - signerAddress - } - - ethAdapter = new Web3Adapter(web3AdapterConfig) - break - case 'ethers': - const ethersAdapterConfig: EthersAdapterConfig = { ethers, signerOrProvider } - ethAdapter = new EthersAdapter(ethersAdapterConfig) - break - default: - throw new Error('Ethereum library not supported') - } - return ethAdapter -} diff --git a/packages/api-kit/tests/utils/setupKits.ts b/packages/api-kit/tests/utils/setupKits.ts new file mode 100644 index 000000000..9da1eff87 --- /dev/null +++ b/packages/api-kit/tests/utils/setupKits.ts @@ -0,0 +1,76 @@ +import hre, { ethers } from 'hardhat' +import Web3 from 'web3' +import { custom, createWalletClient } from 'viem' + +import Safe, { SafeProviderConfig, Eip1193Provider } from '@safe-global/protocol-kit' +import SafeApiKit from '@safe-global/api-kit/index' + +import config from './config' + +type GetKits = { + protocolKit: Safe + safeApiKit: SafeApiKit +} + +type GetKitsOptions = { + signer?: SafeProviderConfig['signer'] + txServiceUrl?: string + safeAddress: string +} + +export function getEip1193Provider(): Eip1193Provider { + switch (process.env.ETH_LIB) { + case 'viem': + const client = createWalletClient({ + transport: custom(hre.network.provider) + }) + + return { request: client.request } as Eip1193Provider + + case 'web3': + const web3Provider = new Web3(hre.network.provider) + + return web3Provider.currentProvider as Eip1193Provider + + case 'ethers': + const browserProvider = new ethers.BrowserProvider(hre.network.provider) + + return { + request: async (request) => { + return browserProvider.send(request.method, [...((request.params as unknown[]) ?? [])]) + } + } + default: + throw new Error('ETH_LIB not set') + } +} + +export async function getProtocolKit({ + signer, + safeAddress +}: { + signer?: GetKitsOptions['signer'] + safeAddress: GetKitsOptions['safeAddress'] +}): Promise { + const provider = getEip1193Provider() + const protocolKit = await Safe.init({ provider, signer, safeAddress }) + + return protocolKit +} + +export function getApiKit(txServiceUrl?: GetKitsOptions['txServiceUrl']): SafeApiKit { + const safeApiKit = new SafeApiKit({ chainId: config.CHAIN_ID, txServiceUrl }) + + return safeApiKit +} + +export async function getKits({ + signer, + safeAddress, + txServiceUrl +}: GetKitsOptions): Promise { + const protocolKit = await getProtocolKit({ signer, safeAddress }) + const safeApiKit = getApiKit(txServiceUrl) + + return { protocolKit, safeApiKit } +} diff --git a/packages/api-kit/tests/utils/setupServiceClient.ts b/packages/api-kit/tests/utils/setupServiceClient.ts deleted file mode 100644 index a69e5c1bf..000000000 --- a/packages/api-kit/tests/utils/setupServiceClient.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { getDefaultProvider, Wallet } from 'ethers' -import { EthAdapter } from '@safe-global/safe-core-sdk-types' -import SafeApiKit from '@safe-global/api-kit/index' -import config from '../utils/config' -import { getEthAdapter } from '../utils/setupEthAdapter' - -interface ServiceClientConfig { - safeApiKit: SafeApiKit - ethAdapter: EthAdapter - signer: Wallet -} - -export async function getServiceClient( - signerPk: string, - txServiceUrl?: string -): Promise { - const provider = getDefaultProvider(config.JSON_RPC) - const signer = new Wallet(signerPk, provider) - const ethAdapter = await getEthAdapter(signer) - const safeApiKit = new SafeApiKit({ chainId: config.CHAIN_ID, txServiceUrl }) - return { safeApiKit, ethAdapter, signer } -} diff --git a/packages/auth-kit/README.md b/packages/auth-kit/README.md index d72f26e16..c96fbba42 100644 --- a/packages/auth-kit/README.md +++ b/packages/auth-kit/README.md @@ -6,16 +6,24 @@ The Auth Kit provides a way to authenticate blockchain accounts using email addresses, social accounts or traditional web3 wallets (ex. Metamask). When using web2 methods as your email or social account, a derived Ethereum address will be generated. -## Reference +## Documentation -- [Auth Kit integration guides](https://docs.safe.global/safe-core-aa-sdk/auth-kit) +- [Auth Kit integration guides](https://docs.safe.global/sdk/auth-kit) -- [Auth Kit reference](https://docs.safe.global/reference/auth-kit) +- [Auth Kit reference](https://docs.safe.global/sdk/auth-kit/reference) ## Example [Check a functional demo](https://github.com/safe-global/safe-core-sdk/tree/main/packages/auth-kit/example) using the `auth-kit` +## Need Help or Have Questions? + +If you have any doubts, questions, or need assistance, feel free to reach out! [Here you will find how to get support.](https://github.com/safe-global/safe-core-sdk/tree/main/SUPPORT.md) + +## Contributing + +Please read our [contribution guidelines](https://github.com/safe-global/safe-core-sdk/tree/main/CONTRIBUTING.md) before submitting any changes. We appreciate your help! 🙌 + ## License This library is [released under MIT](https://github.com/safe-global/safe-core-sdk/blob/main/LICENSE.md). diff --git a/packages/auth-kit/example/README.md b/packages/auth-kit/example/README.md index dbd6c2456..633607dee 100644 --- a/packages/auth-kit/example/README.md +++ b/packages/auth-kit/example/README.md @@ -23,5 +23,4 @@ To use the example properly in your local machine follow these steps: **In the auth-kit example root folder** 3. `yarn install` -4. Configure `.env` following `.env.sample` -5. `yarn start` +4. `yarn start` diff --git a/packages/auth-kit/example/src/App.tsx b/packages/auth-kit/example/src/App.tsx index 26c883ffb..611cc08b8 100644 --- a/packages/auth-kit/example/src/App.tsx +++ b/packages/auth-kit/example/src/App.tsx @@ -2,7 +2,7 @@ import { useEffect, useState } from 'react' import { BrowserProvider, Eip1193Provider, ethers } from 'ethers' import { Box, Button, Divider, Grid, Typography } from '@mui/material' import { EthHashInfo } from '@safe-global/safe-react-components' -import Safe, { EthersAdapter } from '@safe-global/protocol-kit' +import Safe from '@safe-global/protocol-kit' import AppBar from './AppBar' import { AuthKitSignInData, @@ -129,15 +129,9 @@ function App() { const safeAddress = safeAuthSignInResponse?.safes?.[index] || '0x' // Wrap Web3Auth provider with ethers - const provider = new BrowserProvider(safeAuthPack?.getProvider() as Eip1193Provider) - const signer = await provider.getSigner() - const ethAdapter = new EthersAdapter({ - ethers, - signerOrProvider: signer - }) - const protocolKit = await Safe.create({ - safeAddress, - ethAdapter + const protocolKit = await Safe.init({ + provider: safeAuthPack?.getProvider() as Eip1193Provider, + safeAddress }) // Create transaction diff --git a/packages/auth-kit/jest.config.js b/packages/auth-kit/jest.config.js index e841887cb..e96123e0d 100644 --- a/packages/auth-kit/jest.config.js +++ b/packages/auth-kit/jest.config.js @@ -6,7 +6,6 @@ const config = { '^.+\\.ts?$': 'ts-jest' }, moduleNameMapper: { - '^@safe-global/protocol-kit/typechain/(.*)$': '/../protocol-kit/typechain/$1', '^@safe-global/protocol-kit/(.*)$': '/../protocol-kit/src/$1', '^@safe-global/auth-kit/(.*)$': '/src/$1' } diff --git a/packages/auth-kit/package.json b/packages/auth-kit/package.json index 031b0e9dc..f4613a831 100644 --- a/packages/auth-kit/package.json +++ b/packages/auth-kit/package.json @@ -1,6 +1,6 @@ { "name": "@safe-global/auth-kit", - "version": "2.0.5", + "version": "2.0.5-alpha.0", "description": "Authentication library for web2 logins", "main": "dist/src/index.js", "types": "dist/src/index.d.ts", @@ -40,9 +40,9 @@ "react-dom": "^18.2.0" }, "dependencies": { - "@safe-global/api-kit": "^2.3.2", - "@safe-global/protocol-kit": "^3.1.1", + "@safe-global/api-kit": "^2.3.2-alpha.0", + "@safe-global/protocol-kit": "^4.0.0-alpha.0", "@web3auth/safeauth-embed": "^0.0.0", - "ethers": "^6.7.1" + "ethers": "^6.12.1" } } diff --git a/packages/onramp-kit/README.md b/packages/onramp-kit/README.md index b46ae5c49..49e4fbcf8 100644 --- a/packages/onramp-kit/README.md +++ b/packages/onramp-kit/README.md @@ -1,4 +1,4 @@ -# OnRamp Kit +# Onramp Kit [![NPM Version](https://badge.fury.io/js/%40safe-global%2Fonramp-kit.svg)](https://badge.fury.io/js/%40safe-global%2Fonramp-kit) [![GitHub Release](https://img.shields.io/github/release/safe-global/safe-core-sdk.svg?style=flat)](https://github.com/safe-global/safe-core-sdk/releases) @@ -6,16 +6,24 @@ The Onramp Kit allows users to buy cryptocurrencies using a credit card and other payment options. -## Reference +## Documentation -- [OnRamp Kit integration guides](https://docs.safe.global/safe-core-aa-sdk/onramp-kit) +- [Onramp Kit integration guides](https://docs.safe.global/sdk/onramp-kit) -- [OnRamp Kit reference](https://docs.safe.global/reference/onramp-kit) +- [Onramp Kit reference](https://docs.safe.global/sdk/onramp-kit/reference) ## Example [Check a functional demo](https://github.com/safe-global/safe-core-sdk/tree/main/packages/onramp-kit/example) using the `onramp-kit` +## Need Help or Have Questions? + +If you have any doubts, questions, or need assistance, feel free to reach out! [Here you will find how to get support.](https://github.com/safe-global/safe-core-sdk/tree/main/SUPPORT.md) + +## Contributing + +Please read our [contribution guidelines](https://github.com/safe-global/safe-core-sdk/tree/main/CONTRIBUTING.md) before submitting any changes. We appreciate your help! 🙌 + ## License This library is [released under MIT](https://github.com/safe-global/safe-core-sdk/blob/main/LICENSE.md). diff --git a/packages/onramp-kit/example/client/.env.sample b/packages/onramp-kit/example/client/.env.sample index b3166dbe1..cbe051c43 100644 --- a/packages/onramp-kit/example/client/.env.sample +++ b/packages/onramp-kit/example/client/.env.sample @@ -8,6 +8,7 @@ VITE_STRIPE_PUBLIC_KEY= VITE_SAFE_STRIPE_BACKEND_BASE_URL= # Configure the Monerium client ID. You need to get one from Monerium. +# Add the client ID for the authorization code flow here (not the one for the client credentials flow). # More info here: # https://monerium.dev/docs/getting-started/create-app VITE_MONERIUM_CLIENT_ID= diff --git a/packages/onramp-kit/example/client/package.json b/packages/onramp-kit/example/client/package.json index c54925480..32a3674ae 100644 --- a/packages/onramp-kit/example/client/package.json +++ b/packages/onramp-kit/example/client/package.json @@ -11,7 +11,7 @@ "dependencies": { "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.5", - "@monerium/sdk": "^2.9.0", + "@monerium/sdk": "^2.12.0", "@mui/material": "^5.15.15", "@safe-global/auth-kit": "file:../../../auth-kit", "@safe-global/onramp-kit": "file:../../", diff --git a/packages/onramp-kit/example/client/src/AuthContext.tsx b/packages/onramp-kit/example/client/src/AuthContext.tsx index d1f3c5430..ca4c401b9 100644 --- a/packages/onramp-kit/example/client/src/AuthContext.tsx +++ b/packages/onramp-kit/example/client/src/AuthContext.tsx @@ -38,7 +38,7 @@ const AuthProvider = ({ children }: AuthContextProviderProps) => { const options: SafeAuthInitOptions = { enableLogging: true, showWidgetButton: false, - chainConfig: { chainId: '0x5', rpcTarget: 'https://rpc.ankr.com/eth_goerli' } + chainConfig: { chainId: '0xaa36a7', rpcTarget: 'https://sepolia.gateway.tenderly.co' } } await authPack.init(options) diff --git a/packages/onramp-kit/example/client/src/components/monerium/Connected.tsx b/packages/onramp-kit/example/client/src/components/monerium/Connected.tsx index 8e6e0630b..969f063a1 100644 --- a/packages/onramp-kit/example/client/src/components/monerium/Connected.tsx +++ b/packages/onramp-kit/example/client/src/components/monerium/Connected.tsx @@ -31,7 +31,9 @@ function Connected({ authContext, orderState, safe, onLogout, onTransfer }: Conn {isLoading ? ( - + {orderState && [OrderState.placed, OrderState.pending].includes(orderState) && ( + + )} {orderState && ( <> {orderState === OrderState.placed && Order placed} diff --git a/packages/onramp-kit/example/client/src/components/monerium/Monerium.tsx b/packages/onramp-kit/example/client/src/components/monerium/Monerium.tsx index b96d730c3..c97844f30 100644 --- a/packages/onramp-kit/example/client/src/components/monerium/Monerium.tsx +++ b/packages/onramp-kit/example/client/src/components/monerium/Monerium.tsx @@ -1,8 +1,7 @@ import { useState, useEffect } from 'react' -import { ethers } from 'ethers' import { AuthContext, OrderState, PaymentStandard } from '@monerium/sdk' import { Box } from '@mui/material' -import Safe, { EthersAdapter } from '@safe-global/protocol-kit' +import Safe from '@safe-global/protocol-kit' import { useAuth } from '../../AuthContext' import { MoneriumPack, SafeMoneriumClient } from '@safe-global/onramp-kit' @@ -23,13 +22,8 @@ function Monerium() { ;(async () => { if (!authProvider || !selectedSafe) return - const provider = new ethers.BrowserProvider(authProvider) - - const safeOwner = await provider.getSigner() - const ethAdapter = new EthersAdapter({ ethers, signerOrProvider: safeOwner }) - - const protocolKit = await Safe.create({ - ethAdapter: ethAdapter, + const protocolKit = await Safe.init({ + provider: authProvider, safeAddress: selectedSafe, isL1SafeSingleton: true }) diff --git a/packages/onramp-kit/example/server/.gitignore b/packages/onramp-kit/example/server/.gitignore index 776f8bc85..0bbbcb2a4 100644 --- a/packages/onramp-kit/example/server/.gitignore +++ b/packages/onramp-kit/example/server/.gitignore @@ -25,6 +25,3 @@ build npm-debug.log* yarn-debug.log* yarn-error.log* - -typechain -typechain-types diff --git a/packages/onramp-kit/example/server/package.json b/packages/onramp-kit/example/server/package.json index 67e30dc85..d2d50c425 100644 --- a/packages/onramp-kit/example/server/package.json +++ b/packages/onramp-kit/example/server/package.json @@ -29,6 +29,6 @@ "@types/node": "^20.12.5", "nodemon": "^3.1.0", "ts-node": "^10.9.2", - "typescript": "^4.9.5" + "typescript": "^5.3.2" } } diff --git a/packages/onramp-kit/example/server/yarn.lock b/packages/onramp-kit/example/server/yarn.lock index 60e772fcd..824bd2083 100644 --- a/packages/onramp-kit/example/server/yarn.lock +++ b/packages/onramp-kit/example/server/yarn.lock @@ -1183,10 +1183,10 @@ type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" -typescript@^4.9.5: - version "4.9.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" - integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== +typescript@^5.3.2: + version "5.4.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.5.tgz#42ccef2c571fdbd0f6718b1d1f5e6e5ef006f611" + integrity sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ== undefsafe@^2.0.5: version "2.0.5" diff --git a/packages/onramp-kit/jest.config.js b/packages/onramp-kit/jest.config.js index 2f1f502fb..919893179 100644 --- a/packages/onramp-kit/jest.config.js +++ b/packages/onramp-kit/jest.config.js @@ -7,7 +7,6 @@ const config = { '^.+\\.ts?$': 'ts-jest' }, moduleNameMapper: { - '^@safe-global/protocol-kit/typechain/(.*)$': '/../protocol-kit/typechain/$1', '^@safe-global/protocol-kit/(.*)$': '/../protocol-kit/src/$1', '^@safe-global/onramp-kit/(.*)$': '/src/$1' } diff --git a/packages/onramp-kit/package.json b/packages/onramp-kit/package.json index f69691f79..7aee73ef0 100644 --- a/packages/onramp-kit/package.json +++ b/packages/onramp-kit/package.json @@ -1,6 +1,6 @@ { "name": "@safe-global/onramp-kit", - "version": "3.0.4", + "version": "3.0.4-alpha.0", "description": "Onramp library", "main": "dist/src/index.js", "types": "dist/src/index.d.ts", @@ -35,13 +35,13 @@ "access": "public" }, "dependencies": { - "@monerium/sdk": "^2.9.0", - "@safe-global/api-kit": "^2.3.2", - "@safe-global/protocol-kit": "^3.1.1", - "@safe-global/safe-core-sdk-types": "^4.1.1", + "@monerium/sdk": "^2.12.0", + "@safe-global/api-kit": "^2.3.2-alpha.0", + "@safe-global/protocol-kit": "^4.0.0-alpha.0", + "@safe-global/safe-core-sdk-types": "^5.0.0-alpha.0", "@stripe/crypto": "^0.0.4", "@stripe/stripe-js": "^1.54.2", - "ethers": "^6.7.1" + "ethers": "^6.12.1" }, "devDependencies": { "events": "^3.3.0", diff --git a/packages/onramp-kit/src/packs/monerium/SafeMoneriumClient.test.ts b/packages/onramp-kit/src/packs/monerium/SafeMoneriumClient.test.ts index 45865b363..fd29fbd2d 100644 --- a/packages/onramp-kit/src/packs/monerium/SafeMoneriumClient.test.ts +++ b/packages/onramp-kit/src/packs/monerium/SafeMoneriumClient.test.ts @@ -1,7 +1,10 @@ -import { hashMessage } from 'ethers' +import { Contract, hashMessage } from 'ethers' import { PaymentStandard } from '@monerium/sdk' import Safe, * as protocolKitPackage from '@safe-global/protocol-kit' -import { OperationType } from '@safe-global/safe-core-sdk-types' +import { + OperationType, + signMessageLib_1_4_1_ContractArtifacts +} from '@safe-global/safe-core-sdk-types' import SafeApiKit from '@safe-global/api-kit' import { SafeMoneriumClient } from './SafeMoneriumClient' @@ -41,12 +44,12 @@ describe('SafeMoneriumClient', () => { beforeEach(() => { jest.clearAllMocks() protocolKit.getChainId = jest.fn().mockResolvedValue(5) - protocolKit.getEthAdapter = jest.fn().mockReturnValue({ + protocolKit.getSafeProvider = jest.fn().mockReturnValue({ call: jest.fn().mockImplementation(async () => MAGIC_VALUE), getSignerAddress: jest.fn().mockResolvedValue('0xSignerAddress') }) - protocolKit.getEthAdapter.call = jest.fn().mockImplementation(async () => MAGIC_VALUE) + protocolKit.getSafeProvider.call = jest.fn().mockImplementation(async () => MAGIC_VALUE) safeMoneriumClient = new SafeMoneriumClient( { environment: 'sandbox', clientId: 'mockClientId', redirectUrl: 'http://mockUrl' }, protocolKit @@ -116,7 +119,7 @@ describe('SafeMoneriumClient', () => { it('should allow to check if a message is NOT signed in the smart contract if the promise is fulfilled', async () => { // Promise fulfilled without signature - protocolKit.getEthAdapter().call = jest.fn().mockImplementation(async () => '0x') + protocolKit.getSafeProvider().call = jest.fn().mockImplementation(async () => '0x') const isMessageSigned = await safeMoneriumClient.isMessageSigned( '0xSafeAddress', @@ -136,7 +139,7 @@ describe('SafeMoneriumClient', () => { } // promise is rejected with the signature - protocolKit.getEthAdapter().call = jest + protocolKit.getSafeProvider().call = jest .fn() .mockImplementation(() => Promise.reject(new EthersError('execution reverted: "Hash not approved"', MAGIC_VALUE)) @@ -160,7 +163,7 @@ describe('SafeMoneriumClient', () => { } // promise is rejected without a signature - protocolKit.getEthAdapter().call = jest + protocolKit.getSafeProvider().call = jest .fn() .mockImplementation(() => Promise.reject(new EthersError('execution reverted: "Hash not approved"', '0x')) @@ -220,11 +223,18 @@ describe('SafeMoneriumClient', () => { } jest.spyOn(protocolKitPackage, 'getSignMessageLibContract').mockResolvedValueOnce({ + safeVersion: '1.3.0', + contractName: 'signMessageLibVersion', + contract: new Contract('0x0000000000000000000000000000000000000001', []), + safeProvider: protocolKit.getSafeProvider() as protocolKitPackage.SafeProvider, encode: jest.fn(), + contractAbi: signMessageLib_1_4_1_ContractArtifacts.abi, + contractAddress: '', getAddress: jest.fn(), getMessageHash: jest.fn(), signMessage: jest.fn(), - estimateGas: jest.fn() + estimateGas: jest.fn(), + init: jest.fn() }) protocolKit.createTransaction = jest.fn().mockResolvedValueOnce({ @@ -258,7 +268,7 @@ describe('SafeMoneriumClient', () => { it('should map the protocol kit chainId to the Monerium Chain types', async () => { protocolKit.getChainId = jest.fn().mockResolvedValueOnce(1n) expect(await safeMoneriumClient.getChain()).toBe('ethereum') - protocolKit.getChainId = jest.fn().mockResolvedValueOnce(5n) + protocolKit.getChainId = jest.fn().mockResolvedValueOnce(11155111n) expect(await safeMoneriumClient.getChain()).toBe('ethereum') protocolKit.getChainId = jest.fn().mockResolvedValueOnce(100n) expect(await safeMoneriumClient.getChain()).toBe('gnosis') @@ -275,8 +285,8 @@ describe('SafeMoneriumClient', () => { it('should map the protocol kit chainId to the Monerium Network types', async () => { protocolKit.getChainId = jest.fn().mockResolvedValueOnce(1n) expect(await safeMoneriumClient.getNetwork()).toBe('mainnet') - protocolKit.getChainId = jest.fn().mockResolvedValueOnce(5n) - expect(await safeMoneriumClient.getNetwork()).toBe('goerli') + protocolKit.getChainId = jest.fn().mockResolvedValueOnce(11155111n) + expect(await safeMoneriumClient.getNetwork()).toBe('sepolia') protocolKit.getChainId = jest.fn().mockResolvedValueOnce(100n) expect(await safeMoneriumClient.getNetwork()).toBe('mainnet') protocolKit.getChainId = jest.fn().mockResolvedValueOnce(10200n) diff --git a/packages/onramp-kit/src/packs/monerium/SafeMoneriumClient.ts b/packages/onramp-kit/src/packs/monerium/SafeMoneriumClient.ts index c1037a803..a9b891bf9 100644 --- a/packages/onramp-kit/src/packs/monerium/SafeMoneriumClient.ts +++ b/packages/onramp-kit/src/packs/monerium/SafeMoneriumClient.ts @@ -10,18 +10,14 @@ import { placeOrderMessage, ClassOptions } from '@monerium/sdk' -import Safe, { getSignMessageLibContract } from '@safe-global/protocol-kit' +import Safe, { getSignMessageLibContract, SafeProvider } from '@safe-global/protocol-kit' import SafeApiKit from '@safe-global/api-kit' import { decodeSignatureData, getErrorMessage, parseIsValidSignatureErrorResponse } from '@safe-global/onramp-kit/lib/errors' -import { - EthAdapter, - OperationType, - SafeMultisigTransactionResponse -} from '@safe-global/safe-core-sdk-types' +import { OperationType, SafeMultisigTransactionResponse } from '@safe-global/safe-core-sdk-types' import { EIP_1271_BYTES_INTERFACE, @@ -33,7 +29,7 @@ import { SafeMoneriumOrder } from './types' export class SafeMoneriumClient extends MoneriumClient { #protocolKit: Safe - #ethAdapter: EthAdapter + #safeProvider: SafeProvider /** * Constructor where the Monerium environment and the Protocol kit instance are set @@ -44,7 +40,7 @@ export class SafeMoneriumClient extends MoneriumClient { super(moneriumOptions) this.#protocolKit = protocolKit - this.#ethAdapter = protocolKit.getEthAdapter() + this.#safeProvider = protocolKit.getSafeProvider() } /** @@ -123,7 +119,7 @@ export class SafeMoneriumClient extends MoneriumClient { const safeVersion = await this.#protocolKit.getContractVersion() const signMessageContract = await getSignMessageLibContract({ - ethAdapter: this.#ethAdapter, + safeProvider: this.#safeProvider, safeVersion }) @@ -151,7 +147,7 @@ export class SafeMoneriumClient extends MoneriumClient { safeAddress, safeTransactionData: safeTransaction.data, safeTxHash, - senderAddress: (await this.#ethAdapter.getSignerAddress()) || '', + senderAddress: (await this.#safeProvider.getSignerAddress()) || '', senderSignature: senderSignature.data }) @@ -211,12 +207,12 @@ export class SafeMoneriumClient extends MoneriumClient { ]) const checks = [ - this.#ethAdapter.call({ + this.#safeProvider.call({ from: safeAddress, to: safeAddress, data: eip1271data }), - this.#ethAdapter.call({ + this.#safeProvider.call({ from: safeAddress, to: safeAddress, data: eip1271BytesData diff --git a/packages/protocol-kit/LICENSE.md b/packages/protocol-kit/LICENSE.md index 310e6e37c..0e923d187 100644 --- a/packages/protocol-kit/LICENSE.md +++ b/packages/protocol-kit/LICENSE.md @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021-2023 Safe Ecosystem Foundation +Copyright (c) 2021-2024 Safe Ecosystem Foundation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/packages/protocol-kit/README.md b/packages/protocol-kit/README.md index 355f1616c..27b18df28 100644 --- a/packages/protocol-kit/README.md +++ b/packages/protocol-kit/README.md @@ -4,20 +4,22 @@ [![GitHub Release](https://img.shields.io/github/release/safe-global/safe-core-sdk.svg?style=flat)](https://github.com/safe-global/safe-core-sdk/releases) [![GitHub](https://img.shields.io/github/license/safe-global/safe-core-sdk)](https://github.com/safe-global/safe-core-sdk/blob/main/LICENSE.md) -Software development kit that facilitates the interaction with the [Safe contracts](https://github.com/safe-global/safe-contracts). +Software development kit that facilitates the interaction with [Safe Smart Accounts](https://github.com/safe-global/safe-smart-account). ## Table of contents +- [Documentation](#documentation) - [Installation](#installation) -- [Build](#build) -- [Tests](#tests) -- [Getting Started](#getting-started) -- [Safe Factory API Reference](#factory-api) -- [Safe Core SDK API Reference](#sdk-api) +- [Quick Start](#quick-start) +- [Need Help or Have Questions?](#need-help-or-have-questions) +- [Contributing](#contributing) - [License](#license) -- [Contributors](#contributors) -## Installation +## Documentation + +Head to the [Protocol Kit docs](https://docs.safe.global/sdk/protocol-kit) to learn more about how to use this SDK. + +## Installation Install the package with yarn or npm: @@ -26,285 +28,24 @@ yarn add @safe-global/protocol-kit npm install @safe-global/protocol-kit ``` -## Build - -Build the package with yarn or npm: - -```bash -yarn build -npm run build -``` - -## Tests - -Create a `.env` file with environment variables. You can use the `.env.example` file as a reference. - -Test the package with yarn or npm: - -```bash -yarn test -npm run test -``` - -## Getting Started - -The following steps show how to set up the Protocol Kit, deploy a new Safe, create a Safe transaction, generate the required signatures from owners and execute the transaction. However, using the Protocol Kit alone will not allow for the collection of owner signatures off-chain. To do this and be able to see and confirm the pending transactions shown in the [Safe Web App](https://app.safe.global/), it is recommended that you follow this other [guide](/guides/integrating-the-safe-core-sdk.md) that covers the use of the Protocol Kit, combined with the API Kit. - -### 1. Instantiate an EthAdapter - -First of all, we need to create an `EthAdapter`, which contains all the required utilities for the SDKs to interact with the blockchain. It acts as a wrapper for [web3.js](https://web3js.readthedocs.io/) or [ethers.js](https://docs.ethers.org/v6/) Ethereum libraries. - -Depending on the library used by the Dapp, there are two options: - -- [Create an `EthersAdapter` instance](https://github.com/safe-global/safe-core-sdk/tree/main/packages/protocol-kit/src/adapters/ethers) -- [Create a `Web3Adapter` instance](https://github.com/safe-global/safe-core-sdk/tree/main/packages/protocol-kit/src/adapters/web3) - -Once the instance of `EthersAdapter` or `Web3Adapter` is created, it can be used in the SDK initialization. - -### 2. Deploy a new Safe - -To deploy a new Safe account instantiate the `SafeFactory` class and call the `deploySafe` method with the right params to configure the new Safe. This includes defining the list of owners and the threshold of the Safe. A Safe account with three owners and threshold equal three will be used as the starting point for this example but any Safe configuration is valid. - -```js -import Safe, { SafeFactory, SafeAccountConfig } from '@safe-global/protocol-kit' - -const safeFactory = await SafeFactory.create({ ethAdapter }) - -const owners = ['0x
', '0x
', '0x
'] -const threshold = 3 -const safeAccountConfig: SafeAccountConfig = { - owners, - threshold - // ... -} - -const safeSdk: Safe = await safeFactory.deploySafe({ safeAccountConfig }) -``` - -The `deploySafe` method executes a transaction from the `owner1` account, deploys a new Safe and returns an instance of the Protocol Kit connected to the new Safe. Check the `deploySafe` method in the [API Reference](#factory-api) for more details on additional configuration parameters and callbacks. - -Call the `getAddress` method, for example, to check the address of the newly deployed Safe. - -```js -const newSafeAddress = await safeSdk.getAddress() -``` - -To instantiate the Protocol Kit from an existing Safe just pass to it an instance of the `EthAdapter` class and the Safe address. - -```js -import Safe from '@safe-global/protocol-kit' - -const safeSdk: Safe = await Safe.create({ ethAdapter: ethAdapterOwner1, safeAddress }) -``` - -Check the `create` method in the [API Reference](#sdk-api) for more details on additional configuration parameters. - -### 3. Create a Safe transaction - -```js -import { MetaTransactionData } from '@safe-global/safe-core-sdk-types' - -const safeTransactionData: MetaTransactionData = { - to: '0x
', - value: '', - data: '0x' -} -const safeTransaction = await safeSdk.createTransaction({ transactions: [safeTransactionData] }) -``` - -Check the `createTransaction` method in the [API Reference](#sdk-api) for additional details on creating MultiSend transactions. - -Before executing this transaction, it must be signed by the owners and this can be done off-chain or on-chain. In this example `owner1` will sign it off-chain, `owner2` will sign it on-chain and `owner3` will execute it (the executor also signs the transaction transparently). - -### 3.a. Off-chain signatures - -The `owner1` account signs the transaction off-chain. - -```js -const signedSafeTransaction = await safeSdk.signTransaction(safeTransaction) -``` - -Because the signature is off-chain, there is no interaction with the contract and the signature becomes available at `signedSafeTransaction.signatures`. - -### 3.b. On-chain signatures - -To connect `owner2` to the Safe we need to create a new instance of the class `EthAdapter` passing to its constructor the owner we would like to connect. After `owner2` account is connected to the SDK as a signer the transaction hash will be approved on-chain. - -```js -const ethAdapterOwner2 = new EthersAdapter({ ethers, signerOrProvider: owner2 }) -const safeSdk2 = await safeSdk.connect({ ethAdapter: ethAdapterOwner2, safeAddress }) -const txHash = await safeSdk2.getTransactionHash(safeTransaction) -const approveTxResponse = await safeSdk2.approveTransactionHash(txHash) -await approveTxResponse.transactionResponse?.wait() -``` - -### 4. Transaction execution - -Lastly, `owner3` account is connected to the SDK as a signer and executor of the Safe transaction to execute it. - -```js -const ethAdapterOwner3 = new EthersAdapter({ ethers, signerOrProvider: owner3 }) -const safeSdk3 = await safeSdk2.connect({ ethAdapter: ethAdapterOwner3, safeAddress }) -const executeTxResponse = await safeSdk3.executeTransaction(safeTransaction) -await executeTxResponse.transactionResponse?.wait() -``` - -All the signatures used to execute the transaction are now available at `safeTransaction.signatures`. - -## Safe Factory API Reference - -### create - -Returns an instance of the Safe Factory. - -```js -import { SafeFactory } from '@safe-global/protocol-kit' - -const safeFactory = await SafeFactory.create({ ethAdapter }) -``` - -- The `isL1SafeSingleton` flag - - There are two versions of the Safe contracts: [Safe.sol](https://github.com/safe-global/safe-contracts/blob/v1.4.1/contracts/Safe.sol) that does not trigger events in order to save gas and [SafeL2.sol](https://github.com/safe-global/safe-contracts/blob/v1.4.1/contracts/SafeL2.sol) that does, which is more appropriate for L2 networks. - - By default `Safe.sol` will be only used on Ethereum Mainnet. For the rest of the networks where the Safe contracts are already deployed, the `SafeL2.sol` contract will be used unless you add the `isL1SafeSingleton` flag to force the use of the `Safe.sol` contract. - - ```js - const safeFactory = await SafeFactory.create({ ethAdapter, isL1SafeSingleton: true }) - ``` - -- The `contractNetworks` property - - If the Safe contracts are not deployed to your current network, the `contractNetworks` property will be required to point to the addresses of the Safe contracts previously deployed by you. - - ```js - import { ContractNetworksConfig } from '@safe-global/protocol-kit' - - const chainId = await ethAdapter.getChainId() - const contractNetworks: ContractNetworksConfig = { - [chainId]: { - safeSingletonAddress: '', - safeProxyFactoryAddress: '', - multiSendAddress: '', - multiSendCallOnlyAddress: '', - fallbackHandlerAddress: '', - signMessageLibAddress: '', - createCallAddress: '', - simulateTxAccessorAddress: '', - safeSingletonAbi: '', // Optional. Only needed with web3.js - safeProxyFactoryAbi: '', // Optional. Only needed with web3.js - multiSendAbi: '', // Optional. Only needed with web3.js - multiSendCallOnlyAbi: '', // Optional. Only needed with web3.js - fallbackHandlerAbi: '', // Optional. Only needed with web3.js - signMessageLibAbi: '', // Optional. Only needed with web3.js - createCallAbi: '', // Optional. Only needed with web3.js - simulateTxAccessorAbi: '' // Optional. Only needed with web3.js - } - } - - const safeFactory = await SafeFactory.create({ ethAdapter, contractNetworks }) - ``` - -- The `safeVersion` property - - The `SafeFactory` constructor also accepts the `safeVersion` property to specify the Safe contract version that will be deployed. This string can take the values `1.0.0`, `1.1.1`, `1.2.0`, `1.3.0` or `1.4.1`. If not specified, the `DEFAULT_SAFE_VERSION` value will be used. - - ```js - const safeVersion = 'X.Y.Z' - const safeFactory = await SafeFactory.create({ ethAdapter, safeVersion }) - ``` - -### deploySafe - -Deploys a new Safe and returns an instance of the Protocol Kit connected to the deployed Safe. The Singleton address, contract version and layer instance (`Safe.sol` or `SafeL2.sol`) of the deployed Safe will depend on the configuration used to create the `safeFactory`. - -```js -const safeAccountConfig: SafeAccountConfig = { - owners, - threshold, - to, // Optional - data, // Optional - fallbackHandler, // Optional - paymentToken, // Optional - payment, // Optional - paymentReceiver // Optional -} - -const safeSdk = await safeFactory.deploySafe({ safeAccountConfig }) -``` - -This method can optionally receive the `saltNonce` parameter. - -```js -const safeAccountConfig: SafeAccountConfig = { - owners, - threshold, - to, // Optional - data, // Optional - fallbackHandler, // Optional - paymentToken, // Optional - payment, // Optional - paymentReceiver // Optional -} - -const saltNonce = '' - -const safeSdk = await safeFactory.deploySafe({ safeAccountConfig, saltNonce }) -``` - -Optionally, some properties can be passed as execution options: - -```js -const options: Web3TransactionOptions = { - from, // Optional - gas, // Optional - gasPrice, // Optional - maxFeePerGas, // Optional - maxPriorityFeePerGas // Optional - nonce // Optional -} -``` - -```js -const options: EthersTransactionOptions = { - from, // Optional - gasLimit, // Optional - gasPrice, // Optional - maxFeePerGas, // Optional - maxPriorityFeePerGas // Optional - nonce // Optional -} -``` - -```js -const safeSdk = await safeFactory.deploySafe({ safeAccountConfig, safeDeploymentConfig, options }) -``` - -It can also take an optional callback which receives the `txHash` of the Safe deployment transaction prior to returning a new instance of the Protocol Kit: - -```js -const callback = (txHash: string): void => { - console.log({ txHash }) -} - -const safeSdk = await safeFactory.deploySafe({ safeAccountConfig, callback }) -``` - -## Safe Core SDK API Reference - -### create +## Quick Start -Returns an instance of the Protocol Kit connected to a Safe. The provided Safe must be a `safeAddress` or a `predictedSafe`. +- `provider`: You can set an EIP-1193 compatible provider or an HTTP/WebSocket RPC URL. +- `signer`: This is an optional parameter. It should be the provider's address you want to use or a private key. If not set, it will try to fetch a connected account from the provider. -Initialization of a deployed Safe using the `safeAddress` property: +Loading an already deployed Safe, using the `safeAddress` property: ```js import Safe from '@safe-global/protocol-kit' -const safeSdk = await Safe.create({ ethAdapter, safeAddress }) +const protocolKit = await Safe.init({ + provider, + signer, + safeAddress +}) ``` -Initialization of a not deployed Safe using the `predictedSafe` property. Because Safes are deployed in a deterministic way, passing a `predictedSafe` will allow to initialize the SDK with the Safe configuration and use it to some extent before it is deployed: +Initialization of an undeployed Safe using the `predictedSafe` property. Because Safes are deployed in a deterministic way, passing a `predictedSafe` will allow to initialize the SDK with the Safe configuration and use it to some extent before it's deployed: ```js import Safe, { PredictedSafeProps } from '@safe-global/protocol-kit' @@ -314,719 +55,21 @@ const predictedSafe: PredictedSafeProps = { safeDeploymentConfig } -const safeSdk = await Safe.create({ ethAdapter, predictedSafe }) -``` - -- The `isL1SafeSingleton` flag - - There are two versions of the Safe contracts: [Safe.sol](https://github.com/safe-global/safe-contracts/blob/v1.4.1/contracts/Safe.sol) that does not trigger events in order to save gas and [SafeL2.sol](https://github.com/safe-global/safe-contracts/blob/v1.4.1/contracts/SafeL2.sol) that does, which is more appropriate for L2 networks. - - By default `Safe.sol` will be only used on Ethereum Mainnet. For the rest of the networks where the Safe contracts are already deployed, the `SafeL2.sol` contract will be used unless you add the `isL1SafeSingleton` flag to force the use of the `Safe.sol` contract. - - ```js - const safeSdk = await Safe.create({ ethAdapter, safeAddress, isL1SafeSingleton: true }) - ``` - -- The `contractNetworks` property - - If the Safe contracts are not deployed to your current network, the `contractNetworks` property will be required to point to the addresses of the Safe contracts previously deployed by you. - - ```js - import { ContractNetworksConfig } from '@safe-global/protocol-kit' - - const chainId = await ethAdapter.getChainId() - const contractNetworks: ContractNetworksConfig = { - [chainId]: { - safeSingletonAddress: '', - safeProxyFactoryAddress: '', - multiSendAddress: '', - multiSendCallOnlyAddress: '', - fallbackHandlerAddress: '', - signMessageLibAddress: '', - createCallAddress: '', - simulateTxAccessorAddress: '', - safeSingletonAbi: '', // Optional. Only needed with web3.js - safeProxyFactoryAbi: '', // Optional. Only needed with web3.js - multiSendAbi: '', // Optional. Only needed with web3.js - multiSendCallOnlyAbi: '', // Optional. Only needed with web3.js - fallbackHandlerAbi: '', // Optional. Only needed with web3.js - signMessageLibAbi: '', // Optional. Only needed with web3.js - createCallAbi: '', // Optional. Only needed with web3.js - simulateTxAccessorAbi: '' // Optional. Only needed with web3.js - } - } - - const safeSdk = await Safe.create({ ethAdapter, safeAddress, contractNetworks }) - ``` - -### connect - -Returns a new instance of the Protocol Kit connected to a new Safe or a new Signer. The new connected signer can be passed via the `ethAdapter` property while the new connected Safe can be passed using a `safeAddress` or a `predictedSafe`. - -Connection of a deployed Safe using the `safeAddress` property: - -```js -const safeSdk = await safeSdk.connect({ ethAdapter, safeAddress }) -``` - -Connection of a not deployed Safe using the `predictedSafe` property. Because Safes are deployed in a deterministic way, passing a `predictedSafe` will allow to connect a Safe to the SDK with the Safe configuration: - -```js -import { PredictedSafeProps } from '@safe-global/protocol-kit' - -const predictedSafe: PredictedSafeProps = { - safeAccountConfig, - safeDeploymentConfig -} - -const safeSdk = await safeSdk.connect({ ethAdapter, predictedSafe }) -``` - -- The `isL1SafeSingleton` flag - - There are two versions of the Safe contracts: [Safe.sol](https://github.com/safe-global/safe-contracts/blob/v1.4.1/contracts/Safe.sol) that does not trigger events in order to save gas and [SafeL2.sol](https://github.com/safe-global/safe-contracts/blob/v1.4.1/contracts/SafeL2.sol) that does, which is more appropriate for L2 networks. - - By default `Safe.sol` will be only used on Ethereum Mainnet. For the rest of the networks where the Safe contracts are already deployed, the `SafeL2.sol` contract will be used unless you add the `isL1SafeSingleton` flag to force the use of the `Safe.sol` contract. - - ```js - const safeSdk = await Safe.connect({ ethAdapter, safeAddress, isL1SafeSingleton: true }) - ``` - -- The `contractNetworks` property - - If the Safe contracts are not deployed to your current network, the `contractNetworks` property will be required to point to the addresses of the Safe contracts previously deployed by you. - - ```js - import { ContractNetworksConfig } from '@safe-global/protocol-kit' - - const chainId = await ethAdapter.getChainId() - const contractNetworks: ContractNetworksConfig = { - [chainId]: { - safeSingletonAddress: '', - safeProxyFactoryAddress: '', - multiSendAddress: '', - multiSendCallOnlyAddress: '', - fallbackHandlerAddress: '', - signMessageLibAddress: '', - createCallAddress: '', - simulateTxAccessorAddress: '', - safeSingletonAbi: '', // Optional. Only needed with web3.js - safeProxyFactoryAbi: '', // Optional. Only needed with web3.js - multiSendAbi: '', // Optional. Only needed with web3.js - multiSendCallOnlyAbi: '', // Optional. Only needed with web3.js - fallbackHandlerAbi: '', // Optional. Only needed with web3.js - signMessageLibAbi: '', // Optional. Only needed with web3.js - createCallAbi: '', // Optional. Only needed with web3.js - simulateTxAccessorAbi: '' // Optional. Only needed with web3.js - } - } - const safeSdk = await Safe.connect({ ethAdapter, safeAddress, contractNetworks }) - ``` - -### getAddress - -Returns the address of the current SafeProxy contract. - -```js -const safeAddress = await safeSdk.getAddress() -``` - -### getContractVersion - -Returns the Safe Singleton contract version. - -```js -const contractVersion = await safeSdk.getContractVersion() -``` - -### getOwners - -Returns the list of Safe owner accounts. - -```js -const ownerAddresses = await safeSdk.getOwners() -``` - -### getNonce - -Returns the Safe nonce. - -```js -const nonce = await safeSdk.getNonce() -``` - -### getThreshold - -Returns the Safe threshold. - -```js -const threshold = await safeSdk.getThreshold() -``` - -### getChainId - -Returns the chainId of the connected network. - -```js -const chainId = await safeSdk.getChainId() -``` - -### getBalance - -Returns the ETH balance of the Safe. - -```js -const balance = await safeSdk.getBalance() -``` - -### getGuard - -Returns the enabled Safe guard or 0x address if no guards are enabled. - -```js -const guardAddress = await safeSdk.getGuard() -``` - -### getModules - -Returns the list of addresses of all the enabled Safe modules. - -```js -const moduleAddresses = await safeSdk.getModules() -``` - -### isModuleEnabled - -Checks if a specific Safe module is enabled for the current Safe. - -```js -const isEnabled = await safeSdk.isModuleEnabled(moduleAddress) -``` - -### isOwner - -Checks if a specific address is an owner of the current Safe. - -```js -const isOwner = await safeSdk.isOwner(address) -``` - -### createTransaction - -Returns a Safe transaction ready to be signed by the owners and executed. The Protocol Kit supports the creation of single Safe transactions but also MultiSend transactions. - -This method takes an array of `MetaTransactionData` objects that represent the individual transactions we want to include in our MultiSend transaction. - -When the array contains only one transaction, it is not wrapped in the MultiSend. - -```js -const transactions: MetaTransactionData[] = [ - { - to, - data, - value, - operation // Optional - }, - { - to, - data, - value, - operation // Optional - } - // ... -] -const safeTransaction = await safeSdk.createTransaction({ transactions }) -``` - -This method can also receive the `options` parameter to set the optional properties in the MultiSend transaction: - -```js -const transactions: MetaTransactionData[] = [ - { - to, - data, - value, - operation // Optional - }, - { - to, - data, - value, - operation // Optional - } - // ... -] -const options: SafeTransactionOptionalProps = { - safeTxGas, // Optional - baseGas, // Optional - gasPrice, // Optional - gasToken, // Optional - refundReceiver, // Optional - nonce // Optional -} -const safeTransaction = await safeSdk.createTransaction({ transactions, options }) -``` - -In addition, the optional `onlyCalls` parameter, which is `false` by default, allows to force the use of the `MultiSendCallOnly` instead of the `MultiSend` contract when sending a batch transaction: - -```js -const onlyCalls = true -const safeTransaction = await safeSdk.createTransaction({ - transactions, - options, - onlyCalls +const protocolKit = await Safe.init({ + provider, + signer, + predictedSafe }) ``` -If the optional properties are not manually set, the Safe transaction returned will have the default value for each one: - -- `operation`: `OperationType.Call` (0) is the default value. -- `safeTxGas`: The right gas estimation is the default value. -- `baseGas`: 0 is the default value. -- `gasPrice`: 0 is the default value. -- `gasToken`: 0x address is the default value. -- `refundReceiver`: 0x address is the default value. -- `nonce`: The current Safe nonce is the default value. - -Read more about [create transactions from a Safe](https://docs.safe.global/safe-core-aa-sdk/protocol-kit#making-a-transaction-from-a-safe). - -### createRejectionTransaction - -Returns a Safe transaction ready to be signed by the owners that invalidates the pending Safe transaction/s with a specific nonce. - -```js -const transactions: MetaTransactionData[] = [ - { - // ... - } -] -const safeTransaction = await safeSdk.createTransaction({ transactions }) -const rejectionTransaction = await safeSdk.createRejectionTransaction(safeTransaction.data.nonce) -``` - -### copyTransaction - -Copies a Safe transaction. - -```js -const safeTransaction1 = await safeSdk.createTransaction({ transactions }) -const safeTransaction2 = await copyTransaction(safeTransaction1) -``` - -### getTransactionHash - -Returns the transaction hash of a Safe transaction. - -```js -const transactions: MetaTransactionData[] = [ - { - // ... - } -] -const safeTransaction = await safeSdk.createTransaction({ transactions }) -const txHash = await safeSdk.getTransactionHash(safeTransaction) -``` - -### signHash - -Signs a hash using the current owner account. - -```js -const transactions: MetaTransactionData[] = [ - { - // ... - } -] -const safeTransaction = await safeSdk.createTransaction({ transactions }) -const txHash = await safeSdk.getTransactionHash(safeTransaction) -const signature = await safeSdk.signHash(txHash) -``` - -### signTypedData - -Signs a transaction according to the EIP-712 using the current signer account. - -```js -const transactions: MetaTransactionData[] = [ - { - // ... - } -] -const safeTransaction = await safeSdk.createTransaction({ transactions }) -const signature = await safeSdk.signTypedData(safeTransaction) -``` - -### signTransaction - -Returns a new `SafeTransaction` object that includes the signature of the current owner. `eth_sign` will be used by default to generate the signature. - -```js -const transactions: MetaTransactionData[] = [ - { - // ... - } -] -const safeTransaction = await safeSdk.createTransaction({ transactions }) -const signedSafeTransaction = await safeSdk.signTransaction(safeTransaction) -``` - -Optionally, an additional parameter can be passed to specify a different way of signing: - -```js -const signedSafeTransaction = await safeSdk.signTransaction( - safeTransaction, - SigningMethod.ETH_SIGN_TYPED_DATA -) -``` - -```js -const signedSafeTransaction = await safeSdk.signTransaction(safeTransaction, SigningMethod.ETH_SIGN) // default option. -``` - -### approveTransactionHash - -Approves a hash on-chain using the current owner account. - -```js -const transactions: MetaTransactionData[] = [ - { - // ... - } -] -const safeTransaction = await safeSdk.createTransaction({ transactions }) -const txHash = await safeSdk.getTransactionHash(safeTransaction) -const txResponse = await safeSdk.approveTransactionHash(txHash) -await txResponse.transactionResponse?.wait() -``` - -Optionally, some properties can be passed as execution options: - -```js -const options: Web3TransactionOptions = { - from, // Optional - gas, // Optional - gasPrice, // Optional - maxFeePerGas, // Optional - maxPriorityFeePerGas // Optional - nonce // Optional -} -``` - -```js -const options: EthersTransactionOptions = { - from, // Optional - gasLimit, // Optional - gasPrice, // Optional - maxFeePerGas, // Optional - maxPriorityFeePerGas // Optional - nonce // Optional -} -``` - -```js -const txResponse = await safeSdk.approveTransactionHash(txHash, options) -``` - -### getOwnersWhoApprovedTx - -Returns a list of owners who have approved a specific Safe transaction. - -```js -const transactions: MetaTransactionData[] = [ - { - // ... - } -] -const safeTransaction = await safeSdk.createTransaction({ transactions }) -const txHash = await safeSdk.getTransactionHash(safeTransaction) -const ownerAddresses = await safeSdk.getOwnersWhoApprovedTx(txHash) -``` - -### createEnableFallbackHandlerTx - -Returns the Safe transaction to enable the fallback handler. - -```js -const safeTransaction = await safeSdk.createEnableFallbackHandlerTx(fallbackHandlerAddress) -const txResponse = await safeSdk.executeTransaction(safeTransaction) -await txResponse.transactionResponse?.wait() -``` - -This method can optionally receive the `options` parameter: - -```js -const options: SafeTransactionOptionalProps = { - safeTxGas, // Optional - baseGas, // Optional - gasPrice, // Optional - gasToken, // Optional - refundReceiver, // Optional - nonce // Optional -} -const safeTransaction = await safeSdk.createEnableFallbackHandlerTx(fallbackHandlerAddress, options) -``` - -### createDisableFallbackHandlerTx - -Returns the Safe transaction to disable the fallback handler. - -```js -const safeTransaction = await safeSdk.createDisableFallbackHandlerTx() -const txResponse = await safeSdk.executeTransaction(safeTransaction) -await txResponse.transactionResponse?.wait() -``` - -This method can optionally receive the `options` parameter: - -```js -const options: SafeTransactionOptionalProps = { ... } -const safeTransaction = await safeSdk.createDisableFallbackHandlerTx(options) -``` - -### createEnableGuardTx - -Returns the Safe transaction to enable a Safe guard. - -```js -const safeTransaction = await safeSdk.createEnableGuardTx(guardAddress) -const txResponse = await safeSdk.executeTransaction(safeTransaction) -await txResponse.transactionResponse?.wait() -``` - -This method can optionally receive the `options` parameter: +## Need Help or Have Questions? -```js -const options: SafeTransactionOptionalProps = { - safeTxGas, // Optional - baseGas, // Optional - gasPrice, // Optional - gasToken, // Optional - refundReceiver, // Optional - nonce // Optional -} -const safeTransaction = await safeSdk.createEnableGuardTx(guardAddress, options) -``` - -### createDisableGuardTx - -Returns the Safe transaction to disable a Safe guard. - -```js -const safeTransaction = await safeSdk.createDisableGuardTx() -const txResponse = await safeSdk.executeTransaction(safeTransaction) -await txResponse.transactionResponse?.wait() -``` - -This method can optionally receive the `options` parameter: - -```js -const options: SafeTransactionOptionalProps = { ... } -const safeTransaction = await safeSdk.createDisableGuardTx(options) -``` - -### createEnableModuleTx - -Returns a Safe transaction ready to be signed that will enable a Safe module. - -```js -const safeTransaction = await safeSdk.createEnableModuleTx(moduleAddress) -const txResponse = await safeSdk.executeTransaction(safeTransaction) -await txResponse.transactionResponse?.wait() -``` - -This method can optionally receive the `options` parameter: - -```js -const options: SafeTransactionOptionalProps = { ... } -const safeTransaction = await safeSdk.createEnableModuleTx(moduleAddress, options) -``` - -### createDisableModuleTx - -Returns a Safe transaction ready to be signed that will disable a Safe module. - -```js -const safeTransaction = await safeSdk.createDisableModuleTx(moduleAddress) -const txResponse = await safeSdk.executeTransaction(safeTransaction) -await txResponse.transactionResponse?.wait() -``` - -This method can optionally receive the `options` parameter: - -```js -const options: SafeTransactionOptionalProps = { ... } -const safeTransaction = await safeSdk.createDisableModuleTx(moduleAddress, options) -``` - -### createAddOwnerTx - -Returns the Safe transaction to add an owner and optionally change the threshold. - -```js -const params: AddOwnerTxParams = { - ownerAddress, - threshold // Optional. If `threshold` is not provided the current threshold will not change. -} -const safeTransaction = await safeSdk.createAddOwnerTx(params) -const txResponse = await safeSdk.executeTransaction(safeTransaction) -await txResponse.transactionResponse?.wait() -``` - -This method can optionally receive the `options` parameter: - -```js -const options: SafeTransactionOptionalProps = { ... } -const safeTransaction = await safeSdk.createAddOwnerTx(params, options) -``` - -### createRemoveOwnerTx - -Returns the Safe transaction to remove an owner and optionally change the threshold. - -```js -const params: RemoveOwnerTxParams = { - ownerAddress, - newThreshold // Optional. If `newThreshold` is not provided, the current threshold will be decreased by one. -} -const safeTransaction = await safeSdk.createRemoveOwnerTx(params) -const txResponse = await safeSdk.executeTransaction(safeTransaction) -await txResponse.transactionResponse?.wait() -``` - -This method can optionally receive the `options` parameter: - -```js -const options: SafeTransactionOptionalProps = { ... } -const safeTransaction = await safeSdk.createRemoveOwnerTx(params, options) -``` - -### createSwapOwnerTx - -Returns the Safe transaction to replace an owner of the Safe with a new one. - -```js -const params: SwapOwnerTxParams = { - oldOwnerAddress, - newOwnerAddress -} -const safeTransaction = await safeSdk.createSwapOwnerTx(params) -const txResponse = await safeSdk.executeTransaction(safeTransaction) -await txResponse.transactionResponse?.wait() -``` - -This method can optionally receive the `options` parameter: - -```js -const options: SafeTransactionOptionalProps = { ... } -const safeTransaction = await safeSdk.createSwapOwnerTx(params, options) -``` - -### createChangeThresholdTx - -Returns the Safe transaction to change the threshold. - -```js -const safeTransaction = await safeSdk.createChangeThresholdTx(newThreshold) -const txResponse = await safeSdk.executeTransaction(safeTransaction) -await txResponse.transactionResponse?.wait() -``` - -This method can optionally receive the `options` parameter: - -```js -const options: SafeTransactionOptionalProps = { ... } -const safeTransaction = await safeSdk.createChangeThresholdTx(newThreshold, options) -``` - -### isValidTransaction - -Checks if a Safe transaction can be executed successfully with no errors. - -```js -const transactions: MetaTransactionData[] = [ - { - // ... - } -] -const safeTransaction = await safeSdk.createTransaction({ transactions }) -const isValidTx = await safeSdk.isValidTransaction(safeTransaction) -``` - -Optionally, some properties can be passed as execution options: - -```js -const options: Web3TransactionOptions = { - from, // Optional - gas, // Optional - gasPrice, // Optional - maxFeePerGas, // Optional - maxPriorityFeePerGas // Optional - nonce // Optional -} -``` - -```js -const options: EthersTransactionOptions = { - from, // Optional - gasLimit, // Optional - gasPrice, // Optional - maxFeePerGas, // Optional - maxPriorityFeePerGas // Optional - nonce // Optional -} -``` - -```js -const isValidTx = await safeSdk.isValidTransaction(safeTransaction, options) -``` - -### executeTransaction - -Executes a Safe transaction. - -```js -const transactions: MetaTransactionData[] = [ - { - // ... - } -] -const safeTransaction = await safeSdk.createTransaction({ transactions }) -const txResponse = await safeSdk.executeTransaction(safeTransaction) -await txResponse.transactionResponse?.wait() -``` - -Optionally, some properties can be passed as execution options: - -```js -const options: Web3TransactionOptions = { - from, // Optional - gas, // Optional - gasPrice, // Optional - maxFeePerGas, // Optional - maxPriorityFeePerGas // Optional - nonce // Optional -} -``` - -```js -const options: EthersTransactionOptions = { - from, // Optional - gasLimit, // Optional - gasPrice, // Optional - maxFeePerGas, // Optional - maxPriorityFeePerGas // Optional - nonce // Optional -} -``` - -```js -const txResponse = await safeSdk.executeTransaction(safeTransaction, options) -``` +If you have any doubts, questions, or need assistance, feel free to reach out! [Here you will find how to get support.](https://github.com/safe-global/safe-core-sdk/tree/main/SUPPORT.md) -## License +## Contributing -This library is released under MIT. +Please read our [contribution guidelines](https://github.com/safe-global/safe-core-sdk/tree/main/CONTRIBUTING.md) before submitting any changes. We appreciate your help! 🙌 -## Contributors +## License -- Germán Martínez ([germartinez](https://github.com/germartinez)) +This library is [released under MIT](https://github.com/safe-global/safe-core-sdk/blob/main/LICENSE.md). diff --git a/packages/protocol-kit/hardhat.config.ts b/packages/protocol-kit/hardhat.config.ts index 5ab637921..1d0aa7a5e 100644 --- a/packages/protocol-kit/hardhat.config.ts +++ b/packages/protocol-kit/hardhat.config.ts @@ -2,7 +2,6 @@ import '@nomicfoundation/hardhat-ethers' import 'hardhat-deploy' import 'hardhat-deploy-ethers' import 'tsconfig-paths/register' -import '@nomiclabs/hardhat-web3' import dotenv from 'dotenv' import { HardhatUserConfig, HttpNetworkUserConfig } from 'hardhat/types' import yargs from 'yargs' @@ -49,7 +48,6 @@ const config: HardhatUserConfig = { blockGasLimit: 100000000, gas: 100000000, accounts: [ - // Same as ganache-cli -d { balance: '100000000000000000000', privateKey: '0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d' @@ -94,7 +92,7 @@ const config: HardhatUserConfig = { }, sepolia: { ...sharedNetworkConfig, - url: 'https://rpc.ankr.com/eth_sepolia' + url: 'https://sepolia.gateway.tenderly.co' } }, //@ts-expect-error Type not found diff --git a/packages/protocol-kit/hardhat/deploy/deploy-contracts.ts b/packages/protocol-kit/hardhat/deploy/deploy-contracts.ts index 7fc9e21d0..28789b6e7 100644 --- a/packages/protocol-kit/hardhat/deploy/deploy-contracts.ts +++ b/packages/protocol-kit/hardhat/deploy/deploy-contracts.ts @@ -188,6 +188,20 @@ const deploy: DeployFunction = async (hre: HardhatRuntimeEnvironment): Promise .ts) allows them to be included in the build folder -function moveTypechainFiles(inDir: string, outDir: string): void { - readdir(`${inDir}`, (error, files) => { - if (error) { - console.log(error) - } - if (!existsSync(`${outDir}`)) { - mkdirSync(`${outDir}`, { recursive: true }) - } - files.forEach((file) => { - const pattern = /.d.ts/ - if (!file.match(pattern)) { - return - } - execSync(`cp ${inDir}/${file} ${outDir}/${file}`) - }) - }) -} - -function generateTypes(typechainTarget: string) { - // Src - generateTypechainFiles( - typechainTarget, - `${outDirSrc}${typechainTarget}/v1.4.1`, - safeContracts_V1_4_1 - ) - generateTypechainFiles( - typechainTarget, - `${outDirSrc}${typechainTarget}/v1.3.0`, - safeContracts_V1_3_0 - ) - generateTypechainFiles( - typechainTarget, - `${outDirSrc}${typechainTarget}/v1.2.0`, - safeContracts_V1_2_0 - ) - generateTypechainFiles( - typechainTarget, - `${outDirSrc}${typechainTarget}/v1.1.1`, - safeContracts_V1_1_1 - ) - generateTypechainFiles( - typechainTarget, - `${outDirSrc}${typechainTarget}/v1.0.0`, - safeContracts_V1_0_0 - ) - moveTypechainFiles( - `${typeChainDirectorySrcPath}${typechainTarget}/v1.4.1`, - `${typeChainDirectoryBuildPath}${typechainTarget}/v1.4.1` - ) - moveTypechainFiles( - `${typeChainDirectorySrcPath}${typechainTarget}/v1.3.0`, - `${typeChainDirectoryBuildPath}${typechainTarget}/v1.3.0` - ) - moveTypechainFiles( - `${typeChainDirectorySrcPath}${typechainTarget}/v1.2.0`, - `${typeChainDirectoryBuildPath}${typechainTarget}/v1.2.0` - ) - moveTypechainFiles( - `${typeChainDirectorySrcPath}${typechainTarget}/v1.1.1`, - `${typeChainDirectoryBuildPath}${typechainTarget}/v1.1.1` - ) - moveTypechainFiles( - `${typeChainDirectorySrcPath}${typechainTarget}/v1.0.0`, - `${typeChainDirectoryBuildPath}${typechainTarget}/v1.0.0` - ) - - // Tests - generateTypechainFiles( - typechainTarget, - `${outDirTests}${typechainTarget}/v1.4.1`, - testContracts_V1_4_1 - ) - generateTypechainFiles( - typechainTarget, - `${outDirTests}${typechainTarget}/v1.3.0`, - testContracts_V1_3_0 - ) - generateTypechainFiles( - typechainTarget, - `${outDirTests}${typechainTarget}/v1.2.0`, - testContracts_V1_2_0 - ) -} - -generateTypes('web3-v1') -generateTypes('ethers-v6') diff --git a/packages/protocol-kit/src/Safe.ts b/packages/protocol-kit/src/Safe.ts index 2c07d4aa3..e610ef639 100644 --- a/packages/protocol-kit/src/Safe.ts +++ b/packages/protocol-kit/src/Safe.ts @@ -1,5 +1,4 @@ import { - EthAdapter, OperationType, SafeMultisigTransactionResponse, SafeMultisigConfirmationResponse, @@ -12,9 +11,9 @@ import { TransactionResult, MetaTransactionData, Transaction, - CompatibilityFallbackHandlerContract, EIP712TypedData, - SafeTransactionData + SafeTransactionData, + CompatibilityFallbackHandlerContractType } from '@safe-global/safe-core-sdk-types' import { encodeSetupCallData, @@ -38,7 +37,8 @@ import { SafeConfigProps, SigningMethod, SigningMethodType, - SwapOwnerTxParams + SwapOwnerTxParams, + SafeModulesPaginated } from './types' import { EthSafeSignature, @@ -67,18 +67,18 @@ import { isSafeConfigWithPredictedSafe } from './utils/types' import { getCompatibilityFallbackHandlerContract, getMultiSendCallOnlyContract, - getProxyFactoryContract, - getSafeContract + getProxyFactoryContract } from './contracts/safeDeploymentContracts' import SafeMessage from './utils/messages/SafeMessage' import semverSatisfies from 'semver/functions/satisfies' +import SafeProvider from './SafeProvider' const EQ_OR_GT_1_4_1 = '>=1.4.1' const EQ_OR_GT_1_3_0 = '>=1.3.0' class Safe { #predictedSafe?: PredictedSafeProps - #ethAdapter!: EthAdapter + #safeProvider!: SafeProvider #contractManager!: ContractManager #ownerManager!: OwnerManager #moduleManager!: ModuleManager @@ -97,10 +97,10 @@ class Safe { * @throws "MultiSend contract is not deployed on the current network" * @throws "MultiSendCallOnly contract is not deployed on the current network" */ - static async create(config: SafeConfig): Promise { - const safeSdk = new Safe() - await safeSdk.init(config) - return safeSdk + static async init(config: SafeConfig): Promise { + const protocolKit = new Safe() + await protocolKit.#initializeProtocolKit(config) + return protocolKit } /** @@ -111,33 +111,41 @@ class Safe { * @throws "MultiSend contract is not deployed on the current network" * @throws "MultiSendCallOnly contract is not deployed on the current network" */ - private async init(config: SafeConfig): Promise { - const { ethAdapter, isL1SafeSingleton, contractNetworks } = config - - this.#ethAdapter = ethAdapter + async #initializeProtocolKit(config: SafeConfig) { + const { provider, signer, isL1SafeSingleton, contractNetworks } = config + this.#safeProvider = new SafeProvider({ + provider, + signer + }) if (isSafeConfigWithPredictedSafe(config)) { this.#predictedSafe = config.predictedSafe - this.#contractManager = await ContractManager.create({ - ethAdapter: this.#ethAdapter, - predictedSafe: this.#predictedSafe, - isL1SafeSingleton, - contractNetworks - }) + this.#contractManager = await ContractManager.init( + { + provider, + predictedSafe: this.#predictedSafe, + isL1SafeSingleton, + contractNetworks + }, + this.#safeProvider + ) } else { - this.#contractManager = await ContractManager.create({ - ethAdapter: this.#ethAdapter, - safeAddress: config.safeAddress, - isL1SafeSingleton, - contractNetworks - }) + this.#contractManager = await ContractManager.init( + { + provider, + safeAddress: config.safeAddress, + isL1SafeSingleton, + contractNetworks + }, + this.#safeProvider + ) } - this.#ownerManager = new OwnerManager(this.#ethAdapter, this.#contractManager.safeContract) - this.#moduleManager = new ModuleManager(this.#ethAdapter, this.#contractManager.safeContract) - this.#guardManager = new GuardManager(this.#ethAdapter, this.#contractManager.safeContract) + this.#ownerManager = new OwnerManager(this.#safeProvider, this.#contractManager.safeContract) + this.#moduleManager = new ModuleManager(this.#safeProvider, this.#contractManager.safeContract) + this.#guardManager = new GuardManager(this.#safeProvider, this.#contractManager.safeContract) this.#fallbackHandlerManager = new FallbackHandlerManager( - this.#ethAdapter, + this.#safeProvider, this.#contractManager.safeContract ) } @@ -151,16 +159,18 @@ class Safe { * @throws "MultiSendCallOnly contract is not deployed on the current network" */ async connect(config: ConnectSafeConfig): Promise { - const { ethAdapter, safeAddress, predictedSafe, isL1SafeSingleton, contractNetworks } = config + const { provider, signer, safeAddress, predictedSafe, isL1SafeSingleton, contractNetworks } = + config const configProps: SafeConfigProps = { - ethAdapter: ethAdapter || this.#ethAdapter, + provider: provider || this.#safeProvider.provider, + signer, isL1SafeSingleton: isL1SafeSingleton || this.#contractManager.isL1SafeSingleton, contractNetworks: contractNetworks || this.#contractManager.contractNetworks } // A new existing Safe is connected to the Signer if (safeAddress) { - return await Safe.create({ + return await Safe.init({ safeAddress, ...configProps }) @@ -168,7 +178,7 @@ class Safe { // A new predicted Safe is connected to the Signer if (predictedSafe) { - return await Safe.create({ + return await Safe.init({ predictedSafe, ...configProps }) @@ -176,14 +186,14 @@ class Safe { // The previous predicted Safe is connected to a new Signer if (this.#predictedSafe) { - return await Safe.create({ + return await Safe.init({ predictedSafe: this.#predictedSafe, ...configProps }) } // The previous existing Safe is connected to a new Signer - return await Safe.create({ + return await Safe.init({ safeAddress: await this.getAddress(), ...configProps }) @@ -199,10 +209,10 @@ class Safe { throw new Error('The Safe already exists') } - const chainId = await this.#ethAdapter.getChainId() + const chainId = await this.#safeProvider.getChainId() return getPredictedSafeAddressInitCode({ - ethAdapter: this.#ethAdapter, + safeProvider: this.#safeProvider, chainId, customContracts: this.#contractManager.contractNetworks?.[chainId.toString()], ...this.#predictedSafe @@ -223,9 +233,9 @@ class Safe { ) } - const chainId = await this.#ethAdapter.getChainId() + const chainId = await this.#safeProvider.getChainId() return predictSafeAddress({ - ethAdapter: this.#ethAdapter, + safeProvider: this.#safeProvider, chainId, customContracts: this.#contractManager.contractNetworks?.[chainId.toString()], ...this.#predictedSafe @@ -249,12 +259,12 @@ class Safe { } /** - * Returns the current EthAdapter. + * Returns the current SafeProvider. * - * @returns The current EthAdapter + * @returns The current SafeProvider */ - getEthAdapter(): EthAdapter { - return this.#ethAdapter + getSafeProvider(): SafeProvider { + return this.#safeProvider } /** @@ -282,7 +292,7 @@ class Safe { */ async isSafeDeployed(): Promise { const safeAddress = await this.getAddress() - const isSafeDeployed = await this.#ethAdapter.isContractDeployed(safeAddress) + const isSafeDeployed = await this.#safeProvider.isContractDeployed(safeAddress) return isSafeDeployed } @@ -326,7 +336,9 @@ class Safe { return Promise.resolve(0) } - return this.#contractManager.safeContract.getNonce() + const nonce = await this.#contractManager.safeContract.getNonce() + + return Number(nonce) } /** @@ -348,7 +360,7 @@ class Safe { * @returns The chainId of the connected network */ async getChainId(): Promise { - return this.#ethAdapter.getChainId() + return this.#safeProvider.getChainId() } /** @@ -357,7 +369,7 @@ class Safe { * @returns The ETH balance of the Safe */ async getBalance(): Promise { - return this.#ethAdapter.getBalance(await this.getAddress()) + return this.#safeProvider.getBalance(await this.getAddress()) } /** @@ -395,7 +407,7 @@ class Safe { * @param pageSize - The size of the page. It will be the max length of the returning array. Must be greater then 0. * @returns The list of addresses of all the enabled Safe modules */ - async getModulesPaginated(start: string, pageSize: number = 10): Promise { + async getModulesPaginated(start: string, pageSize: number = 10): Promise { return this.#moduleManager.getModulesPaginated(start, pageSize) } @@ -474,7 +486,7 @@ class Safe { return new EthSafeTransaction( await standardizeSafeTransactionData({ predictedSafe: this.#predictedSafe, - ethAdapter: this.#ethAdapter, + provider: this.#safeProvider.provider, tx: newTransaction, contractNetworks: this.#contractManager.contractNetworks }) @@ -487,7 +499,7 @@ class Safe { return new EthSafeTransaction( await standardizeSafeTransactionData({ safeContract: this.#contractManager.safeContract, - ethAdapter: this.#ethAdapter, + provider: this.#safeProvider.provider, tx: newTransaction, contractNetworks: this.#contractManager.contractNetworks }) @@ -559,7 +571,7 @@ class Safe { * @returns The Safe signature */ async signHash(hash: string): Promise { - const signature = await generateSignature(this.#ethAdapter, hash) + const signature = await generateSignature(this.#safeProvider, hash) return signature } @@ -591,9 +603,9 @@ class Safe { preimageSafeAddress?: string ): Promise { const owners = await this.getOwners() - const signerAddress = await this.#ethAdapter.getSignerAddress() + const signerAddress = await this.#safeProvider.getSignerAddress() if (!signerAddress) { - throw new Error('EthAdapter must be initialized with a signer to use this method') + throw new Error('SafeProvider must be initialized with a signer to use this method') } const addressIsOwner = owners.some( @@ -673,11 +685,11 @@ class Safe { const safeEIP712Args: SafeEIP712Args = { safeAddress: await this.getAddress(), safeVersion: await this.getContractVersion(), - chainId: await this.getEthAdapter().getChainId(), + chainId: await this.#safeProvider.getChainId(), data: eip712Data.data } - return generateEIP712Signature(this.#ethAdapter, safeEIP712Args, methodVersion) + return generateEIP712Signature(this.#safeProvider, safeEIP712Args, methodVersion) } /** @@ -702,9 +714,10 @@ class Safe { : safeTransaction const owners = await this.getOwners() - const signerAddress = await this.#ethAdapter.getSignerAddress() + const signerAddress = await this.#safeProvider.getSignerAddress() + if (!signerAddress) { - throw new Error('EthAdapter must be initialized with a signer to use this method') + throw new Error('SafeProvider must be initialized with a signer to use this method') } const addressIsOwner = owners.some( @@ -786,9 +799,9 @@ class Safe { } const owners = await this.getOwners() - const signerAddress = await this.#ethAdapter.getSignerAddress() + const signerAddress = await this.#safeProvider.getSignerAddress() if (!signerAddress) { - throw new Error('EthAdapter must be initialized with a signer to use this method') + throw new Error('SafeProvider must be initialized with a signer to use this method') } const addressIsOwner = owners.some( (owner: string) => signerAddress && sameString(owner, signerAddress) @@ -796,9 +809,8 @@ class Safe { if (!addressIsOwner) { throw new Error('Transaction hashes can only be approved by Safe owners') } - if (options?.gas && options?.gasLimit) { - throw new Error('Cannot specify gas and gasLimit together in transaction options') - } + + // TODO: fix this return this.#contractManager.safeContract.approveHash(hash, { from: signerAddress, ...options @@ -819,7 +831,7 @@ class Safe { const owners = await this.getOwners() const ownersWhoApproved: string[] = [] for (const owner of owners) { - const approved = await this.#contractManager.safeContract.approvedHashes(owner, txHash) + const [approved] = await this.#contractManager.safeContract.approvedHashes([owner, txHash]) if (approved > 0) { ownersWhoApproved.push(owner) } @@ -1143,9 +1155,9 @@ class Safe { signedSafeTransaction.addSignature(generatePreValidatedSignature(owner)) } const owners = await this.getOwners() - const signerAddress = await this.#ethAdapter.getSignerAddress() + const signerAddress = await this.#safeProvider.getSignerAddress() if (!signerAddress) { - throw new Error('EthAdapter must be initialized with a signer to use this method') + throw new Error('SafeProvider must be initialized with a signer to use this method') } if (owners.includes(signerAddress)) { signedSafeTransaction.addSignature(generatePreValidatedSignature(signerAddress)) @@ -1191,7 +1203,7 @@ class Safe { } const owners = await this.getOwners() const threshold = await this.getThreshold() - const signerAddress = await this.#ethAdapter.getSignerAddress() + const signerAddress = await this.#safeProvider.getSignerAddress() if ( threshold > signedSafeTransaction.signatures.size && signerAddress && @@ -1217,9 +1229,6 @@ class Safe { } } - if (options?.gas && options?.gasLimit) { - throw new Error('Cannot specify gas and gasLimit together in transaction options') - } const txResponse = await this.#contractManager.safeContract.execTransaction( signedSafeTransaction, { @@ -1244,14 +1253,14 @@ class Safe { const customContracts = this.#contractManager.contractNetworks?.[chainId.toString()] const isL1SafeSingleton = this.#contractManager.isL1SafeSingleton - const safeSingletonContract = await getSafeContract({ - ethAdapter: this.#ethAdapter, - safeVersion: safeVersion, + const safeSingletonContract = await this.#safeProvider.getSafeContract({ + safeVersion, isL1SafeSingleton, - customContracts + customContractAbi: customContracts?.safeSingletonAbi, + customContractAddress: customContracts?.safeSingletonAddress }) - const encodedTransaction: string = safeSingletonContract.encode('execTransaction', [ + const encodedTransaction = safeSingletonContract.encode('execTransaction', [ safeTransaction.data.to, safeTransaction.data.value, safeTransaction.data.data, @@ -1262,7 +1271,7 @@ class Safe { safeTransaction.data.gasToken, safeTransaction.data.refundReceiver, safeTransaction.encodedSignatures() - ]) as string + ]) return encodedTransaction } @@ -1345,28 +1354,28 @@ class Safe { const { safeAccountConfig, safeDeploymentConfig } = this.#predictedSafe const safeVersion = await this.getContractVersion() - const ethAdapter = this.#ethAdapter - const chainId = await ethAdapter.getChainId() + const safeProvider = this.#safeProvider + const chainId = await safeProvider.getChainId() const isL1SafeSingleton = this.#contractManager.isL1SafeSingleton const customContracts = this.#contractManager.contractNetworks?.[chainId.toString()] - const safeSingletonContract = await getSafeContract({ - ethAdapter: this.#ethAdapter, + const safeSingletonContract = await safeProvider.getSafeContract({ safeVersion, isL1SafeSingleton, - customContracts + customContractAddress: customContracts?.safeSingletonAddress, + customContractAbi: customContracts?.safeSingletonAbi }) // we use the SafeProxyFactory.sol contract, see: https://github.com/safe-global/safe-contracts/blob/main/contracts/proxies/SafeProxyFactory.sol const safeProxyFactoryContract = await getProxyFactoryContract({ - ethAdapter, + safeProvider, safeVersion, customContracts }) // this is the call to the setup method that sets the threshold & owners of the new Safe, see: https://github.com/safe-global/safe-contracts/blob/main/contracts/Safe.sol#L95 const initializer = await encodeSetupCallData({ - ethAdapter, + safeProvider, safeContract: safeSingletonContract, safeAccountConfig: safeAccountConfig, customContracts @@ -1385,7 +1394,7 @@ class Safe { data: safeProxyFactoryContract.encode('createProxyWithNonce', [ await safeSingletonContract.getAddress(), initializer, // call to the setup method to set the threshold & owners of the new Safe - saltNonce + BigInt(saltNonce) ]) } @@ -1407,11 +1416,11 @@ class Safe { transactions: MetaTransactionData[], transactionOptions?: TransactionOptions ): Promise { - const chainId = await this.#ethAdapter.getChainId() + const chainId = await this.#safeProvider.getChainId() // we use the MultiSend contract to create the batch, see: https://github.com/safe-global/safe-contracts/blob/main/contracts/libraries/MultiSendCallOnly.sol const multiSendCallOnlyContract = await getMultiSendCallOnlyContract({ - ethAdapter: this.#ethAdapter, + safeProvider: this.#safeProvider, safeVersion: await this.getContractVersion(), customContracts: this.#contractManager.contractNetworks?.[chainId.toString()] }) @@ -1436,17 +1445,17 @@ class Safe { * * @returns The fallback Handler contract */ - private async getFallbackHandlerContract(): Promise { + async #getFallbackHandlerContract(): Promise { if (!this.#contractManager.safeContract) { throw new Error('Safe is not deployed') } const safeVersion = (await this.#contractManager.safeContract.getVersion()) ?? DEFAULT_SAFE_VERSION - const chainId = await this.#ethAdapter.getChainId() + const chainId = await this.#safeProvider.getChainId() const compatibilityFallbackHandlerContract = await getCompatibilityFallbackHandlerContract({ - ethAdapter: this.#ethAdapter, + safeProvider: this.#safeProvider, safeVersion, customContracts: this.#contractManager.contractNetworks?.[chainId.toString()] }) @@ -1485,16 +1494,18 @@ class Safe { signature: SafeSignature[] | string = '0x' ): Promise => { const safeAddress = await this.getAddress() - const fallbackHandler = await this.getFallbackHandlerContract() + const fallbackHandler = await this.#getFallbackHandlerContract() const signatureToCheck = signature && Array.isArray(signature) ? buildSignatureBytes(signature) : signature + // @ts-expect-error Argument of type isValidSignature(bytes32,bytes) is not assignable to parameter of type isValidSignature const data = fallbackHandler.encode('isValidSignature(bytes32,bytes)', [ messageHash, signatureToCheck ]) + // @ts-expect-error Argument of type isValidSignature(bytes32,bytes) is not assignable to parameter of type isValidSignature const bytesData = fallbackHandler.encode('isValidSignature(bytes,bytes)', [ messageHash, signatureToCheck @@ -1502,12 +1513,12 @@ class Safe { try { const isValidSignatureResponse = await Promise.all([ - this.#ethAdapter.call({ + this.#safeProvider.call({ from: safeAddress, to: safeAddress, data: data }), - this.#ethAdapter.call({ + this.#safeProvider.call({ from: safeAddress, to: safeAddress, data: bytesData diff --git a/packages/protocol-kit/src/safeFactory/index.ts b/packages/protocol-kit/src/SafeFactory.ts similarity index 58% rename from packages/protocol-kit/src/safeFactory/index.ts rename to packages/protocol-kit/src/SafeFactory.ts index e81ccdcaa..180170e4f 100644 --- a/packages/protocol-kit/src/safeFactory/index.ts +++ b/packages/protocol-kit/src/SafeFactory.ts @@ -14,91 +14,75 @@ import { import { ContractNetworksConfig, SafeAccountConfig, - SafeDeploymentConfig + SafeContractImplementationType, + SafeDeploymentConfig, + SafeProxyFactoryContractImplementationType, + SafeProviderConfig, + SafeFactoryConfig, + SafeFactoryInitConfig, + DeploySafeProps } from '@safe-global/protocol-kit/types' -import { - EthAdapter, - SafeContract, - SafeProxyFactoryContract, - SafeVersion, - TransactionOptions -} from '@safe-global/safe-core-sdk-types' - -export interface DeploySafeProps { - safeAccountConfig: SafeAccountConfig - saltNonce?: string - options?: TransactionOptions - callback?: (txHash: string) => void -} - -export interface SafeFactoryConfig { - /** ethAdapter - Ethereum adapter */ - ethAdapter: EthAdapter - /** safeVersion - Versions of the Safe deployed by this Factory contract */ - safeVersion?: SafeVersion - /** isL1SafeSingleton - Forces to use the Safe L1 version of the contract instead of the L2 version */ - isL1SafeSingleton?: boolean - /** contractNetworks - Contract network configuration */ - contractNetworks?: ContractNetworksConfig -} - -interface SafeFactoryInitConfig { - /** ethAdapter - Ethereum adapter */ - ethAdapter: EthAdapter - /** safeVersion - Versions of the Safe deployed by this Factory contract */ - safeVersion: SafeVersion - /** isL1SafeSingleton - Forces to use the Safe L1 version of the contract instead of the L2 version */ - isL1SafeSingleton?: boolean - /** contractNetworks - Contract network configuration */ - contractNetworks?: ContractNetworksConfig -} +import { SafeVersion } from '@safe-global/safe-core-sdk-types' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' class SafeFactory { #contractNetworks?: ContractNetworksConfig #isL1SafeSingleton?: boolean #safeVersion!: SafeVersion - #ethAdapter!: EthAdapter - #safeProxyFactoryContract!: SafeProxyFactoryContract - #safeContract!: SafeContract - - static async create({ - ethAdapter, + #safeProxyFactoryContract!: SafeProxyFactoryContractImplementationType + #safeContract!: SafeContractImplementationType + #provider!: SafeProviderConfig['provider'] + #signer?: SafeFactoryConfig['signer'] + #safeProvider!: SafeProvider + + static async init({ + provider, + signer, safeVersion = DEFAULT_SAFE_VERSION, isL1SafeSingleton = false, contractNetworks }: SafeFactoryConfig): Promise { const safeFactorySdk = new SafeFactory() - await safeFactorySdk.init({ ethAdapter, safeVersion, isL1SafeSingleton, contractNetworks }) + await safeFactorySdk.#initializeSafeFactory({ + provider, + signer, + safeVersion, + isL1SafeSingleton, + contractNetworks + }) return safeFactorySdk } - private async init({ - ethAdapter, + async #initializeSafeFactory({ + provider, + signer, safeVersion, isL1SafeSingleton, contractNetworks - }: SafeFactoryInitConfig): Promise { - this.#ethAdapter = ethAdapter + }: SafeFactoryInitConfig) { + this.#provider = provider + this.#signer = signer + this.#safeProvider = new SafeProvider({ provider, signer }) this.#safeVersion = safeVersion this.#isL1SafeSingleton = isL1SafeSingleton this.#contractNetworks = contractNetworks - const chainId = await this.#ethAdapter.getChainId() + const chainId = await this.#safeProvider.getChainId() const customContracts = contractNetworks?.[chainId.toString()] this.#safeProxyFactoryContract = await getProxyFactoryContract({ - ethAdapter, + safeProvider: this.#safeProvider, safeVersion, customContracts }) this.#safeContract = await getSafeContract({ - ethAdapter, + safeProvider: this.#safeProvider, safeVersion, isL1SafeSingleton, customContracts }) } - getEthAdapter(): EthAdapter { - return this.#ethAdapter + getSafeProvider(): SafeProvider { + return this.#safeProvider } getSafeVersion(): SafeVersion { @@ -110,14 +94,14 @@ class SafeFactory { } async getChainId(): Promise { - return this.#ethAdapter.getChainId() + return this.#safeProvider.getChainId() } async predictSafeAddress( safeAccountConfig: SafeAccountConfig, saltNonce?: string ): Promise { - const chainId = await this.#ethAdapter.getChainId() + const chainId = await this.#safeProvider.getChainId() const customContracts = this.#contractNetworks?.[chainId.toString()] const safeVersion = this.#safeVersion @@ -127,7 +111,7 @@ class SafeFactory { } return predictSafeAddress({ - ethAdapter: this.#ethAdapter, + safeProvider: this.#safeProvider, chainId, safeAccountConfig, safeDeploymentConfig, @@ -145,24 +129,21 @@ class SafeFactory { validateSafeAccountConfig(safeAccountConfig) validateSafeDeploymentConfig({ saltNonce }) - const signerAddress = await this.#ethAdapter.getSignerAddress() + const signerAddress = await this.#safeProvider.getSignerAddress() if (!signerAddress) { - throw new Error('EthAdapter must be initialized with a signer to use this method') + throw new Error('SafeProvider must be initialized with a signer to use this method') } const chainId = await this.getChainId() const customContracts = this.#contractNetworks?.[chainId.toString()] const initializer = await encodeSetupCallData({ - ethAdapter: this.#ethAdapter, + safeProvider: this.#safeProvider, safeAccountConfig, safeContract: this.#safeContract, customContracts }) - if (options?.gas && options?.gasLimit) { - throw new Error('Cannot specify gas and gasLimit together in transaction options') - } - const safeAddress = await this.#safeProxyFactoryContract.createProxy({ + const safeAddress = await this.#safeProxyFactoryContract.createProxyWithOptions({ safeSingletonAddress: await this.#safeContract.getAddress(), initializer, saltNonce: saltNonce || getChainSpecificDefaultSaltNonce(chainId), @@ -172,12 +153,13 @@ class SafeFactory { }, callback }) - const isContractDeployed = await this.#ethAdapter.isContractDeployed(safeAddress) + const isContractDeployed = await this.#safeProvider.isContractDeployed(safeAddress) if (!isContractDeployed) { throw new Error('SafeProxy contract is not deployed on the current network') } - const safe = await Safe.create({ - ethAdapter: this.#ethAdapter, + const safe = await Safe.init({ + provider: this.#provider, + signer: this.#signer, safeAddress, isL1SafeSingleton: this.#isL1SafeSingleton, contractNetworks: this.#contractNetworks diff --git a/packages/protocol-kit/src/SafeProvider.ts b/packages/protocol-kit/src/SafeProvider.ts new file mode 100644 index 000000000..7b79fde1d --- /dev/null +++ b/packages/protocol-kit/src/SafeProvider.ts @@ -0,0 +1,280 @@ +import { + ethers, + TransactionResponse, + AbstractSigner, + Provider, + BrowserProvider, + JsonRpcProvider +} from 'ethers' +import { generateTypedData, validateEip3770Address } from '@safe-global/protocol-kit/utils' +import { isTypedDataSigner } from '@safe-global/protocol-kit/contracts/utils' +import { EMPTY_DATA } from '@safe-global/protocol-kit/utils/constants' + +import { + EIP712TypedDataMessage, + EIP712TypedDataTx, + Eip3770Address, + SafeEIP712Args +} from '@safe-global/safe-core-sdk-types' +import { + getCompatibilityFallbackHandlerContractInstance, + getCreateCallContractInstance, + getMultiSendCallOnlyContractInstance, + getMultiSendContractInstance, + getSafeContractInstance, + getSafeProxyFactoryContractInstance, + getSignMessageLibContractInstance, + getSimulateTxAccessorContractInstance +} from './contracts/contractInstances' +import { + SafeProviderTransaction, + GetContractProps, + SafeProviderConfig, + Eip1193Provider, + HttpTransport, + SocketTransport +} from '@safe-global/protocol-kit/types' + +class SafeProvider { + #externalProvider: BrowserProvider | JsonRpcProvider + signer?: string + provider: Eip1193Provider | HttpTransport | SocketTransport + + constructor({ provider, signer }: SafeProviderConfig) { + if (typeof provider === 'string') { + this.#externalProvider = new JsonRpcProvider(provider) + } else { + this.#externalProvider = new BrowserProvider(provider) + } + + this.provider = provider + this.signer = signer + } + + getExternalProvider(): Provider { + return this.#externalProvider + } + + async getExternalSigner(): Promise { + // If the signer is not an Ethereum address, it should be a private key + if (this.signer && !ethers.isAddress(this.signer)) { + const privateKeySigner = new ethers.Wallet(this.signer, this.#externalProvider) + return privateKeySigner + } + + if (this.signer) { + return this.#externalProvider.getSigner(this.signer) + } + + if (this.#externalProvider instanceof BrowserProvider) { + return this.#externalProvider.getSigner() + } + + return undefined + } + + isAddress(address: string): boolean { + return ethers.isAddress(address) + } + + async getEip3770Address(fullAddress: string): Promise { + const chainId = await this.getChainId() + return validateEip3770Address(fullAddress, chainId) + } + + async getBalance(address: string, blockTag?: string | number): Promise { + return this.#externalProvider.getBalance(address, blockTag) + } + + async getNonce(address: string, blockTag?: string | number): Promise { + return this.#externalProvider.getTransactionCount(address, blockTag) + } + + async getChainId(): Promise { + return (await this.#externalProvider.getNetwork()).chainId + } + + getChecksummedAddress(address: string): string { + return ethers.getAddress(address) + } + + async getSafeContract({ + safeVersion, + customContractAddress, + customContractAbi, + isL1SafeSingleton + }: GetContractProps) { + return getSafeContractInstance( + safeVersion, + this, + customContractAddress, + customContractAbi, + isL1SafeSingleton + ) + } + + async getSafeProxyFactoryContract({ + safeVersion, + customContractAddress, + customContractAbi + }: GetContractProps) { + const signerOrProvider = (await this.getExternalSigner()) || this.#externalProvider + return getSafeProxyFactoryContractInstance( + safeVersion, + this, + signerOrProvider, + customContractAddress, + customContractAbi + ) + } + + async getMultiSendContract({ + safeVersion, + customContractAddress, + customContractAbi + }: GetContractProps) { + return getMultiSendContractInstance(safeVersion, this, customContractAddress, customContractAbi) + } + + async getMultiSendCallOnlyContract({ + safeVersion, + customContractAddress, + customContractAbi + }: GetContractProps) { + return getMultiSendCallOnlyContractInstance( + safeVersion, + this, + customContractAddress, + customContractAbi + ) + } + + async getCompatibilityFallbackHandlerContract({ + safeVersion, + customContractAddress, + customContractAbi + }: GetContractProps) { + return getCompatibilityFallbackHandlerContractInstance( + safeVersion, + this, + customContractAddress, + customContractAbi + ) + } + + async getSignMessageLibContract({ + safeVersion, + customContractAddress, + customContractAbi + }: GetContractProps) { + return getSignMessageLibContractInstance( + safeVersion, + this, + customContractAddress, + customContractAbi + ) + } + + async getCreateCallContract({ + safeVersion, + customContractAddress, + customContractAbi + }: GetContractProps) { + return getCreateCallContractInstance( + safeVersion, + this, + customContractAddress, + customContractAbi + ) + } + + async getSimulateTxAccessorContract({ + safeVersion, + customContractAddress, + customContractAbi + }: GetContractProps) { + return getSimulateTxAccessorContractInstance( + safeVersion, + this, + customContractAddress, + customContractAbi + ) + } + + async getContractCode(address: string, blockTag?: string | number): Promise { + return this.#externalProvider.getCode(address, blockTag) + } + + async isContractDeployed(address: string, blockTag?: string | number): Promise { + const contractCode = await this.#externalProvider.getCode(address, blockTag) + return contractCode !== EMPTY_DATA + } + + async getStorageAt(address: string, position: string): Promise { + const content = await this.#externalProvider.getStorage(address, position) + const decodedContent = this.decodeParameters(['address'], content) + return decodedContent[0] + } + + async getTransaction(transactionHash: string): Promise { + return this.#externalProvider.getTransaction(transactionHash) as Promise + } + + async getSignerAddress(): Promise { + const signer = await this.getExternalSigner() + + return signer?.getAddress() + } + + async signMessage(message: string): Promise { + const signer = await this.getExternalSigner() + + if (!signer) { + throw new Error('SafeProvider must be initialized with a signer to use this method') + } + const messageArray = ethers.getBytes(message) + + return signer.signMessage(messageArray) + } + + async signTypedData(safeEIP712Args: SafeEIP712Args): Promise { + const signer = await this.getExternalSigner() + + if (!signer) { + throw new Error('SafeProvider must be initialized with a signer to use this method') + } + + if (isTypedDataSigner(signer)) { + const typedData = generateTypedData(safeEIP712Args) + const signature = await signer.signTypedData( + typedData.domain, + typedData.primaryType === 'SafeMessage' + ? { SafeMessage: (typedData as EIP712TypedDataMessage).types.SafeMessage } + : { SafeTx: (typedData as EIP712TypedDataTx).types.SafeTx }, + typedData.message + ) + return signature + } + + throw new Error('The current signer does not implement EIP-712 to sign typed data') + } + + async estimateGas(transaction: SafeProviderTransaction): Promise { + return (await this.#externalProvider.estimateGas(transaction)).toString() + } + + call(transaction: SafeProviderTransaction, blockTag?: string | number): Promise { + return this.#externalProvider.call({ ...transaction, blockTag }) + } + + // TODO: fix anys + encodeParameters(types: string[], values: any[]): string { + return new ethers.AbiCoder().encode(types, values) + } + + decodeParameters(types: string[], values: string): { [key: string]: any } { + return new ethers.AbiCoder().decode(types, values) + } +} + +export default SafeProvider diff --git a/packages/protocol-kit/src/adapters/ethers/EthersAdapter.ts b/packages/protocol-kit/src/adapters/ethers/EthersAdapter.ts deleted file mode 100644 index 1c4d5c79e..000000000 --- a/packages/protocol-kit/src/adapters/ethers/EthersAdapter.ts +++ /dev/null @@ -1,288 +0,0 @@ -import { generateTypedData, validateEip3770Address } from '@safe-global/protocol-kit/utils' -import { - EIP712TypedDataMessage, - EIP712TypedDataTx, - Eip3770Address, - EthAdapter, - EthAdapterTransaction, - GetContractProps, - SafeEIP712Args -} from '@safe-global/safe-core-sdk-types' -import { ethers, TransactionResponse, AbstractSigner, Provider } from 'ethers' -import CompatibilityFallbackHandlerContractEthers from './contracts/CompatibilityFallbackHandler/CompatibilityFallbackHandlerEthersContract' -import CreateCallEthersContract from './contracts/CreateCall/CreateCallEthersContract' -import MultiSendEthersContract from './contracts/MultiSend/MultiSendEthersContract' -import MultiSendCallOnlyEthersContract from './contracts/MultiSendCallOnly/MultiSendCallOnlyEthersContract' -import SafeContractEthers from './contracts/Safe/SafeContractEthers' -import SafeProxyFactoryEthersContract from './contracts/SafeProxyFactory/SafeProxyFactoryEthersContract' -import SignMessageLibEthersContract from './contracts/SignMessageLib/SignMessageLibEthersContract' -import SimulateTxAccessorEthersContract from './contracts/SimulateTxAccessor/SimulateTxAccessorEthersContract' -import { - getCompatibilityFallbackHandlerContractInstance, - getCreateCallContractInstance, - getMultiSendCallOnlyContractInstance, - getMultiSendContractInstance, - getSafeContractInstance, - getSafeProxyFactoryContractInstance, - getSignMessageLibContractInstance, - getSimulateTxAccessorContractInstance -} from './contracts/contractInstancesEthers' -import { isTypedDataSigner, isSignerCompatible } from './utils' - -type Ethers = typeof ethers - -export interface EthersAdapterConfig { - /** ethers - Ethers v6 library */ - ethers: Ethers - /** signerOrProvider - Ethers signer or provider */ - signerOrProvider: AbstractSigner | Provider -} - -class EthersAdapter implements EthAdapter { - #ethers: Ethers - #signer?: AbstractSigner - #provider: Provider - - constructor({ ethers, signerOrProvider }: EthersAdapterConfig) { - if (!ethers) { - throw new Error('ethers property missing from options') - } - this.#ethers = ethers - const isSigner = isSignerCompatible(signerOrProvider) - if (isSigner) { - const signer = signerOrProvider as AbstractSigner - if (!signer.provider) { - throw new Error('Signer must be connected to a provider') - } - this.#provider = signer.provider - this.#signer = signer - } else { - this.#provider = signerOrProvider as Provider - } - } - - getProvider(): Provider { - return this.#provider - } - - getSigner(): AbstractSigner | undefined { - return this.#signer - } - - isAddress(address: string): boolean { - return this.#ethers.isAddress(address) - } - - async getEip3770Address(fullAddress: string): Promise { - const chainId = await this.getChainId() - return validateEip3770Address(fullAddress, chainId) - } - - async getBalance(address: string, blockTag?: string | number): Promise { - return this.#provider.getBalance(address, blockTag) - } - - async getNonce(address: string, blockTag?: string | number): Promise { - return this.#provider.getTransactionCount(address, blockTag) - } - - async getChainId(): Promise { - return (await this.#provider.getNetwork()).chainId - } - - getChecksummedAddress(address: string): string { - return this.#ethers.getAddress(address) - } - - async getSafeContract({ - safeVersion, - singletonDeployment, - customContractAddress - }: GetContractProps): Promise { - const chainId = await this.getChainId() - const contractAddress = - customContractAddress ?? singletonDeployment?.networkAddresses[chainId.toString()] - if (!contractAddress) { - throw new Error('Invalid SafeProxy contract address') - } - const signerOrProvider = this.#signer || this.#provider - return getSafeContractInstance(safeVersion, contractAddress, signerOrProvider) - } - - async getSafeProxyFactoryContract({ - safeVersion, - singletonDeployment, - customContractAddress - }: GetContractProps): Promise { - const chainId = await this.getChainId() - const contractAddress = - customContractAddress ?? singletonDeployment?.networkAddresses[chainId.toString()] - if (!contractAddress) { - throw new Error('Invalid SafeProxyFactory contract address') - } - const signerOrProvider = this.#signer || this.#provider - return getSafeProxyFactoryContractInstance(safeVersion, contractAddress, signerOrProvider) - } - - async getMultiSendContract({ - safeVersion, - singletonDeployment, - customContractAddress - }: GetContractProps): Promise { - const chainId = await this.getChainId() - const contractAddress = - customContractAddress ?? singletonDeployment?.networkAddresses[chainId.toString()] - if (!contractAddress) { - throw new Error('Invalid MultiSend contract address') - } - const signerOrProvider = this.#signer || this.#provider - return getMultiSendContractInstance(safeVersion, contractAddress, signerOrProvider) - } - - async getMultiSendCallOnlyContract({ - safeVersion, - singletonDeployment, - customContractAddress - }: GetContractProps): Promise { - const chainId = await this.getChainId() - const contractAddress = - customContractAddress ?? singletonDeployment?.networkAddresses[chainId.toString()] - if (!contractAddress) { - throw new Error('Invalid MultiSendCallOnly contract address') - } - const signerOrProvider = this.#signer || this.#provider - return getMultiSendCallOnlyContractInstance(safeVersion, contractAddress, signerOrProvider) - } - - async getCompatibilityFallbackHandlerContract({ - safeVersion, - singletonDeployment, - customContractAddress - }: GetContractProps): Promise { - const chainId = await this.getChainId() - const contractAddress = - customContractAddress ?? singletonDeployment?.networkAddresses[chainId.toString()] - if (!contractAddress) { - throw new Error('Invalid CompatibilityFallbackHandler contract address') - } - const signerOrProvider = this.#signer || this.#provider - return getCompatibilityFallbackHandlerContractInstance( - safeVersion, - contractAddress, - signerOrProvider - ) - } - - async getSignMessageLibContract({ - safeVersion, - singletonDeployment, - customContractAddress - }: GetContractProps): Promise { - const chainId = await this.getChainId() - const contractAddress = - customContractAddress ?? singletonDeployment?.networkAddresses[chainId.toString()] - if (!contractAddress) { - throw new Error('Invalid SignMessageLib contract address') - } - const signerOrProvider = this.#signer || this.#provider - return getSignMessageLibContractInstance(safeVersion, contractAddress, signerOrProvider) - } - - async getCreateCallContract({ - safeVersion, - singletonDeployment, - customContractAddress - }: GetContractProps): Promise { - const chainId = await this.getChainId() - const contractAddress = - customContractAddress ?? singletonDeployment?.networkAddresses[chainId.toString()] - if (!contractAddress) { - throw new Error('Invalid CreateCall contract address') - } - const signerOrProvider = this.#signer || this.#provider - return getCreateCallContractInstance(safeVersion, contractAddress, signerOrProvider) - } - - async getSimulateTxAccessorContract({ - safeVersion, - singletonDeployment, - customContractAddress - }: GetContractProps): Promise { - const chainId = await this.getChainId() - const contractAddress = - customContractAddress ?? singletonDeployment?.networkAddresses[chainId.toString()] - if (!contractAddress) { - throw new Error('Invalid SimulateTxAccessor contract address') - } - const signerOrProvider = this.#signer || this.#provider - return getSimulateTxAccessorContractInstance(safeVersion, contractAddress, signerOrProvider) - } - - async getContractCode(address: string, blockTag?: string | number): Promise { - return this.#provider.getCode(address, blockTag) - } - - async isContractDeployed(address: string, blockTag?: string | number): Promise { - const contractCode = await this.#provider.getCode(address, blockTag) - return contractCode !== '0x' - } - - async getStorageAt(address: string, position: string): Promise { - const content = await this.#provider.getStorage(address, position) - const decodedContent = this.decodeParameters(['address'], content) - return decodedContent[0] - } - - async getTransaction(transactionHash: string): Promise { - return this.#provider.getTransaction(transactionHash) as Promise - } - - async getSignerAddress(): Promise { - return this.#signer?.getAddress() - } - - signMessage(message: string): Promise { - if (!this.#signer) { - throw new Error('EthAdapter must be initialized with a signer to use this method') - } - const messageArray = this.#ethers.getBytes(message) - return this.#signer.signMessage(messageArray) - } - - async signTypedData(safeEIP712Args: SafeEIP712Args): Promise { - if (!this.#signer) { - throw new Error('EthAdapter must be initialized with a signer to use this method') - } - if (isTypedDataSigner(this.#signer)) { - const typedData = generateTypedData(safeEIP712Args) - const signature = await this.#signer.signTypedData( - typedData.domain, - typedData.primaryType === 'SafeMessage' - ? { SafeMessage: (typedData as EIP712TypedDataMessage).types.SafeMessage } - : { SafeTx: (typedData as EIP712TypedDataTx).types.SafeTx }, - typedData.message - ) - return signature - } - - throw new Error('The current signer does not implement EIP-712 to sign typed data') - } - - async estimateGas(transaction: EthAdapterTransaction): Promise { - return (await this.#provider.estimateGas(transaction)).toString() - } - - call(transaction: EthAdapterTransaction, blockTag?: string | number): Promise { - return this.#provider.call({ ...transaction, blockTag }) - } - - encodeParameters(types: string[], values: any[]): string { - return new this.#ethers.AbiCoder().encode(types, values) - } - - decodeParameters(types: string[], values: string): { [key: string]: any } { - return new this.#ethers.AbiCoder().decode(types, values) - } -} - -export default EthersAdapter diff --git a/packages/protocol-kit/src/adapters/ethers/README.md b/packages/protocol-kit/src/adapters/ethers/README.md deleted file mode 100644 index d8313d943..000000000 --- a/packages/protocol-kit/src/adapters/ethers/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# Ethers Adapter - -Ethers.js wrapper that contains some utilities and the Safe contracts types (generated with `typechain` `ethers-v6`). It is used to initialize the [Protocol Kit](https://github.com/safe-global/safe-core-sdk/tree/main/packages/protocol-kit). - -## How to use - -If the app integrating the SDK is using `ethers`, create an instance of the `EthersAdapter`, where `signer` is the Ethereum account we are connecting and the one who will sign the transactions. - -> :warning: **NOTE**: Currently only `ethers` `v6` is supported. - -```js -import { ethers } from 'ethers' -import { EthersAdapter } from '@safe-global/protocol-kit' - -const web3Provider = // ... -const provider = new ethers.BrowserProvider(web3Provider) -const safeOwner = provider.getSigner(0) - -const ethAdapter = new EthersAdapter({ - ethers, - signerOrProvider: safeOwner -}) -``` - -Depending on whether the `ethAdapter` instance is used to sign/execute transactions or just call read-only methods, the `signerOrProvider` property can be a `Signer` or a `Provider`. diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/CompatibilityFallbackHandler/CompatibilityFallbackHandlerEthersContract.ts b/packages/protocol-kit/src/adapters/ethers/contracts/CompatibilityFallbackHandler/CompatibilityFallbackHandlerEthersContract.ts deleted file mode 100644 index 8046de1ea..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/CompatibilityFallbackHandler/CompatibilityFallbackHandlerEthersContract.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { - Compatibility_fallback_handler as CompatibilityFallbackHandler_V1_3_0, - Compatibility_fallback_handlerInterface as CompatibilityFallbackHandlerInterface -} from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.3.0/Compatibility_fallback_handler' -import { Compatibility_fallback_handler as CompatibilityFallbackHandler_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.4.1/Compatibility_fallback_handler' -import { CompatibilityFallbackHandlerContract } from '@safe-global/safe-core-sdk-types' - -abstract class CompatibilityFallbackHandlerEthersContract - implements CompatibilityFallbackHandlerContract -{ - constructor( - public contract: CompatibilityFallbackHandler_V1_4_1 | CompatibilityFallbackHandler_V1_3_0 - ) {} - - getAddress(): Promise { - return this.contract.getAddress() - } - - encode: CompatibilityFallbackHandlerInterface['encodeFunctionData'] = ( - methodName: any, - params: any - ): string => { - return this.contract.interface.encodeFunctionData(methodName, params) - } -} - -export default CompatibilityFallbackHandlerEthersContract diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/CompatibilityFallbackHandler/v1.3.0/CompatibilityFallbackHandler_V1_3_0_Ethers.ts b/packages/protocol-kit/src/adapters/ethers/contracts/CompatibilityFallbackHandler/v1.3.0/CompatibilityFallbackHandler_V1_3_0_Ethers.ts deleted file mode 100644 index 77d36778e..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/CompatibilityFallbackHandler/v1.3.0/CompatibilityFallbackHandler_V1_3_0_Ethers.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Compatibility_fallback_handler as CompatibilityFallbackHandler } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.3.0/Compatibility_fallback_handler' -import CompatibilityFallbackHandlerEthersContract from '../CompatibilityFallbackHandlerEthersContract' - -class CompatibilityFallbackHandler_V1_3_0_Ethers extends CompatibilityFallbackHandlerEthersContract { - constructor(public contract: CompatibilityFallbackHandler) { - super(contract) - } -} - -export default CompatibilityFallbackHandler_V1_3_0_Ethers diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/CompatibilityFallbackHandler/v1.4.1/CompatibilityFallbackHandler_V1_4_1_Ethers.ts b/packages/protocol-kit/src/adapters/ethers/contracts/CompatibilityFallbackHandler/v1.4.1/CompatibilityFallbackHandler_V1_4_1_Ethers.ts deleted file mode 100644 index 0a1e9d9ae..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/CompatibilityFallbackHandler/v1.4.1/CompatibilityFallbackHandler_V1_4_1_Ethers.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Compatibility_fallback_handler as CompatibilityFallbackHandler } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.4.1/Compatibility_fallback_handler' -import CompatibilityFallbackHandlerEthersContract from '../CompatibilityFallbackHandlerEthersContract' - -class CompatibilityFallbackHandler_V1_4_1_Ethers extends CompatibilityFallbackHandlerEthersContract { - constructor(public contract: CompatibilityFallbackHandler) { - super(contract) - } -} - -export default CompatibilityFallbackHandler_V1_4_1_Ethers diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/CreateCall/CreateCallEthersContract.ts b/packages/protocol-kit/src/adapters/ethers/contracts/CreateCall/CreateCallEthersContract.ts deleted file mode 100644 index 78aac08c3..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/CreateCall/CreateCallEthersContract.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { - EthersTransactionOptions, - EthersTransactionResult -} from '@safe-global/protocol-kit/adapters/ethers/types' -import { toTxResult } from '@safe-global/protocol-kit/adapters/ethers/utils' -import { - Create_call as CreateCall_V1_3_0, - Create_callInterface as CreateCallContractInterface -} from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.3.0/Create_call' -import { Create_call as CreateCall_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.4.1/Create_call' -import { CreateCallContract } from '@safe-global/safe-core-sdk-types' - -abstract class CreateCallEthersContract implements CreateCallContract { - constructor(public contract: CreateCall_V1_4_1 | CreateCall_V1_3_0) {} - - getAddress(): Promise { - return this.contract.getAddress() - } - - async performCreate2( - value: string, - deploymentData: string, - salt: string, - options?: EthersTransactionOptions - ): Promise { - if (options && !options.gasLimit) { - options.gasLimit = await this.estimateGas('performCreate2', [value, deploymentData, salt], { - ...options - }) - } - const txResponse = await this.contract.performCreate2(value, deploymentData, salt) - return toTxResult(txResponse, options) - } - - async performCreate( - value: string, - deploymentData: string, - options?: EthersTransactionOptions - ): Promise { - if (options && !options.gasLimit) { - options.gasLimit = await this.estimateGas('performCreate', [value, deploymentData], { - ...options - }) - } - const txResponse = await this.contract.performCreate(value, deploymentData, { ...options }) - return toTxResult(txResponse, options) - } - - encode: CreateCallContractInterface['encodeFunctionData'] = ( - methodName: any, - params: any - ): string => { - return this.contract.interface.encodeFunctionData(methodName, params) - } - - async estimateGas( - methodName: string, - params: any[], - options: EthersTransactionOptions - ): Promise { - const method = this.contract.getFunction(methodName) - - return (await method.estimateGas(...params, options)).toString() - } -} - -export default CreateCallEthersContract diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/CreateCall/v1.3.0/CreateCallEthersContract_V1_3_0_Ethers.ts b/packages/protocol-kit/src/adapters/ethers/contracts/CreateCall/v1.3.0/CreateCallEthersContract_V1_3_0_Ethers.ts deleted file mode 100644 index 3f954e55b..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/CreateCall/v1.3.0/CreateCallEthersContract_V1_3_0_Ethers.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Create_call as CreateCall } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.3.0/Create_call' -import CreateCallEthersContract from '../CreateCallEthersContract' - -class CreateCallContract_V1_3_0_Ethers extends CreateCallEthersContract { - constructor(public contract: CreateCall) { - super(contract) - } -} - -export default CreateCallContract_V1_3_0_Ethers diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/CreateCall/v1.4.1/CreateCallEthersContract_V1_4_1_Ethers.ts b/packages/protocol-kit/src/adapters/ethers/contracts/CreateCall/v1.4.1/CreateCallEthersContract_V1_4_1_Ethers.ts deleted file mode 100644 index 6bad21fa7..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/CreateCall/v1.4.1/CreateCallEthersContract_V1_4_1_Ethers.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Create_call as CreateCall } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.4.1/Create_call' -import CreateCallEthersContract from '../CreateCallEthersContract' - -class CreateCallContract_V1_4_1_Ethers extends CreateCallEthersContract { - constructor(public contract: CreateCall) { - super(contract) - } -} - -export default CreateCallContract_V1_4_1_Ethers diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/MultiSend/MultiSendEthersContract.ts b/packages/protocol-kit/src/adapters/ethers/contracts/MultiSend/MultiSendEthersContract.ts deleted file mode 100644 index 25fe02406..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/MultiSend/MultiSendEthersContract.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Multi_send as MultiSend_V1_1_1 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.1.1/Multi_send' -import { - Multi_send as MultiSend_V1_3_0, - Multi_sendInterface as MultiSendInterface -} from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.3.0/Multi_send' -import { Multi_send as MultiSend_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.4.1/Multi_send' -import { MultiSendContract } from '@safe-global/safe-core-sdk-types' - -abstract class MultiSendEthersContract implements MultiSendContract { - constructor(public contract: MultiSend_V1_4_1 | MultiSend_V1_3_0 | MultiSend_V1_1_1) {} - - getAddress(): Promise { - return this.contract.getAddress() - } - - encode: MultiSendInterface['encodeFunctionData'] = (methodName: any, params: any): string => { - return this.contract.interface.encodeFunctionData(methodName, params) - } -} - -export default MultiSendEthersContract diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/MultiSend/v1.1.1/MultiSendContract_V1_1_1_Ethers.ts b/packages/protocol-kit/src/adapters/ethers/contracts/MultiSend/v1.1.1/MultiSendContract_V1_1_1_Ethers.ts deleted file mode 100644 index 0d47911d0..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/MultiSend/v1.1.1/MultiSendContract_V1_1_1_Ethers.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Multi_send as MultiSend } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.1.1/Multi_send' -import MultiSendEthersContract from '../MultiSendEthersContract' - -class MultiSendContract_V1_1_1_Ethers extends MultiSendEthersContract { - constructor(public contract: MultiSend) { - super(contract) - } -} - -export default MultiSendContract_V1_1_1_Ethers diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/MultiSend/v1.3.0/MultiSendContract_V1_3_0_Ethers.ts b/packages/protocol-kit/src/adapters/ethers/contracts/MultiSend/v1.3.0/MultiSendContract_V1_3_0_Ethers.ts deleted file mode 100644 index 81bda33bc..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/MultiSend/v1.3.0/MultiSendContract_V1_3_0_Ethers.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Multi_send as MultiSend } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.3.0/Multi_send' -import MultiSendEthersContract from '../MultiSendEthersContract' - -class MultiSendContract_V1_3_0_Ethers extends MultiSendEthersContract { - constructor(public contract: MultiSend) { - super(contract) - } -} - -export default MultiSendContract_V1_3_0_Ethers diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/MultiSend/v1.4.1/MultiSendContract_V1_4_1_Ethers.ts b/packages/protocol-kit/src/adapters/ethers/contracts/MultiSend/v1.4.1/MultiSendContract_V1_4_1_Ethers.ts deleted file mode 100644 index d7cbc028b..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/MultiSend/v1.4.1/MultiSendContract_V1_4_1_Ethers.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Multi_send as MultiSend } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.4.1/Multi_send' -import MultiSendEthersContract from '../MultiSendEthersContract' - -class MultiSendContract_V1_4_1_Ethers extends MultiSendEthersContract { - constructor(public contract: MultiSend) { - super(contract) - } -} - -export default MultiSendContract_V1_4_1_Ethers diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/MultiSendCallOnly/MultiSendCallOnlyEthersContract.ts b/packages/protocol-kit/src/adapters/ethers/contracts/MultiSendCallOnly/MultiSendCallOnlyEthersContract.ts deleted file mode 100644 index 4f5b02424..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/MultiSendCallOnly/MultiSendCallOnlyEthersContract.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { - Multi_send_call_only as MultiSendCallOnly_V1_3_0, - Multi_send_call_onlyInterface as MultiSendCallOnlyInterface -} from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.3.0/Multi_send_call_only' -import { Multi_send_call_only as MultiSendCallOnly_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.4.1/Multi_send_call_only' -import { MultiSendCallOnlyContract } from '@safe-global/safe-core-sdk-types' - -abstract class MultiSendCallOnlyEthersContract implements MultiSendCallOnlyContract { - constructor(public contract: MultiSendCallOnly_V1_4_1 | MultiSendCallOnly_V1_3_0) {} - - getAddress(): Promise { - return this.contract.getAddress() - } - - encode: MultiSendCallOnlyInterface['encodeFunctionData'] = ( - methodName: any, - params: any - ): string => { - return this.contract.interface.encodeFunctionData(methodName, params) - } -} - -export default MultiSendCallOnlyEthersContract diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/MultiSendCallOnly/v1.3.0/MultiSendCallOnlyContract_V1_3_0_Ethers.ts b/packages/protocol-kit/src/adapters/ethers/contracts/MultiSendCallOnly/v1.3.0/MultiSendCallOnlyContract_V1_3_0_Ethers.ts deleted file mode 100644 index c605dad96..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/MultiSendCallOnly/v1.3.0/MultiSendCallOnlyContract_V1_3_0_Ethers.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Multi_send_call_only as MultiSendCallOnly } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.3.0/Multi_send_call_only' -import MultiSendCallOnlyEthersContract from '../MultiSendCallOnlyEthersContract' - -class MultiSendCallOnlyContract_V1_3_0_Ethers extends MultiSendCallOnlyEthersContract { - constructor(public contract: MultiSendCallOnly) { - super(contract) - } -} - -export default MultiSendCallOnlyContract_V1_3_0_Ethers diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/MultiSendCallOnly/v1.4.1/MultiSendCallOnlyContract_V1_4_1_Ethers.ts b/packages/protocol-kit/src/adapters/ethers/contracts/MultiSendCallOnly/v1.4.1/MultiSendCallOnlyContract_V1_4_1_Ethers.ts deleted file mode 100644 index 6d4449696..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/MultiSendCallOnly/v1.4.1/MultiSendCallOnlyContract_V1_4_1_Ethers.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Multi_send_call_only as MultiSendCallOnly } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.4.1/Multi_send_call_only' -import MultiSendCallOnlyEthersContract from '../MultiSendCallOnlyEthersContract' - -class MultiSendCallOnlyContract_V1_4_1_Ethers extends MultiSendCallOnlyEthersContract { - constructor(public contract: MultiSendCallOnly) { - super(contract) - } -} - -export default MultiSendCallOnlyContract_V1_4_1_Ethers diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/Safe/SafeContractEthers.ts b/packages/protocol-kit/src/adapters/ethers/contracts/Safe/SafeContractEthers.ts deleted file mode 100644 index 718b0909c..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/Safe/SafeContractEthers.ts +++ /dev/null @@ -1,190 +0,0 @@ -import { - EthersTransactionOptions, - EthersTransactionResult -} from '@safe-global/protocol-kit/adapters/ethers/types' -import { toTxResult } from '@safe-global/protocol-kit/adapters/ethers/utils' -import { Gnosis_safe as Safe_V1_0_0 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.0.0/Gnosis_safe' -import { Gnosis_safe as Safe_V1_1_1 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.1.1/Gnosis_safe' -import { Gnosis_safe as Safe_V1_2_0 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.2.0/Gnosis_safe' -import { - Gnosis_safeInterface as SafeInterface, - Gnosis_safe as Safe_V1_3_0 -} from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.3.0/Gnosis_safe' -import { Safe as Safe_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.4.1/Safe' -import { - SafeContract, - SafeSetupConfig, - SafeTransaction, - SafeTransactionData, - SafeVersion -} from '@safe-global/safe-core-sdk-types' - -abstract class SafeContractEthers implements SafeContract { - constructor( - public contract: Safe_V1_4_1 | Safe_V1_3_0 | Safe_V1_2_0 | Safe_V1_1_1 | Safe_V1_0_0 - ) {} - - abstract setup( - setupConfig: SafeSetupConfig, - options?: EthersTransactionOptions - ): Promise - - async getVersion(): Promise { - return (await this.contract.VERSION()) as SafeVersion - } - - getAddress(): Promise { - return this.contract.getAddress() - } - - async getNonce(): Promise { - return Number(await this.contract.nonce()) - } - - async getThreshold(): Promise { - return Number(await this.contract.getThreshold()) - } - - async getOwners(): Promise { - return this.contract.getOwners() - } - - async isOwner(address: string): Promise { - return this.contract.isOwner(address) - } - - async getTransactionHash(safeTransactionData: SafeTransactionData): Promise { - return this.contract.getTransactionHash( - safeTransactionData.to, - safeTransactionData.value, - safeTransactionData.data, - safeTransactionData.operation, - safeTransactionData.safeTxGas, - safeTransactionData.baseGas, - safeTransactionData.gasPrice, - safeTransactionData.gasToken, - safeTransactionData.refundReceiver, - safeTransactionData.nonce - ) - } - - async approvedHashes(ownerAddress: string, hash: string): Promise { - return this.contract.approvedHashes(ownerAddress, hash) - } - - async approveHash( - hash: string, - options?: EthersTransactionOptions - ): Promise { - if (options && !options.gasLimit) { - options.gasLimit = await this.estimateGas('approveHash', [hash], { ...options }) - } - const txResponse = await this.contract.approveHash(hash, { ...options }) - return toTxResult(txResponse, options) - } - - abstract getModules(): Promise - - abstract getModulesPaginated(start: string, pageSize: number): Promise - - abstract isModuleEnabled(moduleAddress: string): Promise - - async isValidTransaction( - safeTransaction: SafeTransaction, - options?: EthersTransactionOptions - ): Promise { - let isTxValid = false - try { - if (options && !options.gasLimit) { - options.gasLimit = await this.estimateGas( - 'execTransaction', - [ - safeTransaction.data.to, - safeTransaction.data.value, - safeTransaction.data.data, - safeTransaction.data.operation, - safeTransaction.data.safeTxGas, - safeTransaction.data.baseGas, - safeTransaction.data.gasPrice, - safeTransaction.data.gasToken, - safeTransaction.data.refundReceiver, - safeTransaction.encodedSignatures() - ], - { - ...options - } - ) - } - isTxValid = await this.contract.execTransaction.staticCall( - safeTransaction.data.to, - safeTransaction.data.value, - safeTransaction.data.data, - safeTransaction.data.operation, - safeTransaction.data.safeTxGas, - safeTransaction.data.baseGas, - safeTransaction.data.gasPrice, - safeTransaction.data.gasToken, - safeTransaction.data.refundReceiver, - safeTransaction.encodedSignatures(), - { ...options } - ) - } catch {} - return isTxValid - } - - async execTransaction( - safeTransaction: SafeTransaction, - options?: EthersTransactionOptions - ): Promise { - if (options && !options.gasLimit) { - options.gasLimit = await this.estimateGas( - 'execTransaction', - [ - safeTransaction.data.to, - safeTransaction.data.value, - safeTransaction.data.data, - safeTransaction.data.operation, - safeTransaction.data.safeTxGas, - safeTransaction.data.baseGas, - safeTransaction.data.gasPrice, - safeTransaction.data.gasToken, - safeTransaction.data.refundReceiver, - safeTransaction.encodedSignatures() - ], - { - ...options - } - ) - } - const txResponse = await this.contract.execTransaction( - safeTransaction.data.to, - safeTransaction.data.value, - safeTransaction.data.data, - safeTransaction.data.operation, - safeTransaction.data.safeTxGas, - safeTransaction.data.baseGas, - safeTransaction.data.gasPrice, - safeTransaction.data.gasToken, - safeTransaction.data.refundReceiver, - safeTransaction.encodedSignatures(), - { ...options } - ) - return toTxResult(txResponse, options) - } - - encode: SafeInterface['encodeFunctionData'] = (methodName: any, params: any): string => { - return this.contract.interface.encodeFunctionData(methodName, params) - } - - async estimateGas( - methodName: string, - params: any[], - options: EthersTransactionOptions - ): Promise { - const method = this.contract.getFunction(methodName) - - return (await method.estimateGas(...params, options)).toString() - } -} - -export default SafeContractEthers diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/Safe/v1.0.0/SafeContract_V1_0_0_Ethers.ts b/packages/protocol-kit/src/adapters/ethers/contracts/Safe/v1.0.0/SafeContract_V1_0_0_Ethers.ts deleted file mode 100644 index 6982e4d0b..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/Safe/v1.0.0/SafeContract_V1_0_0_Ethers.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { - EthersTransactionOptions, - EthersTransactionResult -} from '@safe-global/protocol-kit/adapters/ethers/types' -import { sameString, toTxResult } from '@safe-global/protocol-kit/adapters/ethers/utils' -import { EMPTY_DATA, ZERO_ADDRESS } from '@safe-global/protocol-kit/adapters/ethers/utils/constants' -import { Gnosis_safe as Safe } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.0.0/Gnosis_safe' -import { SafeSetupConfig } from '@safe-global/safe-core-sdk-types' -import SafeContractEthers from '../SafeContractEthers' -import { SENTINEL_ADDRESS } from '@safe-global/protocol-kit/utils/constants' - -class SafeContract_V1_0_0_Ethers extends SafeContractEthers { - constructor(public contract: Safe) { - super(contract) - } - - async setup( - setupConfig: SafeSetupConfig, - options?: EthersTransactionOptions - ): Promise { - const { - owners, - threshold, - to = ZERO_ADDRESS, - data = EMPTY_DATA, - paymentToken = ZERO_ADDRESS, - payment = 0, - paymentReceiver = ZERO_ADDRESS - } = setupConfig - - if (options && !options.gasLimit) { - options.gasLimit = await this.estimateGas( - 'setup', - [owners, threshold, to, data, paymentToken, payment, paymentReceiver], - { - ...options - } - ) - } - const txResponse = await this.contract.setup( - owners, - threshold, - to, - data, - paymentToken, - payment, - paymentReceiver, - { ...options } - ) - - return toTxResult(txResponse, options) - } - - async getModules(): Promise { - return this.contract.getModules() - } - - async getModulesPaginated(start: string, pageSize: number): Promise { - if (pageSize <= 0) throw new Error('Invalid page size for fetching paginated modules') - - const array = await this.getModules() - if (start === SENTINEL_ADDRESS) { - return array.slice(0, pageSize) - } else { - const moduleIndex = array.findIndex((module: string) => sameString(module, start)) - return moduleIndex === -1 ? [] : array.slice(moduleIndex + 1, pageSize) - } - } - - async isModuleEnabled(moduleAddress: string): Promise { - const modules = await this.getModules() - const isModuleEnabled = modules.some((enabledModuleAddress: string) => - sameString(enabledModuleAddress, moduleAddress) - ) - return isModuleEnabled - } -} - -export default SafeContract_V1_0_0_Ethers diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/Safe/v1.1.1/SafeContract_V1_1_1_Ethers.ts b/packages/protocol-kit/src/adapters/ethers/contracts/Safe/v1.1.1/SafeContract_V1_1_1_Ethers.ts deleted file mode 100644 index 5b5a7a6c5..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/Safe/v1.1.1/SafeContract_V1_1_1_Ethers.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { - EthersTransactionOptions, - EthersTransactionResult -} from '@safe-global/protocol-kit/adapters/ethers/types' -import { sameString, toTxResult } from '@safe-global/protocol-kit/adapters/ethers/utils' -import { EMPTY_DATA, ZERO_ADDRESS } from '@safe-global/protocol-kit/adapters/ethers/utils/constants' -import { Gnosis_safe as Safe } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.1.1/Gnosis_safe' -import { SafeSetupConfig } from '@safe-global/safe-core-sdk-types' -import SafeContractEthers from '../SafeContractEthers' - -class SafeContract_V1_1_1_Ethers extends SafeContractEthers { - constructor(public contract: Safe) { - super(contract) - } - - async setup( - setupConfig: SafeSetupConfig, - options?: EthersTransactionOptions - ): Promise { - const { - owners, - threshold, - to = ZERO_ADDRESS, - data = EMPTY_DATA, - fallbackHandler = ZERO_ADDRESS, - paymentToken = ZERO_ADDRESS, - payment = 0, - paymentReceiver = ZERO_ADDRESS - } = setupConfig - - if (options && !options.gasLimit) { - options.gasLimit = await this.estimateGas( - 'setup', - [owners, threshold, to, data, fallbackHandler, paymentToken, payment, paymentReceiver], - { - ...options - } - ) - } - const txResponse = await this.contract.setup( - owners, - threshold, - to, - data, - fallbackHandler, - paymentToken, - payment, - paymentReceiver, - { ...options } - ) - - return toTxResult(txResponse, options) - } - - async getModules(): Promise { - return this.contract.getModules() - } - - async getModulesPaginated(start: string, pageSize: number): Promise { - const { array } = await this.contract.getModulesPaginated(start, pageSize) - return array - } - - async isModuleEnabled(moduleAddress: string): Promise { - const modules = await this.getModules() - const isModuleEnabled = modules.some((enabledModuleAddress: string) => - sameString(enabledModuleAddress, moduleAddress) - ) - return isModuleEnabled - } -} - -export default SafeContract_V1_1_1_Ethers diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/Safe/v1.2.0/SafeContract_V1_2_0_Ethers.ts b/packages/protocol-kit/src/adapters/ethers/contracts/Safe/v1.2.0/SafeContract_V1_2_0_Ethers.ts deleted file mode 100644 index 06681a23d..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/Safe/v1.2.0/SafeContract_V1_2_0_Ethers.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { - EthersTransactionOptions, - EthersTransactionResult -} from '@safe-global/protocol-kit/adapters/ethers/types' -import { toTxResult } from '@safe-global/protocol-kit/adapters/ethers/utils' -import { EMPTY_DATA, ZERO_ADDRESS } from '@safe-global/protocol-kit/adapters/ethers/utils/constants' -import { Gnosis_safe as Safe } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.2.0/Gnosis_safe' -import { SafeSetupConfig } from '@safe-global/safe-core-sdk-types' -import SafeContractEthers from '../SafeContractEthers' - -class SafeContract_V1_2_0_Ethers extends SafeContractEthers { - constructor(public contract: Safe) { - super(contract) - } - - async setup( - setupConfig: SafeSetupConfig, - options?: EthersTransactionOptions - ): Promise { - const { - owners, - threshold, - to = ZERO_ADDRESS, - data = EMPTY_DATA, - fallbackHandler = ZERO_ADDRESS, - paymentToken = ZERO_ADDRESS, - payment = 0, - paymentReceiver = ZERO_ADDRESS - } = setupConfig - - if (options && !options.gasLimit) { - options.gasLimit = await this.estimateGas( - 'setup', - [owners, threshold, to, data, fallbackHandler, paymentToken, payment, paymentReceiver], - { - ...options - } - ) - } - const txResponse = await this.contract.setup( - owners, - threshold, - to, - data, - fallbackHandler, - paymentToken, - payment, - paymentReceiver, - { ...options } - ) - - return toTxResult(txResponse, options) - } - - async getModules(): Promise { - return this.contract.getModules() - } - - async getModulesPaginated(start: string, pageSize: number): Promise { - const { array } = await this.contract.getModulesPaginated(start, pageSize) - return array - } - - async isModuleEnabled(moduleAddress: string): Promise { - return this.contract.isModuleEnabled(moduleAddress) - } -} - -export default SafeContract_V1_2_0_Ethers diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/Safe/v1.3.0/SafeContract_V1_3_0_Ethers.ts b/packages/protocol-kit/src/adapters/ethers/contracts/Safe/v1.3.0/SafeContract_V1_3_0_Ethers.ts deleted file mode 100644 index a1d8db4ac..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/Safe/v1.3.0/SafeContract_V1_3_0_Ethers.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { - EthersTransactionOptions, - EthersTransactionResult -} from '@safe-global/protocol-kit/adapters/ethers/types' -import { toTxResult } from '@safe-global/protocol-kit/adapters/ethers/utils' -import { - EMPTY_DATA, - SENTINEL_ADDRESS, - ZERO_ADDRESS -} from '@safe-global/protocol-kit/adapters/ethers/utils/constants' -import { Gnosis_safe as Safe } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.3.0/Gnosis_safe' -import { SafeSetupConfig } from '@safe-global/safe-core-sdk-types' -import SafeContractEthers from '../SafeContractEthers' - -class SafeContract_V1_3_0_Ethers extends SafeContractEthers { - constructor(public contract: Safe) { - super(contract) - } - - async setup( - setupConfig: SafeSetupConfig, - options?: EthersTransactionOptions - ): Promise { - const { - owners, - threshold, - to = ZERO_ADDRESS, - data = EMPTY_DATA, - fallbackHandler = ZERO_ADDRESS, - paymentToken = ZERO_ADDRESS, - payment = 0, - paymentReceiver = ZERO_ADDRESS - } = setupConfig - - if (options && !options.gasLimit) { - options.gasLimit = await this.estimateGas( - 'setup', - [owners, threshold, to, data, fallbackHandler, paymentToken, payment, paymentReceiver], - { - ...options - } - ) - } - const txResponse = await this.contract.setup( - owners, - threshold, - to, - data, - fallbackHandler, - paymentToken, - payment, - paymentReceiver, - { ...options } - ) - - return toTxResult(txResponse, options) - } - - async getModules(): Promise { - return await this.getModulesPaginated(SENTINEL_ADDRESS, 10) - } - - async getModulesPaginated(start: string, pageSize: number): Promise { - const { array } = await this.contract.getModulesPaginated(start, pageSize) - return array - } - - async isModuleEnabled(moduleAddress: string): Promise { - return this.contract.isModuleEnabled(moduleAddress) - } -} - -export default SafeContract_V1_3_0_Ethers diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/Safe/v1.4.1/SafeContract_V1_4_1_Ethers.ts b/packages/protocol-kit/src/adapters/ethers/contracts/Safe/v1.4.1/SafeContract_V1_4_1_Ethers.ts deleted file mode 100644 index 94404de44..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/Safe/v1.4.1/SafeContract_V1_4_1_Ethers.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { - EthersTransactionOptions, - EthersTransactionResult -} from '@safe-global/protocol-kit/adapters/ethers/types' -import { toTxResult } from '@safe-global/protocol-kit/adapters/ethers/utils' -import { - EMPTY_DATA, - SENTINEL_ADDRESS, - ZERO_ADDRESS -} from '@safe-global/protocol-kit/adapters/ethers/utils/constants' -import { Safe } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.4.1/Safe' -import { SafeSetupConfig } from '@safe-global/safe-core-sdk-types' -import SafeContractEthers from '../SafeContractEthers' - -class SafeContract_V1_4_1_Ethers extends SafeContractEthers { - constructor(public contract: Safe) { - super(contract) - } - - async setup( - setupConfig: SafeSetupConfig, - options?: EthersTransactionOptions - ): Promise { - const { - owners, - threshold, - to = ZERO_ADDRESS, - data = EMPTY_DATA, - fallbackHandler = ZERO_ADDRESS, - paymentToken = ZERO_ADDRESS, - payment = 0, - paymentReceiver = ZERO_ADDRESS - } = setupConfig - - if (options && !options.gasLimit) { - options.gasLimit = await this.estimateGas( - 'setup', - [owners, threshold, to, data, fallbackHandler, paymentToken, payment, paymentReceiver], - { - ...options - } - ) - } - const txResponse = await this.contract.setup( - owners, - threshold, - to, - data, - fallbackHandler, - paymentToken, - payment, - paymentReceiver, - { ...options } - ) - - return toTxResult(txResponse, options) - } - - async getModules(): Promise { - return await this.getModulesPaginated(SENTINEL_ADDRESS, 10) - } - - async getModulesPaginated(start: string, pageSize: number): Promise { - const { array } = await this.contract.getModulesPaginated(start, pageSize) - return array - } - - async isModuleEnabled(moduleAddress: string): Promise { - return this.contract.isModuleEnabled(moduleAddress) - } -} - -export default SafeContract_V1_4_1_Ethers diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/SafeProxyFactory/SafeProxyFactoryEthersContract.ts b/packages/protocol-kit/src/adapters/ethers/contracts/SafeProxyFactory/SafeProxyFactoryEthersContract.ts deleted file mode 100644 index d4829c1e9..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/SafeProxyFactory/SafeProxyFactoryEthersContract.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { EventLog } from 'ethers' -import { EthersTransactionOptions } from '@safe-global/protocol-kit/adapters/ethers/types' -import { Proxy_factory as SafeProxyFactory_V1_0_0 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.0.0/Proxy_factory' -import { Proxy_factory as SafeProxyFactory_V1_1_1 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.1.1/Proxy_factory' -import { Proxy_factory as SafeProxyFactory_V1_3_0 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.3.0/Proxy_factory' -import { Safe_proxy_factory as SafeProxyFactory_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.4.1/Safe_proxy_factory' -import { SafeProxyFactoryContract } from '@safe-global/safe-core-sdk-types' - -export interface CreateProxyProps { - safeSingletonAddress: string - initializer: string - saltNonce: string - options?: EthersTransactionOptions - callback?: (txHash: string) => void -} - -class SafeProxyFactoryEthersContract implements SafeProxyFactoryContract { - constructor( - public contract: - | SafeProxyFactory_V1_4_1 - | SafeProxyFactory_V1_3_0 - | SafeProxyFactory_V1_1_1 - | SafeProxyFactory_V1_0_0 - ) {} - - getAddress(): Promise { - return this.contract.getAddress() - } - - async proxyCreationCode(): Promise { - return this.contract.proxyCreationCode() - } - - async createProxy({ - safeSingletonAddress, - initializer, - saltNonce, - options, - callback - }: CreateProxyProps): Promise { - if (BigInt(saltNonce) < 0) throw new Error('saltNonce must be greater than or equal to 0') - - if (options && !options.gasLimit) { - options.gasLimit = await this.estimateGas( - 'createProxyWithNonce', - [safeSingletonAddress, initializer, saltNonce], - { - ...options - } - ) - } - const proxyAddress = this.contract - .createProxyWithNonce(safeSingletonAddress, initializer, saltNonce, { ...options }) - .then(async (txResponse) => { - if (callback) { - callback(txResponse.hash) - } - const txReceipt = await txResponse.wait() - const events = txReceipt?.logs as EventLog[] - const proxyCreationEvent = events.find((event) => event?.eventName === 'ProxyCreation') - if (!proxyCreationEvent || !proxyCreationEvent.args) { - throw new Error('SafeProxy was not deployed correctly') - } - const proxyAddress: string = proxyCreationEvent.args[0] - return proxyAddress - }) - return proxyAddress - } - - encode(methodName: string, params: any[]): string { - return (this.contract as any).interface.encodeFunctionData(methodName, params) - } - - async estimateGas( - methodName: string, - params: any[], - options: EthersTransactionOptions - ): Promise { - const method = this.contract.getFunction(methodName) - - return (await method.estimateGas(...params, options)).toString() - } -} - -export default SafeProxyFactoryEthersContract diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/SafeProxyFactory/v1.0.0/SafeProxyFactoryContract_V1_0_0_Ethers.ts b/packages/protocol-kit/src/adapters/ethers/contracts/SafeProxyFactory/v1.0.0/SafeProxyFactoryContract_V1_0_0_Ethers.ts deleted file mode 100644 index eeb302cce..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/SafeProxyFactory/v1.0.0/SafeProxyFactoryContract_V1_0_0_Ethers.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Proxy_factory as ProxyFactory } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.0.0/Proxy_factory' -import SafeProxyFactoryEthersContract from '../SafeProxyFactoryEthersContract' - -class SafeProxyFactoryContract_V1_0_0_Ethers extends SafeProxyFactoryEthersContract { - constructor(public contract: ProxyFactory) { - super(contract) - } -} - -export default SafeProxyFactoryContract_V1_0_0_Ethers diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/SafeProxyFactory/v1.1.1/SafeProxyFactoryContract_V1_1_1_Ethers.ts b/packages/protocol-kit/src/adapters/ethers/contracts/SafeProxyFactory/v1.1.1/SafeProxyFactoryContract_V1_1_1_Ethers.ts deleted file mode 100644 index fcac49d5f..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/SafeProxyFactory/v1.1.1/SafeProxyFactoryContract_V1_1_1_Ethers.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Proxy_factory as ProxyFactory } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.1.1/Proxy_factory' -import SafeProxyFactoryEthersContract from '../SafeProxyFactoryEthersContract' - -class SafeProxyFactoryContract_V1_1_1_Ethers extends SafeProxyFactoryEthersContract { - constructor(public contract: ProxyFactory) { - super(contract) - } -} - -export default SafeProxyFactoryContract_V1_1_1_Ethers diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/SafeProxyFactory/v1.3.0/SafeProxyFactoryContract_V1_3_0_Ethers.ts b/packages/protocol-kit/src/adapters/ethers/contracts/SafeProxyFactory/v1.3.0/SafeProxyFactoryContract_V1_3_0_Ethers.ts deleted file mode 100644 index 12c731c99..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/SafeProxyFactory/v1.3.0/SafeProxyFactoryContract_V1_3_0_Ethers.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Proxy_factory as ProxyFactory } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.3.0/Proxy_factory' -import SafeProxyFactoryEthersContract from '../SafeProxyFactoryEthersContract' - -class SafeProxyFactoryContract_V1_3_0_Ethers extends SafeProxyFactoryEthersContract { - constructor(public contract: ProxyFactory) { - super(contract) - } -} - -export default SafeProxyFactoryContract_V1_3_0_Ethers diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/SafeProxyFactory/v1.4.1/SafeProxyFactoryContract_V1_4_1_Ethers.ts b/packages/protocol-kit/src/adapters/ethers/contracts/SafeProxyFactory/v1.4.1/SafeProxyFactoryContract_V1_4_1_Ethers.ts deleted file mode 100644 index c6d960eaa..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/SafeProxyFactory/v1.4.1/SafeProxyFactoryContract_V1_4_1_Ethers.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Safe_proxy_factory as SafeProxyFactory } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.4.1/Safe_proxy_factory' -import SafeProxyFactoryEthersContract from '../SafeProxyFactoryEthersContract' - -class SafeProxyFactoryContract_V1_4_1_Ethers extends SafeProxyFactoryEthersContract { - constructor(public contract: SafeProxyFactory) { - super(contract) - } -} - -export default SafeProxyFactoryContract_V1_4_1_Ethers diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/SignMessageLib/SignMessageLibEthersContract.ts b/packages/protocol-kit/src/adapters/ethers/contracts/SignMessageLib/SignMessageLibEthersContract.ts deleted file mode 100644 index c147c7aa6..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/SignMessageLib/SignMessageLibEthersContract.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { - EthersTransactionOptions, - EthersTransactionResult -} from '@safe-global/protocol-kit/adapters/ethers/types' -import { toTxResult } from '@safe-global/protocol-kit/adapters/ethers/utils' -import { - Sign_message_lib as SignMessageLib_V1_3_0, - Sign_message_libInterface as SignMessageLibContractInterface -} from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.3.0/Sign_message_lib' -import { Sign_message_lib as SignMessageLib_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.4.1/Sign_message_lib' -import { SignMessageLibContract } from '@safe-global/safe-core-sdk-types' - -abstract class SignMessageLibEthersContract implements SignMessageLibContract { - constructor(public contract: SignMessageLib_V1_4_1 | SignMessageLib_V1_3_0) {} - - getAddress(): Promise { - return this.contract.getAddress() - } - - async signMessage( - data: string, - options?: EthersTransactionOptions - ): Promise { - if (options && !options.gasLimit) { - options.gasLimit = await this.estimateGas('signMessage', [data], { ...options }) - } - const txResponse = await this.contract.signMessage(data, { ...options }) - return toTxResult(txResponse, options) - } - - async getMessageHash(message: string): Promise { - return this.contract.getMessageHash(message) - } - - encode: SignMessageLibContractInterface['encodeFunctionData'] = ( - methodName: any, - params: any - ): string => { - return this.contract.interface.encodeFunctionData(methodName, params) - } - - async estimateGas( - methodName: string, - params: any[], - options: EthersTransactionOptions - ): Promise { - const method = this.contract.getFunction(methodName) - - return (await method.estimateGas(...params, options)).toString() - } -} - -export default SignMessageLibEthersContract diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/SignMessageLib/v1.3.0/SignMessageLibContract_V1_3_0_Ethers.ts b/packages/protocol-kit/src/adapters/ethers/contracts/SignMessageLib/v1.3.0/SignMessageLibContract_V1_3_0_Ethers.ts deleted file mode 100644 index ee9d19997..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/SignMessageLib/v1.3.0/SignMessageLibContract_V1_3_0_Ethers.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Sign_message_lib as SignMessageLib } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.3.0/Sign_message_lib' -import SignMessageLibEthersContract from '../SignMessageLibEthersContract' - -class SignMessageLibContract_V1_3_0_Ethers extends SignMessageLibEthersContract { - constructor(public contract: SignMessageLib) { - super(contract) - } -} - -export default SignMessageLibContract_V1_3_0_Ethers diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/SignMessageLib/v1.4.1/SignMessageLibContract_V1_4_1_Ethers.ts b/packages/protocol-kit/src/adapters/ethers/contracts/SignMessageLib/v1.4.1/SignMessageLibContract_V1_4_1_Ethers.ts deleted file mode 100644 index 1e950a45e..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/SignMessageLib/v1.4.1/SignMessageLibContract_V1_4_1_Ethers.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Sign_message_lib as SignMessageLib } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.4.1/Sign_message_lib' -import SignMessageLibEthersContract from '../SignMessageLibEthersContract' - -class SignMessageLibContract_V1_4_1_Ethers extends SignMessageLibEthersContract { - constructor(public contract: SignMessageLib) { - super(contract) - } -} - -export default SignMessageLibContract_V1_4_1_Ethers diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/SimulateTxAccessor/SimulateTxAccessorEthersContract.ts b/packages/protocol-kit/src/adapters/ethers/contracts/SimulateTxAccessor/SimulateTxAccessorEthersContract.ts deleted file mode 100644 index 0306dcb3f..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/SimulateTxAccessor/SimulateTxAccessorEthersContract.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { - Simulate_tx_accessor as SimulateTxAccessor_V1_3_0, - Simulate_tx_accessorInterface as SimulateTxAccessorInterface -} from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.3.0/Simulate_tx_accessor' -import { Simulate_tx_accessor as SimulateTxAccessor_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.4.1/Simulate_tx_accessor' -import { SimulateTxAccessorContract } from '@safe-global/safe-core-sdk-types' - -abstract class SimulateTxAccessorEthersContract implements SimulateTxAccessorContract { - constructor(public contract: SimulateTxAccessor_V1_4_1 | SimulateTxAccessor_V1_3_0) {} - - getAddress(): Promise { - return this.contract.getAddress() - } - - encode: SimulateTxAccessorInterface['encodeFunctionData'] = ( - methodName: any, - params: any - ): string => { - return this.contract.interface.encodeFunctionData(methodName, params) - } -} - -export default SimulateTxAccessorEthersContract diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/SimulateTxAccessor/v1.3.0/SimulateTxAccessorContract_V1_3_0_Ethers.ts b/packages/protocol-kit/src/adapters/ethers/contracts/SimulateTxAccessor/v1.3.0/SimulateTxAccessorContract_V1_3_0_Ethers.ts deleted file mode 100644 index 1646cd048..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/SimulateTxAccessor/v1.3.0/SimulateTxAccessorContract_V1_3_0_Ethers.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Simulate_tx_accessor as SimulateTxAccessor } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.3.0/Simulate_tx_accessor' -import SimulateTxAccessorEthersContract from '../SimulateTxAccessorEthersContract' - -class SimulateTxAccessorContract_V1_3_0_Ethers extends SimulateTxAccessorEthersContract { - constructor(public contract: SimulateTxAccessor) { - super(contract) - } -} - -export default SimulateTxAccessorContract_V1_3_0_Ethers diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/SimulateTxAccessor/v1.4.1/SimulateTxAccessorContract_V1_4_1_Ethers.ts b/packages/protocol-kit/src/adapters/ethers/contracts/SimulateTxAccessor/v1.4.1/SimulateTxAccessorContract_V1_4_1_Ethers.ts deleted file mode 100644 index 7315ed1ae..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/SimulateTxAccessor/v1.4.1/SimulateTxAccessorContract_V1_4_1_Ethers.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Simulate_tx_accessor as SimulateTxAccessor } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.4.1/Simulate_tx_accessor' -import SimulateTxAccessorEthersContract from '../SimulateTxAccessorEthersContract' - -class SimulateTxAccessorContract_V1_4_1_Ethers extends SimulateTxAccessorEthersContract { - constructor(public contract: SimulateTxAccessor) { - super(contract) - } -} - -export default SimulateTxAccessorContract_V1_4_1_Ethers diff --git a/packages/protocol-kit/src/adapters/ethers/contracts/contractInstancesEthers.ts b/packages/protocol-kit/src/adapters/ethers/contracts/contractInstancesEthers.ts deleted file mode 100644 index cd179e9ee..000000000 --- a/packages/protocol-kit/src/adapters/ethers/contracts/contractInstancesEthers.ts +++ /dev/null @@ -1,249 +0,0 @@ -import { AbstractSigner, Provider } from 'ethers' -import { Gnosis_safe__factory as SafeSingleton_V1_0_0 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.0.0/factories/Gnosis_safe__factory' -import { Proxy_factory__factory as SafeProxyFactory_V1_0_0 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.0.0/factories/Proxy_factory__factory' -import { Gnosis_safe__factory as SafeSingleton_V1_1_1 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.1.1/factories/Gnosis_safe__factory' -import { Multi_send__factory as MultiSend_V1_1_1 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.1.1/factories/Multi_send__factory' -import { Proxy_factory__factory as SafeProxyFactory_V1_1_1 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.1.1/factories/Proxy_factory__factory' -import { Gnosis_safe__factory as SafeSingleton_V1_2_0 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.2.0/factories/Gnosis_safe__factory' -import { Compatibility_fallback_handler__factory as CompatibilityFallbackHandler_V1_3_0 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.3.0/factories/Compatibility_fallback_handler__factory' -import { Create_call__factory as CreateCall_V1_3_0 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.3.0/factories/Create_call__factory' -import { Gnosis_safe__factory as SafeSingleton_V1_3_0 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.3.0/factories/Gnosis_safe__factory' -import { Multi_send__factory as MultiSend_V1_3_0 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.3.0/factories/Multi_send__factory' -import { Multi_send_call_only__factory as MultiSendCallOnly_V1_3_0 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.3.0/factories/Multi_send_call_only__factory' -import { Proxy_factory__factory as SafeProxyFactory_V1_3_0 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.3.0/factories/Proxy_factory__factory' -import { Sign_message_lib__factory as SignMessageLib_V1_3_0 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.3.0/factories/Sign_message_lib__factory' -import { Simulate_tx_accessor__factory as SimulateTxAccessor_V1_3_0 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.3.0/factories/Simulate_tx_accessor__factory' -import { Compatibility_fallback_handler__factory as CompatibilityFallbackHandler_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.4.1/factories/Compatibility_fallback_handler__factory' -import { Create_call__factory as CreateCall_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.4.1/factories/Create_call__factory' -import { Multi_send__factory as MultiSend_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.4.1/factories/Multi_send__factory' -import { Multi_send_call_only__factory as MultiSendCallOnly_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.4.1/factories/Multi_send_call_only__factory' -import { Safe__factory as SafeSingleton_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.4.1/factories/Safe__factory' -import { Safe_proxy_factory__factory as SafeProxyFactory_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.4.1/factories/Safe_proxy_factory__factory' -import { Sign_message_lib__factory as SignMessageLib_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.4.1/factories/Sign_message_lib__factory' -import { Simulate_tx_accessor__factory as SimulateTxAccessor_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.4.1/factories/Simulate_tx_accessor__factory' -import { SafeVersion } from '@safe-global/safe-core-sdk-types' -import CompatibilityFallbackHandler_V1_3_0_Ethers from './CompatibilityFallbackHandler/v1.3.0/CompatibilityFallbackHandler_V1_3_0_Ethers' -import CompatibilityFallbackHandler_V1_4_1_Ethers from './CompatibilityFallbackHandler/v1.4.1/CompatibilityFallbackHandler_V1_4_1_Ethers' -import CreateCallContract_V1_3_0_Ethers from './CreateCall/v1.3.0/CreateCallEthersContract_V1_3_0_Ethers' -import CreateCallContract_V1_4_1_Ethers from './CreateCall/v1.4.1/CreateCallEthersContract_V1_4_1_Ethers' -import MultiSendContract_V1_1_1_Ethers from './MultiSend/v1.1.1/MultiSendContract_V1_1_1_Ethers' -import MultiSendContract_V1_3_0_Ethers from './MultiSend/v1.3.0/MultiSendContract_V1_3_0_Ethers' -import MultiSendContract_V1_4_1_Ethers from './MultiSend/v1.4.1/MultiSendContract_V1_4_1_Ethers' -import MultiSendCallOnlyContract_V1_3_0_Ethers from './MultiSendCallOnly/v1.3.0/MultiSendCallOnlyContract_V1_3_0_Ethers' -import MultiSendCallOnlyContract_V1_4_1_Ethers from './MultiSendCallOnly/v1.4.1/MultiSendCallOnlyContract_V1_4_1_Ethers' -import SafeContract_V1_0_0_Ethers from './Safe/v1.0.0/SafeContract_V1_0_0_Ethers' -import SafeContract_V1_1_1_Ethers from './Safe/v1.1.1/SafeContract_V1_1_1_Ethers' -import SafeContract_V1_2_0_Ethers from './Safe/v1.2.0/SafeContract_V1_2_0_Ethers' -import SafeContract_V1_3_0_Ethers from './Safe/v1.3.0/SafeContract_V1_3_0_Ethers' -import SafeContract_V1_4_1_Ethers from './Safe/v1.4.1/SafeContract_V1_4_1_Ethers' -import SafeProxyFactoryContract_V1_0_0_Ethers from './SafeProxyFactory/v1.0.0/SafeProxyFactoryContract_V1_0_0_Ethers' -import SafeProxyFactoryContract_V1_1_1_Ethers from './SafeProxyFactory/v1.1.1/SafeProxyFactoryContract_V1_1_1_Ethers' -import SafeProxyFactoryContract_V1_3_0_Ethers from './SafeProxyFactory/v1.3.0/SafeProxyFactoryContract_V1_3_0_Ethers' -import SafeProxyFactoryContract_V1_4_1_Ethers from './SafeProxyFactory/v1.4.1/SafeProxyFactoryContract_V1_4_1_Ethers' -import SignMessageLibContract_V1_3_0_Ethers from './SignMessageLib/v1.3.0/SignMessageLibContract_V1_3_0_Ethers' -import SignMessageLibContract_V1_4_1_Ethers from './SignMessageLib/v1.4.1/SignMessageLibContract_V1_4_1_Ethers' -import SimulateTxAccessorContract_V1_3_0_Ethers from './SimulateTxAccessor/v1.3.0/SimulateTxAccessorContract_V1_3_0_Ethers' -import SimulateTxAccessorContract_V1_4_1_Ethers from './SimulateTxAccessor/v1.4.1/SimulateTxAccessorContract_V1_4_1_Ethers' - -export function getSafeContractInstance( - safeVersion: SafeVersion, - contractAddress: string, - signerOrProvider: AbstractSigner | Provider -): - | SafeContract_V1_4_1_Ethers - | SafeContract_V1_3_0_Ethers - | SafeContract_V1_2_0_Ethers - | SafeContract_V1_1_1_Ethers - | SafeContract_V1_0_0_Ethers { - let safeContract - switch (safeVersion) { - case '1.4.1': - safeContract = SafeSingleton_V1_4_1.connect(contractAddress, signerOrProvider) - return new SafeContract_V1_4_1_Ethers(safeContract) - case '1.3.0': - safeContract = SafeSingleton_V1_3_0.connect(contractAddress, signerOrProvider) - return new SafeContract_V1_3_0_Ethers(safeContract) - case '1.2.0': - safeContract = SafeSingleton_V1_2_0.connect(contractAddress, signerOrProvider) - return new SafeContract_V1_2_0_Ethers(safeContract) - case '1.1.1': - safeContract = SafeSingleton_V1_1_1.connect(contractAddress, signerOrProvider) - return new SafeContract_V1_1_1_Ethers(safeContract) - case '1.0.0': - safeContract = SafeSingleton_V1_0_0.connect(contractAddress, signerOrProvider) - return new SafeContract_V1_0_0_Ethers(safeContract) - default: - throw new Error('Invalid Safe version') - } -} - -export function getCompatibilityFallbackHandlerContractInstance( - safeVersion: SafeVersion, - contractAddress: string, - signerOrProvider: AbstractSigner | Provider -): CompatibilityFallbackHandler_V1_4_1_Ethers | CompatibilityFallbackHandler_V1_3_0_Ethers { - let compatibilityFallbackHandlerContract - switch (safeVersion) { - case '1.4.1': - compatibilityFallbackHandlerContract = CompatibilityFallbackHandler_V1_4_1.connect( - contractAddress, - signerOrProvider - ) - return new CompatibilityFallbackHandler_V1_4_1_Ethers(compatibilityFallbackHandlerContract) - case '1.3.0': - case '1.2.0': - case '1.1.1': - compatibilityFallbackHandlerContract = CompatibilityFallbackHandler_V1_3_0.connect( - contractAddress, - signerOrProvider - ) - return new CompatibilityFallbackHandler_V1_3_0_Ethers(compatibilityFallbackHandlerContract) - default: - throw new Error('Invalid Safe version') - } -} - -export function getMultiSendContractInstance( - safeVersion: SafeVersion, - contractAddress: string, - signerOrProvider: AbstractSigner | Provider -): - | MultiSendContract_V1_4_1_Ethers - | MultiSendContract_V1_3_0_Ethers - | MultiSendContract_V1_1_1_Ethers { - let multiSendContract - switch (safeVersion) { - case '1.4.1': - multiSendContract = MultiSend_V1_4_1.connect(contractAddress, signerOrProvider) - return new MultiSendContract_V1_4_1_Ethers(multiSendContract) - case '1.3.0': - multiSendContract = MultiSend_V1_3_0.connect(contractAddress, signerOrProvider) - return new MultiSendContract_V1_3_0_Ethers(multiSendContract) - case '1.2.0': - case '1.1.1': - case '1.0.0': - multiSendContract = MultiSend_V1_1_1.connect(contractAddress, signerOrProvider) - return new MultiSendContract_V1_1_1_Ethers(multiSendContract) - default: - throw new Error('Invalid Safe version') - } -} - -export function getMultiSendCallOnlyContractInstance( - safeVersion: SafeVersion, - contractAddress: string, - signerOrProvider: AbstractSigner | Provider -): MultiSendCallOnlyContract_V1_4_1_Ethers | MultiSendCallOnlyContract_V1_3_0_Ethers { - let multiSendCallOnlyContract - switch (safeVersion) { - case '1.4.1': - multiSendCallOnlyContract = MultiSendCallOnly_V1_4_1.connect( - contractAddress, - signerOrProvider - ) - return new MultiSendCallOnlyContract_V1_4_1_Ethers(multiSendCallOnlyContract) - case '1.3.0': - case '1.2.0': - case '1.1.1': - case '1.0.0': - multiSendCallOnlyContract = MultiSendCallOnly_V1_3_0.connect( - contractAddress, - signerOrProvider - ) - return new MultiSendCallOnlyContract_V1_3_0_Ethers(multiSendCallOnlyContract) - default: - throw new Error('Invalid Safe version') - } -} - -export function getSafeProxyFactoryContractInstance( - safeVersion: SafeVersion, - contractAddress: string, - signerOrProvider: AbstractSigner | Provider -): - | SafeProxyFactoryContract_V1_4_1_Ethers - | SafeProxyFactoryContract_V1_3_0_Ethers - | SafeProxyFactoryContract_V1_1_1_Ethers - | SafeProxyFactoryContract_V1_0_0_Ethers { - let safeProxyFactoryContract - switch (safeVersion) { - case '1.4.1': - safeProxyFactoryContract = SafeProxyFactory_V1_4_1.connect(contractAddress, signerOrProvider) - return new SafeProxyFactoryContract_V1_4_1_Ethers(safeProxyFactoryContract) - case '1.3.0': - safeProxyFactoryContract = SafeProxyFactory_V1_3_0.connect(contractAddress, signerOrProvider) - return new SafeProxyFactoryContract_V1_3_0_Ethers(safeProxyFactoryContract) - case '1.2.0': - case '1.1.1': - safeProxyFactoryContract = SafeProxyFactory_V1_1_1.connect(contractAddress, signerOrProvider) - return new SafeProxyFactoryContract_V1_1_1_Ethers(safeProxyFactoryContract) - case '1.0.0': - safeProxyFactoryContract = SafeProxyFactory_V1_0_0.connect(contractAddress, signerOrProvider) - return new SafeProxyFactoryContract_V1_0_0_Ethers(safeProxyFactoryContract) - default: - throw new Error('Invalid Safe version') - } -} - -export function getSignMessageLibContractInstance( - safeVersion: SafeVersion, - contractAddress: string, - signerOrProvider: AbstractSigner | Provider -): SignMessageLibContract_V1_4_1_Ethers | SignMessageLibContract_V1_3_0_Ethers { - let signMessageLibContract - switch (safeVersion) { - case '1.4.1': - signMessageLibContract = SignMessageLib_V1_4_1.connect(contractAddress, signerOrProvider) - return new SignMessageLibContract_V1_4_1_Ethers(signMessageLibContract) - case '1.3.0': - signMessageLibContract = SignMessageLib_V1_3_0.connect(contractAddress, signerOrProvider) - return new SignMessageLibContract_V1_3_0_Ethers(signMessageLibContract) - default: - throw new Error('Invalid Safe version') - } -} - -export function getCreateCallContractInstance( - safeVersion: SafeVersion, - contractAddress: string, - signerOrProvider: AbstractSigner | Provider -): CreateCallContract_V1_4_1_Ethers | CreateCallContract_V1_3_0_Ethers { - let createCallContract - switch (safeVersion) { - case '1.4.1': - createCallContract = CreateCall_V1_4_1.connect(contractAddress, signerOrProvider) - return new CreateCallContract_V1_4_1_Ethers(createCallContract) - case '1.3.0': - case '1.2.0': - case '1.1.1': - case '1.0.0': - createCallContract = CreateCall_V1_3_0.connect(contractAddress, signerOrProvider) - return new CreateCallContract_V1_3_0_Ethers(createCallContract) - default: - throw new Error('Invalid Safe version') - } -} - -export function getSimulateTxAccessorContractInstance( - safeVersion: SafeVersion, - contractAddress: string, - signerOrProvider: AbstractSigner | Provider -): SimulateTxAccessorContract_V1_4_1_Ethers | SimulateTxAccessorContract_V1_3_0_Ethers { - let simulateTxAccessorContract - switch (safeVersion) { - case '1.4.1': - simulateTxAccessorContract = SimulateTxAccessor_V1_4_1.connect( - contractAddress, - signerOrProvider - ) - return new SimulateTxAccessorContract_V1_4_1_Ethers(simulateTxAccessorContract) - case '1.3.0': - simulateTxAccessorContract = SimulateTxAccessor_V1_3_0.connect( - contractAddress, - signerOrProvider - ) - return new SimulateTxAccessorContract_V1_3_0_Ethers(simulateTxAccessorContract) - default: - throw new Error('Invalid Safe version') - } -} diff --git a/packages/protocol-kit/src/adapters/ethers/index.ts b/packages/protocol-kit/src/adapters/ethers/index.ts deleted file mode 100644 index ac2473f50..000000000 --- a/packages/protocol-kit/src/adapters/ethers/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -import EthersAdapter, { EthersAdapterConfig } from './EthersAdapter' -import CreateCallEthersContract from './contracts/CreateCall/CreateCallEthersContract' -import MultiSendEthersContract from './contracts/MultiSend/MultiSendEthersContract' -import MultiSendCallOnlyEthersContract from './contracts/MultiSendCallOnly/MultiSendCallOnlyEthersContract' -import SafeContractEthers from './contracts/Safe/SafeContractEthers' -import SafeProxyFactoryEthersContract, { - CreateProxyProps -} from './contracts/SafeProxyFactory/SafeProxyFactoryEthersContract' -import SignMessageLibEthersContract from './contracts/SignMessageLib/SignMessageLibEthersContract' -import { EthersTransactionOptions, EthersTransactionResult } from './types' - -export { - CreateCallEthersContract, - CreateProxyProps, - EthersAdapter, - EthersAdapterConfig, - EthersTransactionOptions, - EthersTransactionResult, - MultiSendCallOnlyEthersContract, - MultiSendEthersContract, - SafeContractEthers, - SafeProxyFactoryEthersContract, - SignMessageLibEthersContract -} diff --git a/packages/protocol-kit/src/adapters/ethers/types.ts b/packages/protocol-kit/src/adapters/ethers/types.ts deleted file mode 100644 index 0c9e606ca..000000000 --- a/packages/protocol-kit/src/adapters/ethers/types.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { ContractTransactionResponse } from 'ethers' -import { BaseTransactionResult } from '@safe-global/safe-core-sdk-types' - -export interface EthersTransactionOptions { - from?: string - gasLimit?: number | string - gasPrice?: number | string - maxFeePerGas?: number | string - maxPriorityFeePerGas?: number | string - nonce?: number -} - -export interface EthersTransactionResult extends BaseTransactionResult { - transactionResponse: ContractTransactionResponse - options?: EthersTransactionOptions -} diff --git a/packages/protocol-kit/src/adapters/ethers/utils/index.ts b/packages/protocol-kit/src/adapters/ethers/utils/index.ts deleted file mode 100644 index 3912dcf14..000000000 --- a/packages/protocol-kit/src/adapters/ethers/utils/index.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { ContractTransactionResponse, Provider, AbstractSigner } from 'ethers' -import { EthersTransactionOptions, EthersTransactionResult } from '../types' - -export function sameString(str1: string, str2: string): boolean { - return str1.toLowerCase() === str2.toLowerCase() -} - -export function toTxResult( - transactionResponse: ContractTransactionResponse, - options?: EthersTransactionOptions -): EthersTransactionResult { - return { - hash: transactionResponse.hash, - options, - transactionResponse - } -} - -export function isTypedDataSigner(signer: any): signer is AbstractSigner { - return (signer as unknown as AbstractSigner).signTypedData !== undefined -} - -/** - * Check if the signerOrProvider is compatible with `Signer` - * @param signerOrProvider - Signer or provider - * @returns true if the parameter is compatible with `Signer` - */ -export function isSignerCompatible(signerOrProvider: AbstractSigner | Provider): boolean { - const candidate = signerOrProvider as AbstractSigner - - const isSigntransactionCompatible = typeof candidate.signTransaction === 'function' - const isSignMessageCompatible = typeof candidate.signMessage === 'function' - const isGetAddressCompatible = typeof candidate.getAddress === 'function' - - return isSigntransactionCompatible && isSignMessageCompatible && isGetAddressCompatible -} diff --git a/packages/protocol-kit/src/adapters/web3/README.md b/packages/protocol-kit/src/adapters/web3/README.md deleted file mode 100644 index 71ab2cf35..000000000 --- a/packages/protocol-kit/src/adapters/web3/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# Web3 Adapter - -Web3.js wrapper that contains some utilities and the Safe contracts types (generated with `typechain` `web3-v1`). It is used to initialize the [Protocol Kit](https://github.com/safe-global/safe-core-sdk/tree/main/packages/protocol-kit). - -## How to use - -If the app integrating the SDK is using `Web3`, create an instance of the `Web3Adapter`, where `signerAddress` is the Ethereum account we are connecting and the one who will sign the transactions. - -```js -import Web3 from 'web3' -import { Web3Adapter } from '@safe-global/protocol-kit' - -const provider = new Web3.providers.HttpProvider('http://localhost:8545') -const web3 = new Web3(provider) -const safeOwner = '0x
' - -const ethAdapter = new Web3Adapter({ - web3, - signerAddress: safeOwner -}) -``` - -In case the `ethAdapter` instance is only used to execute read-only methods the `signerAddress` property can be omitted. - -```js -const readOnlyEthAdapter = new Web3Adapter({ web3 }) -``` diff --git a/packages/protocol-kit/src/adapters/web3/Web3Adapter.ts b/packages/protocol-kit/src/adapters/web3/Web3Adapter.ts deleted file mode 100644 index f8fca35dc..000000000 --- a/packages/protocol-kit/src/adapters/web3/Web3Adapter.ts +++ /dev/null @@ -1,341 +0,0 @@ -import { generateTypedData, validateEip3770Address } from '@safe-global/protocol-kit/utils' -import { - Eip3770Address, - EthAdapter, - EthAdapterTransaction, - GetContractProps, - SafeEIP712Args -} from '@safe-global/safe-core-sdk-types' -import Web3 from 'web3' -import { Transaction } from 'web3-core' -import { ContractOptions } from 'web3-eth-contract' -import { AbiItem } from 'web3-utils' -// TODO remove @types/web3 when migrating to web3@v4 -// Deprecated https://www.npmjs.com/package/@types/web3?activeTab=readme -// Migration guide https://docs.web3js.org/docs/guides/web3_migration_guide#types -import type { JsonRPCResponse, Provider } from 'web3/providers' -import CompatibilityFallbackHandlerWeb3Contract from './contracts/CompatibilityFallbackHandler/CompatibilityFallbackHandlerWeb3Contract' -import CreateCallWeb3Contract from './contracts/CreateCall/CreateCallWeb3Contract' -import MultiSendWeb3Contract from './contracts/MultiSend/MultiSendWeb3Contract' -import MultiSendCallOnlyWeb3Contract from './contracts/MultiSendCallOnly/MultiSendCallOnlyWeb3Contract' -import SafeContractWeb3 from './contracts/Safe/SafeContractWeb3' -import SafeProxyFactoryWeb3Contract from './contracts/SafeProxyFactory/SafeProxyFactoryWeb3Contract' -import SignMessageLibWeb3Contract from './contracts/SignMessageLib/SignMessageLibWeb3Contract' -import SimulateTxAccessorWeb3Contract from './contracts/SimulateTxAccessor/SimulateTxAccessorWeb3Contract' -import { - getCompatibilityFallbackHandlerContractInstance, - getCreateCallContractInstance, - getMultiSendCallOnlyContractInstance, - getMultiSendContractInstance, - getSafeContractInstance, - getSafeProxyFactoryContractInstance, - getSignMessageLibContractInstance, - getSimulateTxAccessorContractInstance -} from './contracts/contractInstancesWeb3' -import { SigningMethod } from '@safe-global/protocol-kit/types' - -export interface Web3AdapterConfig { - /** web3 - Web3 library */ - web3: Web3 - /** signerAddress - Address of the signer */ - signerAddress?: string -} - -class Web3Adapter implements EthAdapter { - #web3: Web3 - #signerAddress?: string - - constructor({ web3, signerAddress }: Web3AdapterConfig) { - if (!web3) { - throw new Error('web3 property missing from options') - } - this.#web3 = web3 - this.#signerAddress = signerAddress - } - - isAddress(address: string): boolean { - return this.#web3.utils.isAddress(address) - } - - async getEip3770Address(fullAddress: string): Promise { - const chainId = await this.getChainId() - return validateEip3770Address(fullAddress, chainId) - } - - async getBalance(address: string, defaultBlock?: string | number): Promise { - const balance = defaultBlock - ? await this.#web3.eth.getBalance(address, defaultBlock) - : await this.#web3.eth.getBalance(address) - return BigInt(balance) - } - - async getNonce(address: string, defaultBlock?: string | number): Promise { - const nonce = defaultBlock - ? await this.#web3.eth.getTransactionCount(address, defaultBlock) - : await this.#web3.eth.getTransactionCount(address) - return nonce - } - - async getChainId(): Promise { - return BigInt(await this.#web3.eth.getChainId()) - } - - getChecksummedAddress(address: string): string { - return this.#web3.utils.toChecksumAddress(address) - } - - async getSafeContract({ - safeVersion, - singletonDeployment, - customContractAddress, - customContractAbi - }: GetContractProps): Promise { - const chainId = await this.getChainId() - const contractAddress = - customContractAddress ?? singletonDeployment?.networkAddresses[chainId.toString()] - if (!contractAddress) { - throw new Error('Invalid SafeProxy contract address') - } - const safeContract = this.getContract( - contractAddress, - customContractAbi ?? (singletonDeployment?.abi as AbiItem[]) - ) - return getSafeContractInstance(safeVersion, safeContract) - } - - async getSafeProxyFactoryContract({ - safeVersion, - singletonDeployment, - customContractAddress, - customContractAbi - }: GetContractProps): Promise { - const chainId = await this.getChainId() - const contractAddress = - customContractAddress ?? singletonDeployment?.networkAddresses[chainId.toString()] - if (!contractAddress) { - throw new Error('Invalid SafeProxyFactory contract address') - } - const proxyFactoryContract = this.getContract( - contractAddress, - customContractAbi ?? (singletonDeployment?.abi as AbiItem[]) - ) - return getSafeProxyFactoryContractInstance(safeVersion, proxyFactoryContract) - } - - async getMultiSendContract({ - safeVersion, - singletonDeployment, - customContractAddress, - customContractAbi - }: GetContractProps): Promise { - const chainId = await this.getChainId() - const contractAddress = - customContractAddress ?? singletonDeployment?.networkAddresses[chainId.toString()] - if (!contractAddress) { - throw new Error('Invalid MultiSend contract address') - } - const multiSendContract = this.getContract( - contractAddress, - customContractAbi ?? (singletonDeployment?.abi as AbiItem[]) - ) - return getMultiSendContractInstance(safeVersion, multiSendContract) - } - - async getMultiSendCallOnlyContract({ - safeVersion, - singletonDeployment, - customContractAddress, - customContractAbi - }: GetContractProps): Promise { - const chainId = await this.getChainId() - const contractAddress = - customContractAddress ?? singletonDeployment?.networkAddresses[chainId.toString()] - if (!contractAddress) { - throw new Error('Invalid MultiSendCallOnly contract address') - } - const multiSendContract = this.getContract( - contractAddress, - customContractAbi ?? (singletonDeployment?.abi as AbiItem[]) - ) - return getMultiSendCallOnlyContractInstance(safeVersion, multiSendContract) - } - - async getCompatibilityFallbackHandlerContract({ - safeVersion, - singletonDeployment, - customContractAddress, - customContractAbi - }: GetContractProps): Promise { - const chainId = await this.getChainId() - const contractAddress = - customContractAddress ?? singletonDeployment?.networkAddresses[chainId.toString()] - if (!contractAddress) { - throw new Error('Invalid Compatibility Fallback Handler contract address') - } - const multiSendContract = this.getContract( - contractAddress, - customContractAbi ?? (singletonDeployment?.abi as AbiItem[]) - ) - return getCompatibilityFallbackHandlerContractInstance(safeVersion, multiSendContract) - } - - async getSignMessageLibContract({ - safeVersion, - singletonDeployment, - customContractAddress, - customContractAbi - }: GetContractProps): Promise { - const chainId = await this.getChainId() - const contractAddress = - customContractAddress ?? singletonDeployment?.networkAddresses[chainId.toString()] - if (!contractAddress) { - throw new Error('Invalid SignMessageLib contract address') - } - const signMessageLibContract = this.getContract( - contractAddress, - customContractAbi ?? (singletonDeployment?.abi as AbiItem[]) - ) - return getSignMessageLibContractInstance(safeVersion, signMessageLibContract) - } - - async getCreateCallContract({ - safeVersion, - singletonDeployment, - customContractAddress, - customContractAbi - }: GetContractProps): Promise { - const chainId = await this.getChainId() - const contractAddress = - customContractAddress ?? singletonDeployment?.networkAddresses[chainId.toString()] - if (!contractAddress) { - throw new Error('Invalid CreateCall contract address') - } - const createCallContract = this.getContract( - contractAddress, - customContractAbi ?? (singletonDeployment?.abi as AbiItem[]) - ) - return getCreateCallContractInstance(safeVersion, createCallContract) - } - - async getSimulateTxAccessorContract({ - safeVersion, - singletonDeployment, - customContractAddress, - customContractAbi - }: GetContractProps): Promise { - const chainId = await this.getChainId() - const contractAddress = - customContractAddress ?? singletonDeployment?.networkAddresses[chainId.toString()] - if (!contractAddress) { - throw new Error('Invalid SimulateTxAccessor contract address') - } - const simulateTxAccessorContract = this.getContract( - contractAddress, - customContractAbi ?? (singletonDeployment?.abi as AbiItem[]) - ) - return getSimulateTxAccessorContractInstance(safeVersion, simulateTxAccessorContract) - } - - getContract(address: string, abi: AbiItem | AbiItem[], options?: ContractOptions): any { - return new this.#web3.eth.Contract(abi, address, options) - } - - async getContractCode(address: string, defaultBlock?: string | number): Promise { - const code = defaultBlock - ? await this.#web3.eth.getCode(address, defaultBlock) - : await this.#web3.eth.getCode(address) - return code - } - - async isContractDeployed(address: string, defaultBlock?: string | number): Promise { - const contractCode = await this.getContractCode(address, defaultBlock) - return contractCode !== '0x' - } - - async getStorageAt(address: string, position: string): Promise { - const content = await this.#web3.eth.getStorageAt(address, position) - const decodedContent = this.decodeParameters(['address'], content) - return decodedContent[0] - } - - async getTransaction(transactionHash: string): Promise { - return this.#web3.eth.getTransaction(transactionHash) - } - - async getSignerAddress(): Promise { - return this.#signerAddress - } - - signMessage(message: string): Promise { - if (!this.#signerAddress) { - throw new Error('EthAdapter must be initialized with a signer to use this method') - } - return this.#web3.eth.sign(message, this.#signerAddress) - } - - async signTypedData( - safeEIP712Args: SafeEIP712Args, - methodVersion?: 'v3' | 'v4' - ): Promise { - if (!this.#signerAddress) { - throw new Error('This method requires a signer') - } - const typedData = generateTypedData(safeEIP712Args) - let method = SigningMethod.ETH_SIGN_TYPED_DATA_V3 - if (methodVersion === 'v4') { - method = SigningMethod.ETH_SIGN_TYPED_DATA_V4 - } else if (!methodVersion) { - method = SigningMethod.ETH_SIGN_TYPED_DATA - } - const jsonTypedData = JSON.stringify(typedData) - const signedTypedData = { - jsonrpc: '2.0', - method, - params: - methodVersion === 'v3' || methodVersion === 'v4' - ? [this.#signerAddress, jsonTypedData] - : [jsonTypedData, this.#signerAddress], - from: this.#signerAddress, - id: new Date().getTime() - } - return new Promise((resolve, reject) => { - const provider = this.#web3.currentProvider as Provider - function callback(err: Error): void - function callback(err: null, val: JsonRPCResponse): void - function callback(err: null | Error, val?: JsonRPCResponse): void { - if (err) { - reject(err) - return - } - - if (val?.result == null) { - reject(new Error("EIP-712 is not supported by user's wallet")) - return - } - resolve(val.result) - } - provider.send(signedTypedData, callback) - }) - } - - async estimateGas( - transaction: EthAdapterTransaction, - callback?: (error: Error, gas: number) => void - ): Promise { - return (await this.#web3.eth.estimateGas(transaction, callback)).toString() - } - - call(transaction: EthAdapterTransaction, defaultBlock?: string | number): Promise { - return this.#web3.eth.call(transaction, defaultBlock) - } - - encodeParameters(types: string[], values: any[]): string { - return this.#web3.eth.abi.encodeParameters(types, values) - } - - decodeParameters(types: any[], values: string): { [key: string]: any } { - return this.#web3.eth.abi.decodeParameters(types, values) - } -} - -export default Web3Adapter diff --git a/packages/protocol-kit/src/adapters/web3/contracts/CompatibilityFallbackHandler/CompatibilityFallbackHandlerWeb3Contract.ts b/packages/protocol-kit/src/adapters/web3/contracts/CompatibilityFallbackHandler/CompatibilityFallbackHandlerWeb3Contract.ts deleted file mode 100644 index 8daaab819..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/CompatibilityFallbackHandler/CompatibilityFallbackHandlerWeb3Contract.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Compatibility_fallback_handler as CompatibilityFallbackHandler_V1_3_0 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.3.0/Compatibility_fallback_handler' -import { Compatibility_fallback_handler as CompatibilityFallbackHandler_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.4.1/Compatibility_fallback_handler' -import { CompatibilityFallbackHandlerContract } from '@safe-global/safe-core-sdk-types' - -abstract class CompatibilityFallbackHandlerWeb3Contract - implements CompatibilityFallbackHandlerContract -{ - constructor( - public contract: CompatibilityFallbackHandler_V1_4_1 | CompatibilityFallbackHandler_V1_3_0 - ) {} - - getAddress(): Promise { - return Promise.resolve(this.contract.options.address) - } - - encode(methodName: string, params: any[]): string { - return (this.contract as any).methods[methodName](...params).encodeABI() - } -} - -export default CompatibilityFallbackHandlerWeb3Contract diff --git a/packages/protocol-kit/src/adapters/web3/contracts/CompatibilityFallbackHandler/v1.3.0/CompatibilityFallbackHandler_V1_3_0_Web3.ts b/packages/protocol-kit/src/adapters/web3/contracts/CompatibilityFallbackHandler/v1.3.0/CompatibilityFallbackHandler_V1_3_0_Web3.ts deleted file mode 100644 index 3d179d43a..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/CompatibilityFallbackHandler/v1.3.0/CompatibilityFallbackHandler_V1_3_0_Web3.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Compatibility_fallback_handler as CompatibilityFallbackHandler } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.3.0/Compatibility_fallback_handler' -import CompatibilityFallbackHandlerWeb3Contract from '../CompatibilityFallbackHandlerWeb3Contract' - -class CompatibilityFallbackHandler_V1_3_0_Web3 extends CompatibilityFallbackHandlerWeb3Contract { - constructor(public contract: CompatibilityFallbackHandler) { - super(contract) - } -} - -export default CompatibilityFallbackHandler_V1_3_0_Web3 diff --git a/packages/protocol-kit/src/adapters/web3/contracts/CompatibilityFallbackHandler/v1.4.1/CompatibilityFallbackHandler_V1_4_1_Web3.ts b/packages/protocol-kit/src/adapters/web3/contracts/CompatibilityFallbackHandler/v1.4.1/CompatibilityFallbackHandler_V1_4_1_Web3.ts deleted file mode 100644 index 0670913ab..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/CompatibilityFallbackHandler/v1.4.1/CompatibilityFallbackHandler_V1_4_1_Web3.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Compatibility_fallback_handler as CompatibilityFallbackHandler } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.4.1/Compatibility_fallback_handler' -import CompatibilityFallbackHandlerWeb3Contract from '../CompatibilityFallbackHandlerWeb3Contract' - -class CompatibilityFallbackHandler_V1_4_1_Web3 extends CompatibilityFallbackHandlerWeb3Contract { - constructor(public contract: CompatibilityFallbackHandler) { - super(contract) - } -} - -export default CompatibilityFallbackHandler_V1_4_1_Web3 diff --git a/packages/protocol-kit/src/adapters/web3/contracts/CreateCall/CreateCallWeb3Contract.ts b/packages/protocol-kit/src/adapters/web3/contracts/CreateCall/CreateCallWeb3Contract.ts deleted file mode 100644 index 54adbf12e..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/CreateCall/CreateCallWeb3Contract.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { - Web3TransactionOptions, - Web3TransactionResult -} from '@safe-global/protocol-kit/adapters/web3/types' -import { toTxResult } from '@safe-global/protocol-kit/adapters/web3/utils' -import { Create_call as CreateCall_V1_3_0 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.3.0/Create_call' -import { Create_call as CreateCall_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.4.1/Create_call' -import { CreateCallContract } from '@safe-global/safe-core-sdk-types' - -abstract class CreateCallWeb3Contract implements CreateCallContract { - constructor(public contract: CreateCall_V1_4_1 | CreateCall_V1_3_0) {} - - getAddress(): Promise { - return Promise.resolve(this.contract.options.address) - } - - async performCreate2( - value: string, - deploymentData: string, - salt: string, - options?: Web3TransactionOptions - ): Promise { - if (options && !options.gas) { - options.gas = await this.estimateGas('performCreate2', [value, deploymentData, salt], { - ...options - }) - } - const txResponse = this.contract.methods - .performCreate2(value, deploymentData, salt) - .send(options) - return toTxResult(txResponse, options) - } - - async performCreate( - value: string, - deploymentData: string, - options?: Web3TransactionOptions - ): Promise { - if (options && !options.gas) { - options.gas = await this.estimateGas('performCreate', [value, deploymentData], { ...options }) - } - const txResponse = this.contract.methods.performCreate(value, deploymentData).send(options) - return toTxResult(txResponse, options) - } - - encode(methodName: string, params: any[]): string { - return (this.contract as any).methods[methodName](...params).encodeABI() - } - - async estimateGas( - methodName: string, - params: any[], - options: Web3TransactionOptions - ): Promise { - return ( - await (this.contract.methods as any)[methodName](...params).estimateGas(options) - ).toString() - } -} - -export default CreateCallWeb3Contract diff --git a/packages/protocol-kit/src/adapters/web3/contracts/CreateCall/v1.3.0/CreateCallEthersContract_V1_3_0_Web3.ts b/packages/protocol-kit/src/adapters/web3/contracts/CreateCall/v1.3.0/CreateCallEthersContract_V1_3_0_Web3.ts deleted file mode 100644 index c5a3fce5e..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/CreateCall/v1.3.0/CreateCallEthersContract_V1_3_0_Web3.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Create_call as CreateCall } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.3.0/Create_call' -import CreateCallWeb3Contract from '../CreateCallWeb3Contract' - -class CreateCallContract_V1_3_0_Web3 extends CreateCallWeb3Contract { - constructor(public contract: CreateCall) { - super(contract) - } -} - -export default CreateCallContract_V1_3_0_Web3 diff --git a/packages/protocol-kit/src/adapters/web3/contracts/CreateCall/v1.4.1/CreateCallEthersContract_V1_4_1_Web3.ts b/packages/protocol-kit/src/adapters/web3/contracts/CreateCall/v1.4.1/CreateCallEthersContract_V1_4_1_Web3.ts deleted file mode 100644 index 78032edb1..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/CreateCall/v1.4.1/CreateCallEthersContract_V1_4_1_Web3.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Create_call as CreateCall } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.4.1/Create_call' -import CreateCallWeb3Contract from '../CreateCallWeb3Contract' - -class CreateCallContract_V1_4_1_Web3 extends CreateCallWeb3Contract { - constructor(public contract: CreateCall) { - super(contract) - } -} - -export default CreateCallContract_V1_4_1_Web3 diff --git a/packages/protocol-kit/src/adapters/web3/contracts/MultiSend/MultiSendWeb3Contract.ts b/packages/protocol-kit/src/adapters/web3/contracts/MultiSend/MultiSendWeb3Contract.ts deleted file mode 100644 index 5f8473fb3..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/MultiSend/MultiSendWeb3Contract.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Multi_send as MultiSend_V1_1_1 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.1.1/Multi_send' -import { Multi_send as MultiSend_V1_3_0 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.3.0/Multi_send' -import { Multi_send as MultiSend_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.4.1/Multi_send' -import { MultiSendContract } from '@safe-global/safe-core-sdk-types' - -abstract class MultiSendWeb3Contract implements MultiSendContract { - constructor(public contract: MultiSend_V1_4_1 | MultiSend_V1_3_0 | MultiSend_V1_1_1) {} - - getAddress(): Promise { - return Promise.resolve(this.contract.options.address) - } - - encode(methodName: string, params: any[]): string { - return (this.contract as any).methods[methodName](...params).encodeABI() - } -} - -export default MultiSendWeb3Contract diff --git a/packages/protocol-kit/src/adapters/web3/contracts/MultiSend/v1.1.1/MultiSendContract_V1_1_1_Web3.ts b/packages/protocol-kit/src/adapters/web3/contracts/MultiSend/v1.1.1/MultiSendContract_V1_1_1_Web3.ts deleted file mode 100644 index f12451e6c..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/MultiSend/v1.1.1/MultiSendContract_V1_1_1_Web3.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Multi_send as MultiSend } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.1.1/Multi_send' -import MultiSendWeb3Contract from '../MultiSendWeb3Contract' - -class MultiSendContract_V1_1_1_Web3 extends MultiSendWeb3Contract { - constructor(public contract: MultiSend) { - super(contract) - } -} - -export default MultiSendContract_V1_1_1_Web3 diff --git a/packages/protocol-kit/src/adapters/web3/contracts/MultiSend/v1.3.0/MultiSendContract_V1_3_0_Web3.ts b/packages/protocol-kit/src/adapters/web3/contracts/MultiSend/v1.3.0/MultiSendContract_V1_3_0_Web3.ts deleted file mode 100644 index 305c97703..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/MultiSend/v1.3.0/MultiSendContract_V1_3_0_Web3.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Multi_send as MultiSend } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.3.0/Multi_send' -import MultiSendWeb3Contract from '../MultiSendWeb3Contract' - -class MultiSendContract_V1_3_0_Web3 extends MultiSendWeb3Contract { - constructor(public contract: MultiSend) { - super(contract) - } -} - -export default MultiSendContract_V1_3_0_Web3 diff --git a/packages/protocol-kit/src/adapters/web3/contracts/MultiSend/v1.4.1/MultiSendContract_V1_4_1_Web3.ts b/packages/protocol-kit/src/adapters/web3/contracts/MultiSend/v1.4.1/MultiSendContract_V1_4_1_Web3.ts deleted file mode 100644 index 510dfbd25..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/MultiSend/v1.4.1/MultiSendContract_V1_4_1_Web3.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Multi_send as MultiSend } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.4.1/Multi_send' -import MultiSendWeb3Contract from '../MultiSendWeb3Contract' - -class MultiSendContract_V1_4_1_Web3 extends MultiSendWeb3Contract { - constructor(public contract: MultiSend) { - super(contract) - } -} - -export default MultiSendContract_V1_4_1_Web3 diff --git a/packages/protocol-kit/src/adapters/web3/contracts/MultiSendCallOnly/MultiSendCallOnlyWeb3Contract.ts b/packages/protocol-kit/src/adapters/web3/contracts/MultiSendCallOnly/MultiSendCallOnlyWeb3Contract.ts deleted file mode 100644 index 7b8e5fa8f..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/MultiSendCallOnly/MultiSendCallOnlyWeb3Contract.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Multi_send_call_only as MultiSendCallOnly_V1_3_0 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.3.0/Multi_send_call_only' -import { Multi_send_call_only as MultiSendCallOnly_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.4.1/Multi_send_call_only' -import { MultiSendCallOnlyContract } from '@safe-global/safe-core-sdk-types' - -abstract class MultiSendCallOnlyWeb3Contract implements MultiSendCallOnlyContract { - constructor(public contract: MultiSendCallOnly_V1_4_1 | MultiSendCallOnly_V1_3_0) {} - - getAddress(): Promise { - return Promise.resolve(this.contract.options.address) - } - - encode(methodName: string, params: any[]): string { - return (this.contract as any).methods[methodName](...params).encodeABI() - } -} - -export default MultiSendCallOnlyWeb3Contract diff --git a/packages/protocol-kit/src/adapters/web3/contracts/MultiSendCallOnly/v1.3.0/MultiSendCallOnlyContract_V1_3_0_Web3.ts b/packages/protocol-kit/src/adapters/web3/contracts/MultiSendCallOnly/v1.3.0/MultiSendCallOnlyContract_V1_3_0_Web3.ts deleted file mode 100644 index 01c66bc1e..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/MultiSendCallOnly/v1.3.0/MultiSendCallOnlyContract_V1_3_0_Web3.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Multi_send_call_only as MultiSendCallOnly } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.3.0/Multi_send_call_only' -import MultiSendCallOnlyWeb3Contract from '../MultiSendCallOnlyWeb3Contract' - -class MultiSendCallOnlyContract_V1_3_0_Web3 extends MultiSendCallOnlyWeb3Contract { - constructor(public contract: MultiSendCallOnly) { - super(contract) - } -} - -export default MultiSendCallOnlyContract_V1_3_0_Web3 diff --git a/packages/protocol-kit/src/adapters/web3/contracts/MultiSendCallOnly/v1.4.1/MultiSendCallOnlyContract_V1_4_1_Web3.ts b/packages/protocol-kit/src/adapters/web3/contracts/MultiSendCallOnly/v1.4.1/MultiSendCallOnlyContract_V1_4_1_Web3.ts deleted file mode 100644 index b60d53f2d..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/MultiSendCallOnly/v1.4.1/MultiSendCallOnlyContract_V1_4_1_Web3.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Multi_send_call_only as MultiSendCallOnly } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.4.1/Multi_send_call_only' -import MultiSendCallOnlyWeb3Contract from '../MultiSendCallOnlyWeb3Contract' - -class MultiSendCallOnlyContract_V1_4_1_Web3 extends MultiSendCallOnlyWeb3Contract { - constructor(public contract: MultiSendCallOnly) { - super(contract) - } -} - -export default MultiSendCallOnlyContract_V1_4_1_Web3 diff --git a/packages/protocol-kit/src/adapters/web3/contracts/Safe/SafeContractWeb3.ts b/packages/protocol-kit/src/adapters/web3/contracts/Safe/SafeContractWeb3.ts deleted file mode 100644 index 8d7a56140..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/Safe/SafeContractWeb3.ts +++ /dev/null @@ -1,192 +0,0 @@ -import { - Web3TransactionOptions, - Web3TransactionResult -} from '@safe-global/protocol-kit/adapters/web3/types' -import { toTxResult } from '@safe-global/protocol-kit/adapters/web3/utils' -import { Gnosis_safe as Safe_V1_0_0 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.0.0/Gnosis_safe' -import { Gnosis_safe as Safe_V1_1_1 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.1.1/Gnosis_safe' -import { Gnosis_safe as Safe_V1_2_0 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.2.0/Gnosis_safe' -import { Gnosis_safe as Safe_V1_3_0 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.3.0/Gnosis_safe' -import { Safe as Safe_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.4.1/Safe' -import { - SafeContract, - SafeSetupConfig, - SafeTransaction, - SafeTransactionData, - SafeVersion -} from '@safe-global/safe-core-sdk-types' - -abstract class SafeContractWeb3 implements SafeContract { - constructor( - public contract: Safe_V1_4_1 | Safe_V1_3_0 | Safe_V1_2_0 | Safe_V1_1_1 | Safe_V1_0_0 - ) {} - - abstract setup( - setupConfig: SafeSetupConfig, - options?: Web3TransactionOptions - ): Promise - - async getVersion(): Promise { - return (await this.contract.methods.VERSION().call()) as SafeVersion - } - - getAddress(): Promise { - return Promise.resolve(this.contract.options.address) - } - - async getNonce(): Promise { - return Number(await this.contract.methods.nonce().call()) - } - - async getThreshold(): Promise { - return Number(await this.contract.methods.getThreshold().call()) - } - - async getOwners(): Promise { - return this.contract.methods.getOwners().call() - } - - async isOwner(address: string): Promise { - return this.contract.methods.isOwner(address).call() - } - - async getTransactionHash(safeTransactionData: SafeTransactionData): Promise { - return this.contract.methods - .getTransactionHash( - safeTransactionData.to, - safeTransactionData.value, - safeTransactionData.data, - safeTransactionData.operation, - safeTransactionData.safeTxGas, - safeTransactionData.baseGas, - safeTransactionData.gasPrice, - safeTransactionData.gasToken, - safeTransactionData.refundReceiver, - safeTransactionData.nonce - ) - .call() - } - - async approvedHashes(ownerAddress: string, hash: string): Promise { - return BigInt(await this.contract.methods.approvedHashes(ownerAddress, hash).call()) - } - - async approveHash( - hash: string, - options?: Web3TransactionOptions - ): Promise { - if (options && !options.gas) { - options.gas = await this.estimateGas('approveHash', [hash], { ...options }) - } - const txResponse = this.contract.methods.approveHash(hash).send(options) - return toTxResult(txResponse, options) - } - - abstract getModules(): Promise - - abstract getModulesPaginated(start: string, pageSize: number): Promise - - abstract isModuleEnabled(moduleAddress: string): Promise - - async isValidTransaction( - safeTransaction: SafeTransaction, - options?: Web3TransactionOptions - ): Promise { - let isTxValid = false - try { - if (options && !options.gas) { - options.gas = await this.estimateGas( - 'execTransaction', - [ - safeTransaction.data.to, - safeTransaction.data.value, - safeTransaction.data.data, - safeTransaction.data.operation, - safeTransaction.data.safeTxGas, - safeTransaction.data.baseGas, - safeTransaction.data.gasPrice, - safeTransaction.data.gasToken, - safeTransaction.data.refundReceiver, - safeTransaction.encodedSignatures() - ], - { - ...options - } - ) - } - isTxValid = await this.contract.methods - .execTransaction( - safeTransaction.data.to, - safeTransaction.data.value, - safeTransaction.data.data, - safeTransaction.data.operation, - safeTransaction.data.safeTxGas, - safeTransaction.data.baseGas, - safeTransaction.data.gasPrice, - safeTransaction.data.gasToken, - safeTransaction.data.refundReceiver, - safeTransaction.encodedSignatures() - ) - .call(options) - } catch {} - return isTxValid - } - - async execTransaction( - safeTransaction: SafeTransaction, - options?: Web3TransactionOptions - ): Promise { - if (options && !options.gas) { - options.gas = await this.estimateGas( - 'execTransaction', - [ - safeTransaction.data.to, - safeTransaction.data.value, - safeTransaction.data.data, - safeTransaction.data.operation, - safeTransaction.data.safeTxGas, - safeTransaction.data.baseGas, - safeTransaction.data.gasPrice, - safeTransaction.data.gasToken, - safeTransaction.data.refundReceiver, - safeTransaction.encodedSignatures() - ], - { - ...options - } - ) - } - const txResponse = this.contract.methods - .execTransaction( - safeTransaction.data.to, - safeTransaction.data.value, - safeTransaction.data.data, - safeTransaction.data.operation, - safeTransaction.data.safeTxGas, - safeTransaction.data.baseGas, - safeTransaction.data.gasPrice, - safeTransaction.data.gasToken, - safeTransaction.data.refundReceiver, - safeTransaction.encodedSignatures() - ) - .send(options) - - return toTxResult(txResponse, options) - } - - encode(methodName: string, params: any[]): string { - return (this.contract.methods as any)[methodName](...params).encodeABI() - } - - async estimateGas( - methodName: string, - params: any[], - options: Web3TransactionOptions - ): Promise { - return ( - await (this.contract.methods as any)[methodName](...params).estimateGas(options) - ).toString() - } -} - -export default SafeContractWeb3 diff --git a/packages/protocol-kit/src/adapters/web3/contracts/Safe/v1.0.0/SafeContract_V1_0_0_Web3.ts b/packages/protocol-kit/src/adapters/web3/contracts/Safe/v1.0.0/SafeContract_V1_0_0_Web3.ts deleted file mode 100644 index 9265d3258..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/Safe/v1.0.0/SafeContract_V1_0_0_Web3.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { - Web3TransactionOptions, - Web3TransactionResult -} from '@safe-global/protocol-kit/adapters/web3/types' -import { sameString, toTxResult } from '@safe-global/protocol-kit/adapters/web3/utils' -import { - EMPTY_DATA, - ZERO_ADDRESS, - SENTINEL_ADDRESS -} from '@safe-global/protocol-kit/adapters/web3/utils/constants' -import { Gnosis_safe as Safe } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.0.0/Gnosis_safe' -import { SafeSetupConfig } from '@safe-global/safe-core-sdk-types' -import SafeContractWeb3 from '../SafeContractWeb3' - -class SafeContract_V1_0_0_Web3 extends SafeContractWeb3 { - constructor(public contract: Safe) { - super(contract) - } - - async setup( - setupConfig: SafeSetupConfig, - options?: Web3TransactionOptions - ): Promise { - const { - owners, - threshold, - to = ZERO_ADDRESS, - data = EMPTY_DATA, - paymentToken = ZERO_ADDRESS, - payment = 0, - paymentReceiver = ZERO_ADDRESS - } = setupConfig - - if (options && !options.gas) { - options.gas = await this.estimateGas( - 'setup', - [owners, threshold, to, data, paymentToken, payment, paymentReceiver], - { - ...options - } - ) - } - const txResponse = this.contract.methods - .setup(owners, threshold, to, data, paymentToken, payment, paymentReceiver) - .send(options) - - return toTxResult(txResponse, options) - } - - async getModules(): Promise { - return this.contract.methods.getModules().call() - } - - async getModulesPaginated(start: string, pageSize: number): Promise { - if (pageSize <= 0) throw new Error('Invalid page size for fetching paginated modules') - - const array = await this.getModules() - if (start === SENTINEL_ADDRESS) { - return array.slice(0, pageSize) - } else { - const moduleIndex = array.findIndex((module: string) => sameString(module, start)) - return moduleIndex === -1 ? [] : array.slice(moduleIndex + 1, pageSize) - } - } - - async isModuleEnabled(moduleAddress: string): Promise { - const modules = await this.getModules() - const isModuleEnabled = modules.some((enabledModuleAddress: string) => - sameString(enabledModuleAddress, moduleAddress) - ) - return isModuleEnabled - } -} - -export default SafeContract_V1_0_0_Web3 diff --git a/packages/protocol-kit/src/adapters/web3/contracts/Safe/v1.1.1/SafeContract_V1_1_1_Web3.ts b/packages/protocol-kit/src/adapters/web3/contracts/Safe/v1.1.1/SafeContract_V1_1_1_Web3.ts deleted file mode 100644 index f957f21a1..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/Safe/v1.1.1/SafeContract_V1_1_1_Web3.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { - Web3TransactionOptions, - Web3TransactionResult -} from '@safe-global/protocol-kit/adapters/web3/types' -import { sameString, toTxResult } from '@safe-global/protocol-kit/adapters/web3/utils' -import { EMPTY_DATA, ZERO_ADDRESS } from '@safe-global/protocol-kit/adapters/web3/utils/constants' -import { Gnosis_safe as Safe } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.1.1/Gnosis_safe' -import { SafeSetupConfig } from '@safe-global/safe-core-sdk-types' -import SafeContractWeb3 from '../SafeContractWeb3' - -class SafeContract_V1_1_1_Web3 extends SafeContractWeb3 { - constructor(public contract: Safe) { - super(contract) - } - - async setup( - setupConfig: SafeSetupConfig, - options?: Web3TransactionOptions - ): Promise { - const { - owners, - threshold, - to = ZERO_ADDRESS, - data = EMPTY_DATA, - fallbackHandler = ZERO_ADDRESS, - paymentToken = ZERO_ADDRESS, - payment = 0, - paymentReceiver = ZERO_ADDRESS - } = setupConfig - - if (options && !options.gas) { - options.gas = await this.estimateGas( - 'setup', - [owners, threshold, to, data, fallbackHandler, paymentToken, payment, paymentReceiver], - { - ...options - } - ) - } - const txResponse = this.contract.methods - .setup(owners, threshold, to, data, fallbackHandler, paymentToken, payment, paymentReceiver) - .send(options) - - return toTxResult(txResponse, options) - } - - async getModules(): Promise { - return this.contract.methods.getModules().call() - } - - async getModulesPaginated(start: string, pageSize: number): Promise { - const { array } = await this.contract.methods.getModulesPaginated(start, pageSize).call() - return array - } - - async isModuleEnabled(moduleAddress: string): Promise { - const modules = await this.getModules() - const isModuleEnabled = modules.some((enabledModuleAddress: string) => - sameString(enabledModuleAddress, moduleAddress) - ) - return isModuleEnabled - } -} - -export default SafeContract_V1_1_1_Web3 diff --git a/packages/protocol-kit/src/adapters/web3/contracts/Safe/v1.2.0/SafeContract_V1_2_0_Web3.ts b/packages/protocol-kit/src/adapters/web3/contracts/Safe/v1.2.0/SafeContract_V1_2_0_Web3.ts deleted file mode 100644 index 1cc9bb831..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/Safe/v1.2.0/SafeContract_V1_2_0_Web3.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { - Web3TransactionOptions, - Web3TransactionResult -} from '@safe-global/protocol-kit/adapters/web3/types' -import { toTxResult } from '@safe-global/protocol-kit/adapters/web3/utils' -import { EMPTY_DATA, ZERO_ADDRESS } from '@safe-global/protocol-kit/adapters/web3/utils/constants' -import { Gnosis_safe as Safe } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.2.0/Gnosis_safe' -import { SafeSetupConfig } from '@safe-global/safe-core-sdk-types' -import SafeContractWeb3 from '../SafeContractWeb3' - -class SafeContract_V1_2_0_Web3 extends SafeContractWeb3 { - constructor(public contract: Safe) { - super(contract) - } - - async setup( - setupConfig: SafeSetupConfig, - options?: Web3TransactionOptions - ): Promise { - const { - owners, - threshold, - to = ZERO_ADDRESS, - data = EMPTY_DATA, - fallbackHandler = ZERO_ADDRESS, - paymentToken = ZERO_ADDRESS, - payment = 0, - paymentReceiver = ZERO_ADDRESS - } = setupConfig - - if (options && !options.gas) { - options.gas = await this.estimateGas( - 'setup', - [owners, threshold, to, data, fallbackHandler, paymentToken, payment, paymentReceiver], - { - ...options - } - ) - } - const txResponse = this.contract.methods - .setup(owners, threshold, to, data, fallbackHandler, paymentToken, payment, paymentReceiver) - .send(options) - - return toTxResult(txResponse, options) - } - - async getModules(): Promise { - return this.contract.methods.getModules().call() - } - - async getModulesPaginated(start: string, pageSize: number): Promise { - const { array } = await this.contract.methods.getModulesPaginated(start, pageSize).call() - return array - } - - async isModuleEnabled(moduleAddress: string): Promise { - return this.contract.methods.isModuleEnabled(moduleAddress).call() - } -} - -export default SafeContract_V1_2_0_Web3 diff --git a/packages/protocol-kit/src/adapters/web3/contracts/Safe/v1.3.0/SafeContract_V1_3_0_Web3.ts b/packages/protocol-kit/src/adapters/web3/contracts/Safe/v1.3.0/SafeContract_V1_3_0_Web3.ts deleted file mode 100644 index 62f13e45e..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/Safe/v1.3.0/SafeContract_V1_3_0_Web3.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { - Web3TransactionOptions, - Web3TransactionResult -} from '@safe-global/protocol-kit/adapters/web3/types' -import { toTxResult } from '@safe-global/protocol-kit/adapters/web3/utils' -import { - EMPTY_DATA, - SENTINEL_ADDRESS, - ZERO_ADDRESS -} from '@safe-global/protocol-kit/adapters/web3/utils/constants' -import { Gnosis_safe as Safe } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.3.0/Gnosis_safe' -import { SafeSetupConfig } from '@safe-global/safe-core-sdk-types' -import SafeContractWeb3 from '../SafeContractWeb3' - -class SafeContract_V1_3_0_Web3 extends SafeContractWeb3 { - constructor(public contract: Safe) { - super(contract) - } - - async setup( - setupConfig: SafeSetupConfig, - options?: Web3TransactionOptions - ): Promise { - const { - owners, - threshold, - to = ZERO_ADDRESS, - data = EMPTY_DATA, - fallbackHandler = ZERO_ADDRESS, - paymentToken = ZERO_ADDRESS, - payment = 0, - paymentReceiver = ZERO_ADDRESS - } = setupConfig - - if (options && !options.gas) { - options.gas = await this.estimateGas( - 'setup', - [owners, threshold, to, data, fallbackHandler, paymentToken, payment, paymentReceiver], - { - ...options - } - ) - } - const txResponse = this.contract.methods - .setup(owners, threshold, to, data, fallbackHandler, paymentToken, payment, paymentReceiver) - .send(options) - - return toTxResult(txResponse, options) - } - - async getModules(): Promise { - return await this.getModulesPaginated(SENTINEL_ADDRESS, 10) - } - - async getModulesPaginated(start: string, pageSize: number): Promise { - const { array } = await this.contract.methods.getModulesPaginated(start, pageSize).call() - return array - } - - async isModuleEnabled(moduleAddress: string): Promise { - return this.contract.methods.isModuleEnabled(moduleAddress).call() - } -} - -export default SafeContract_V1_3_0_Web3 diff --git a/packages/protocol-kit/src/adapters/web3/contracts/Safe/v1.4.1/SafeContract_V1_4_1_Web3.ts b/packages/protocol-kit/src/adapters/web3/contracts/Safe/v1.4.1/SafeContract_V1_4_1_Web3.ts deleted file mode 100644 index 7751e9394..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/Safe/v1.4.1/SafeContract_V1_4_1_Web3.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { - Web3TransactionOptions, - Web3TransactionResult -} from '@safe-global/protocol-kit/adapters/web3/types' -import { toTxResult } from '@safe-global/protocol-kit/adapters/web3/utils' -import { - EMPTY_DATA, - SENTINEL_ADDRESS, - ZERO_ADDRESS -} from '@safe-global/protocol-kit/adapters/web3/utils/constants' -import { Safe } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.4.1/Safe' -import { SafeSetupConfig } from '@safe-global/safe-core-sdk-types' -import SafeContractWeb3 from '../SafeContractWeb3' - -class SafeContract_V1_4_1_Web3 extends SafeContractWeb3 { - constructor(public contract: Safe) { - super(contract) - } - - async setup( - setupConfig: SafeSetupConfig, - options?: Web3TransactionOptions - ): Promise { - const { - owners, - threshold, - to = ZERO_ADDRESS, - data = EMPTY_DATA, - fallbackHandler = ZERO_ADDRESS, - paymentToken = ZERO_ADDRESS, - payment = 0, - paymentReceiver = ZERO_ADDRESS - } = setupConfig - - if (options && !options.gas) { - options.gas = await this.estimateGas( - 'setup', - [owners, threshold, to, data, fallbackHandler, paymentToken, payment, paymentReceiver], - { - ...options - } - ) - } - const txResponse = this.contract.methods - .setup(owners, threshold, to, data, fallbackHandler, paymentToken, payment, paymentReceiver) - .send(options) - - return toTxResult(txResponse, options) - } - - async getModules(): Promise { - return await this.getModulesPaginated(SENTINEL_ADDRESS, 10) - } - - async getModulesPaginated(start: string, pageSize: number): Promise { - const { array } = await this.contract.methods.getModulesPaginated(start, pageSize).call() - return array - } - - async isModuleEnabled(moduleAddress: string): Promise { - return this.contract.methods.isModuleEnabled(moduleAddress).call() - } -} - -export default SafeContract_V1_4_1_Web3 diff --git a/packages/protocol-kit/src/adapters/web3/contracts/SafeProxyFactory/SafeProxyFactoryWeb3Contract.ts b/packages/protocol-kit/src/adapters/web3/contracts/SafeProxyFactory/SafeProxyFactoryWeb3Contract.ts deleted file mode 100644 index c0ab63576..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/SafeProxyFactory/SafeProxyFactoryWeb3Contract.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { Web3TransactionOptions } from '@safe-global/protocol-kit/adapters/web3/types' -import { toTxResult } from '@safe-global/protocol-kit/adapters/web3/utils' -import { Proxy_factory as SafeProxyFactory_V1_0_0 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.0.0/Proxy_factory' -import { Proxy_factory as SafeProxyFactory_V1_1_1 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.1.1/Proxy_factory' -import { Proxy_factory as SafeProxyFactory_V1_3_0 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.3.0/Proxy_factory' -import { Safe_proxy_factory as SafeProxyFactory_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.4.1/Safe_proxy_factory' -import { SafeProxyFactoryContract } from '@safe-global/safe-core-sdk-types' -import { TransactionReceipt } from 'web3-core/types' - -export interface CreateProxyProps { - safeSingletonAddress: string - initializer: string - saltNonce: string - options?: Web3TransactionOptions - callback?: (txHash: string) => void -} - -class SafeProxyFactoryWeb3Contract implements SafeProxyFactoryContract { - constructor( - public contract: - | SafeProxyFactory_V1_4_1 - | SafeProxyFactory_V1_3_0 - | SafeProxyFactory_V1_1_1 - | SafeProxyFactory_V1_0_0 - ) {} - - getAddress(): Promise { - return Promise.resolve(this.contract.options.address) - } - - async proxyCreationCode(): Promise { - return this.contract.methods.proxyCreationCode().call() - } - - async createProxy({ - safeSingletonAddress, - initializer, - saltNonce, - options, - callback - }: CreateProxyProps): Promise { - if (BigInt(saltNonce) < 0) throw new Error('saltNonce must be greater than or equal to 0') - if (options && !options.gas) { - options.gas = await this.estimateGas( - 'createProxyWithNonce', - [safeSingletonAddress, initializer, saltNonce], - { - ...options - } - ) - } - const txResponse = this.contract.methods - .createProxyWithNonce(safeSingletonAddress, initializer, saltNonce) - .send(options) - - if (callback) { - const txResult = await toTxResult(txResponse) - callback(txResult.hash) - } - - const txResult: TransactionReceipt = await new Promise((resolve, reject) => - txResponse.once('receipt', (receipt: TransactionReceipt) => resolve(receipt)).catch(reject) - ) - const proxyAddress = txResult.events?.ProxyCreation?.returnValues?.proxy - if (!proxyAddress) { - throw new Error('SafeProxy was not deployed correctly') - } - return proxyAddress - } - - encode(methodName: string, params: any[]): string { - return (this.contract as any).methods[methodName](...params).encodeABI() - } - - async estimateGas( - methodName: string, - params: any[], - options: Web3TransactionOptions - ): Promise { - return ( - await (this.contract.methods as any)[methodName](...params).estimateGas(options) - ).toString() - } -} - -export default SafeProxyFactoryWeb3Contract diff --git a/packages/protocol-kit/src/adapters/web3/contracts/SafeProxyFactory/v1.0.0/SafeProxyFactoryContract_V1_0_0_Web3.ts b/packages/protocol-kit/src/adapters/web3/contracts/SafeProxyFactory/v1.0.0/SafeProxyFactoryContract_V1_0_0_Web3.ts deleted file mode 100644 index 6e315f5d6..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/SafeProxyFactory/v1.0.0/SafeProxyFactoryContract_V1_0_0_Web3.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Proxy_factory as ProxyFactory } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.0.0/Proxy_factory' -import SafeProxyFactoryWeb3Contract from '../SafeProxyFactoryWeb3Contract' - -class SafeProxyFactoryContract_V1_0_0_Web3 extends SafeProxyFactoryWeb3Contract { - constructor(public contract: ProxyFactory) { - super(contract) - } -} - -export default SafeProxyFactoryContract_V1_0_0_Web3 diff --git a/packages/protocol-kit/src/adapters/web3/contracts/SafeProxyFactory/v1.1.1/SafeProxyFactoryContract_V1_1_1_Web3.ts b/packages/protocol-kit/src/adapters/web3/contracts/SafeProxyFactory/v1.1.1/SafeProxyFactoryContract_V1_1_1_Web3.ts deleted file mode 100644 index fd5414acc..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/SafeProxyFactory/v1.1.1/SafeProxyFactoryContract_V1_1_1_Web3.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Proxy_factory as ProxyFactory } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.1.1/Proxy_factory' -import SafeProxyFactoryWeb3Contract from '../SafeProxyFactoryWeb3Contract' - -class SafeProxyFactoryContract_V1_1_1_Web3 extends SafeProxyFactoryWeb3Contract { - constructor(public contract: ProxyFactory) { - super(contract) - } -} - -export default SafeProxyFactoryContract_V1_1_1_Web3 diff --git a/packages/protocol-kit/src/adapters/web3/contracts/SafeProxyFactory/v1.3.0/SafeProxyFactoryContract_V1_3_0_Web3.ts b/packages/protocol-kit/src/adapters/web3/contracts/SafeProxyFactory/v1.3.0/SafeProxyFactoryContract_V1_3_0_Web3.ts deleted file mode 100644 index 830457a44..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/SafeProxyFactory/v1.3.0/SafeProxyFactoryContract_V1_3_0_Web3.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Proxy_factory as ProxyFactory } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.3.0/Proxy_factory' -import SafeProxyFactoryWeb3Contract from '../SafeProxyFactoryWeb3Contract' - -class SafeProxyFactoryContract_V1_3_0_Web3 extends SafeProxyFactoryWeb3Contract { - constructor(public contract: ProxyFactory) { - super(contract) - } -} - -export default SafeProxyFactoryContract_V1_3_0_Web3 diff --git a/packages/protocol-kit/src/adapters/web3/contracts/SafeProxyFactory/v1.4.1/SafeProxyFactoryContract_V1_4_1_Web3.ts b/packages/protocol-kit/src/adapters/web3/contracts/SafeProxyFactory/v1.4.1/SafeProxyFactoryContract_V1_4_1_Web3.ts deleted file mode 100644 index ca079736e..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/SafeProxyFactory/v1.4.1/SafeProxyFactoryContract_V1_4_1_Web3.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Safe_proxy_factory as SafeProxyFactory } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.4.1/Safe_proxy_factory' -import SafeProxyFactoryWeb3Contract from '../SafeProxyFactoryWeb3Contract' - -class SafeProxyFactoryContract_V1_4_1_Web3 extends SafeProxyFactoryWeb3Contract { - constructor(public contract: SafeProxyFactory) { - super(contract) - } -} - -export default SafeProxyFactoryContract_V1_4_1_Web3 diff --git a/packages/protocol-kit/src/adapters/web3/contracts/SignMessageLib/SignMessageLibWeb3Contract.ts b/packages/protocol-kit/src/adapters/web3/contracts/SignMessageLib/SignMessageLibWeb3Contract.ts deleted file mode 100644 index bae8172e8..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/SignMessageLib/SignMessageLibWeb3Contract.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { - Web3TransactionOptions, - Web3TransactionResult -} from '@safe-global/protocol-kit/adapters/web3/types' -import { toTxResult } from '@safe-global/protocol-kit/adapters/web3/utils' -import { Sign_message_lib as SignMessageLib_V1_3_0 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.3.0/Sign_message_lib' -import { Sign_message_lib as SignMessageLib_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.4.1/Sign_message_lib' -import { SignMessageLibContract } from '@safe-global/safe-core-sdk-types' - -abstract class SignMessageLibWeb3Contract implements SignMessageLibContract { - constructor(public contract: SignMessageLib_V1_4_1 | SignMessageLib_V1_3_0) {} - - getAddress(): Promise { - return Promise.resolve(this.contract.options.address) - } - - async signMessage( - data: string, - options?: Web3TransactionOptions - ): Promise { - if (options && !options.gas) { - options.gas = await this.estimateGas('signMessage', [data], { ...options }) - } - const txResponse = this.contract.methods.signMessage(data).send(options) - return toTxResult(txResponse, options) - } - - async getMessageHash(message: string): Promise { - return this.contract.methods.getMessageHash(message).call() - } - - encode(methodName: string, params: any[]): string { - return (this.contract as any).methods[methodName](...params).encodeABI() - } - - async estimateGas( - methodName: string, - params: any[], - options: Web3TransactionOptions - ): Promise { - return ( - await (this.contract.methods as any)[methodName](...params).estimateGas(options) - ).toString() - } -} - -export default SignMessageLibWeb3Contract diff --git a/packages/protocol-kit/src/adapters/web3/contracts/SignMessageLib/v1.3.0/SignMessageLibContract_V1_3_0_Web3.ts b/packages/protocol-kit/src/adapters/web3/contracts/SignMessageLib/v1.3.0/SignMessageLibContract_V1_3_0_Web3.ts deleted file mode 100644 index cda2038e4..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/SignMessageLib/v1.3.0/SignMessageLibContract_V1_3_0_Web3.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Sign_message_lib as SignMessageLib } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.3.0/Sign_message_lib' -import SignMessageLibWeb3Contract from '../SignMessageLibWeb3Contract' - -class SignMessageLibContract_V1_3_0_Web3 extends SignMessageLibWeb3Contract { - constructor(public contract: SignMessageLib) { - super(contract) - } -} - -export default SignMessageLibContract_V1_3_0_Web3 diff --git a/packages/protocol-kit/src/adapters/web3/contracts/SignMessageLib/v1.4.1/SignMessageLibContract_V1_4_1_Web3.ts b/packages/protocol-kit/src/adapters/web3/contracts/SignMessageLib/v1.4.1/SignMessageLibContract_V1_4_1_Web3.ts deleted file mode 100644 index 6433d1ef9..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/SignMessageLib/v1.4.1/SignMessageLibContract_V1_4_1_Web3.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Sign_message_lib as SignMessageLib } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.4.1/Sign_message_lib' -import SignMessageLibWeb3Contract from '../SignMessageLibWeb3Contract' - -class SignMessageLibContract_V1_4_1_Web3 extends SignMessageLibWeb3Contract { - constructor(public contract: SignMessageLib) { - super(contract) - } -} - -export default SignMessageLibContract_V1_4_1_Web3 diff --git a/packages/protocol-kit/src/adapters/web3/contracts/SimulateTxAccessor/SimulateTxAccessorWeb3Contract.ts b/packages/protocol-kit/src/adapters/web3/contracts/SimulateTxAccessor/SimulateTxAccessorWeb3Contract.ts deleted file mode 100644 index 03f4f6f14..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/SimulateTxAccessor/SimulateTxAccessorWeb3Contract.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Simulate_tx_accessor as SimulateTxAccessor_V1_3_0 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.3.0/Simulate_tx_accessor' -import { Simulate_tx_accessor as SimulateTxAccessor_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.4.1/Simulate_tx_accessor' -import { SimulateTxAccessorContract } from '@safe-global/safe-core-sdk-types' - -abstract class SimulateTxAccessorWeb3Contract implements SimulateTxAccessorContract { - constructor(public contract: SimulateTxAccessor_V1_4_1 | SimulateTxAccessor_V1_3_0) {} - - getAddress(): Promise { - return Promise.resolve(this.contract.options.address) - } - - encode(methodName: string, params: any[]): string { - return (this.contract as any).methods[methodName](...params).encodeABI() - } -} - -export default SimulateTxAccessorWeb3Contract diff --git a/packages/protocol-kit/src/adapters/web3/contracts/SimulateTxAccessor/v1.3.0/SimulateTxAccessorContract_V1_3_0_Web3.ts b/packages/protocol-kit/src/adapters/web3/contracts/SimulateTxAccessor/v1.3.0/SimulateTxAccessorContract_V1_3_0_Web3.ts deleted file mode 100644 index ae1b294b1..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/SimulateTxAccessor/v1.3.0/SimulateTxAccessorContract_V1_3_0_Web3.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Simulate_tx_accessor as SimulateTxAccessor } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.3.0/Simulate_tx_accessor' -import SimulateTxAccessorWeb3Contract from '../SimulateTxAccessorWeb3Contract' - -class SimulateTxAccessor_V1_3_0_Web3 extends SimulateTxAccessorWeb3Contract { - constructor(public contract: SimulateTxAccessor) { - super(contract) - } -} - -export default SimulateTxAccessor_V1_3_0_Web3 diff --git a/packages/protocol-kit/src/adapters/web3/contracts/SimulateTxAccessor/v1.4.1/SimulateTxAccessorContract_V1_4_1_Web3.ts b/packages/protocol-kit/src/adapters/web3/contracts/SimulateTxAccessor/v1.4.1/SimulateTxAccessorContract_V1_4_1_Web3.ts deleted file mode 100644 index adfbf525a..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/SimulateTxAccessor/v1.4.1/SimulateTxAccessorContract_V1_4_1_Web3.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Simulate_tx_accessor as SimulateTxAccessor } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.4.1/Simulate_tx_accessor' -import SimulateTxAccessorWeb3Contract from '../SimulateTxAccessorWeb3Contract' - -class SimulateTxAccessor_V1_4_1_Web3 extends SimulateTxAccessorWeb3Contract { - constructor(public contract: SimulateTxAccessor) { - super(contract) - } -} - -export default SimulateTxAccessor_V1_4_1_Web3 diff --git a/packages/protocol-kit/src/adapters/web3/contracts/contractInstancesWeb3.ts b/packages/protocol-kit/src/adapters/web3/contracts/contractInstancesWeb3.ts deleted file mode 100644 index 6378370f2..000000000 --- a/packages/protocol-kit/src/adapters/web3/contracts/contractInstancesWeb3.ts +++ /dev/null @@ -1,220 +0,0 @@ -import { Gnosis_safe as SafeSingleton_V1_0_0 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.0.0/Gnosis_safe' -import { Proxy_factory as SafeProxyFactory_V1_0_0 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.0.0/Proxy_factory' -import { Gnosis_safe as SafeSingleton_V1_1_1 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.1.1/Gnosis_safe' -import { Multi_send as MultiSend_V1_1_1 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.1.1/Multi_send' -import { Proxy_factory as SafeProxyFactory_V1_1_1 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.1.1/Proxy_factory' -import { Gnosis_safe as SafeSingleton_V1_2_0 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.2.0/Gnosis_safe' -import { Compatibility_fallback_handler as CompatibilityFallbackHandler_V1_3_0 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.3.0/Compatibility_fallback_handler' -import { Create_call as CreateCall_V1_3_0 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.3.0/Create_call' -import { Gnosis_safe as SafeSingleton_V1_3_0 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.3.0/Gnosis_safe' -import { Multi_send as MultiSend_V1_3_0 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.3.0/Multi_send' -import { Multi_send_call_only as MultiSendCallOnly_V1_3_0 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.3.0/Multi_send_call_only' -import { Proxy_factory as SafeProxyFactory_V1_3_0 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.3.0/Proxy_factory' -import { Sign_message_lib as SignMessageLib_V1_3_0 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.3.0/Sign_message_lib' -import { Simulate_tx_accessor as SimulateTxAccessor_V1_3_0 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.3.0/Simulate_tx_accessor' -import { Compatibility_fallback_handler as CompatibilityFallbackHandler_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.4.1/Compatibility_fallback_handler' -import { Create_call as CreateCall_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.4.1/Create_call' -import { Multi_send as MultiSend_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.4.1/Multi_send' -import { Multi_send_call_only as MultiSendCallOnly_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.4.1/Multi_send_call_only' -import { Safe as SafeSingleton_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.4.1/Safe' -import { Safe_proxy_factory as SafeProxyFactory_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.4.1/Safe_proxy_factory' -import { Sign_message_lib as SignMessageLib_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.4.1/Sign_message_lib' -import { Simulate_tx_accessor as SimulateTxAccessor_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/web3-v1/v1.4.1/Simulate_tx_accessor' -import { SafeVersion } from '@safe-global/safe-core-sdk-types' -import CompatibilityFallbackHandler_V1_3_0_Web3 from './CompatibilityFallbackHandler/v1.3.0/CompatibilityFallbackHandler_V1_3_0_Web3' -import CompatibilityFallbackHandler_V1_4_1_Web3 from './CompatibilityFallbackHandler/v1.4.1/CompatibilityFallbackHandler_V1_4_1_Web3' -import CreateCallContract_V1_3_0_Web3 from './CreateCall/v1.3.0/CreateCallEthersContract_V1_3_0_Web3' -import CreateCallContract_V1_4_1_Web3 from './CreateCall/v1.4.1/CreateCallEthersContract_V1_4_1_Web3' -import MultiSendContract_V1_1_1_Web3 from './MultiSend/v1.1.1/MultiSendContract_V1_1_1_Web3' -import MultiSendContract_V1_3_0_Web3 from './MultiSend/v1.3.0/MultiSendContract_V1_3_0_Web3' -import MultiSendContract_V1_4_1_Web3 from './MultiSend/v1.4.1/MultiSendContract_V1_4_1_Web3' -import MultiSendCallOnlyContract_V1_3_0_Web3 from './MultiSendCallOnly/v1.3.0/MultiSendCallOnlyContract_V1_3_0_Web3' -import MultiSendCallOnlyContract_V1_4_1_Web3 from './MultiSendCallOnly/v1.4.1/MultiSendCallOnlyContract_V1_4_1_Web3' -import SafeContract_V1_0_0_Web3 from './Safe/v1.0.0/SafeContract_V1_0_0_Web3' -import SafeContract_V1_1_1_Web3 from './Safe/v1.1.1/SafeContract_V1_1_1_Web3' -import SafeContract_V1_2_0_Web3 from './Safe/v1.2.0/SafeContract_V1_2_0_Web3' -import SafeContract_V1_3_0_Web3 from './Safe/v1.3.0/SafeContract_V1_3_0_Web3' -import SafeContract_V1_4_1_Web3 from './Safe/v1.4.1/SafeContract_V1_4_1_Web3' -import SafeProxyFactoryContract_V1_0_0_Web3 from './SafeProxyFactory/v1.0.0/SafeProxyFactoryContract_V1_0_0_Web3' -import SafeProxyFactoryContract_V1_1_1_Web3 from './SafeProxyFactory/v1.1.1/SafeProxyFactoryContract_V1_1_1_Web3' -import SafeProxyFactoryContract_V1_3_0_Web3 from './SafeProxyFactory/v1.3.0/SafeProxyFactoryContract_V1_3_0_Web3' -import SafeProxyFactoryContract_V1_4_1_Web3 from './SafeProxyFactory/v1.4.1/SafeProxyFactoryContract_V1_4_1_Web3' -import SignMessageLibContract_V1_3_0_Web3 from './SignMessageLib/v1.3.0/SignMessageLibContract_V1_3_0_Web3' -import SignMessageLibContract_V1_4_1_Web3 from './SignMessageLib/v1.4.1/SignMessageLibContract_V1_4_1_Web3' -import SimulateTxAccessorContract_V1_3_0_Web3 from './SimulateTxAccessor/v1.3.0/SimulateTxAccessorContract_V1_3_0_Web3' -import SimulateTxAccessorContract_V1_4_1_Web3 from './SimulateTxAccessor/v1.4.1/SimulateTxAccessorContract_V1_4_1_Web3' - -export function getSafeContractInstance( - safeVersion: SafeVersion, - safeContract: - | SafeSingleton_V1_4_1 - | SafeSingleton_V1_3_0 - | SafeSingleton_V1_2_0 - | SafeSingleton_V1_1_1 - | SafeSingleton_V1_0_0 -): - | SafeContract_V1_4_1_Web3 - | SafeContract_V1_3_0_Web3 - | SafeContract_V1_2_0_Web3 - | SafeContract_V1_1_1_Web3 - | SafeContract_V1_0_0_Web3 { - switch (safeVersion) { - case '1.4.1': - return new SafeContract_V1_4_1_Web3(safeContract as SafeSingleton_V1_4_1) - case '1.3.0': - return new SafeContract_V1_3_0_Web3(safeContract as SafeSingleton_V1_3_0) - case '1.2.0': - return new SafeContract_V1_2_0_Web3(safeContract as SafeSingleton_V1_2_0) - case '1.1.1': - return new SafeContract_V1_1_1_Web3(safeContract as SafeSingleton_V1_1_1) - case '1.0.0': - return new SafeContract_V1_0_0_Web3(safeContract as SafeSingleton_V1_0_0) - default: - throw new Error('Invalid Safe version') - } -} - -export function getCompatibilityFallbackHandlerContractInstance( - safeVersion: SafeVersion, - compatibilityFallbackhandlerContract: - | CompatibilityFallbackHandler_V1_4_1 - | CompatibilityFallbackHandler_V1_3_0 -): CompatibilityFallbackHandler_V1_4_1_Web3 | CompatibilityFallbackHandler_V1_3_0_Web3 { - switch (safeVersion) { - case '1.4.1': - return new CompatibilityFallbackHandler_V1_4_1_Web3( - compatibilityFallbackhandlerContract as CompatibilityFallbackHandler_V1_4_1 - ) - case '1.3.0': - case '1.2.0': - case '1.1.1': - return new CompatibilityFallbackHandler_V1_3_0_Web3( - compatibilityFallbackhandlerContract as CompatibilityFallbackHandler_V1_3_0 - ) - default: - throw new Error('Invalid Safe version') - } -} - -export function getMultiSendContractInstance( - safeVersion: SafeVersion, - multiSendContract: MultiSend_V1_4_1 | MultiSend_V1_3_0 | MultiSend_V1_1_1 -): MultiSendContract_V1_4_1_Web3 | MultiSendContract_V1_3_0_Web3 | MultiSendContract_V1_1_1_Web3 { - switch (safeVersion) { - case '1.4.1': - return new MultiSendContract_V1_4_1_Web3(multiSendContract as MultiSend_V1_4_1) - case '1.3.0': - return new MultiSendContract_V1_3_0_Web3(multiSendContract as MultiSend_V1_3_0) - case '1.2.0': - case '1.1.1': - case '1.0.0': - return new MultiSendContract_V1_1_1_Web3(multiSendContract as MultiSend_V1_1_1) - default: - throw new Error('Invalid Safe version') - } -} - -export function getMultiSendCallOnlyContractInstance( - safeVersion: SafeVersion, - multiSendCallOnlyContract: MultiSendCallOnly_V1_4_1 | MultiSendCallOnly_V1_3_0 -): MultiSendCallOnlyContract_V1_4_1_Web3 | MultiSendCallOnlyContract_V1_3_0_Web3 { - switch (safeVersion) { - case '1.4.1': - return new MultiSendCallOnlyContract_V1_4_1_Web3( - multiSendCallOnlyContract as MultiSendCallOnly_V1_4_1 - ) - case '1.3.0': - case '1.2.0': - case '1.1.1': - case '1.0.0': - return new MultiSendCallOnlyContract_V1_3_0_Web3( - multiSendCallOnlyContract as MultiSendCallOnly_V1_3_0 - ) - default: - throw new Error('Invalid Safe version') - } -} - -export function getSafeProxyFactoryContractInstance( - safeVersion: SafeVersion, - safeProxyFactoryContract: - | SafeProxyFactory_V1_4_1 - | SafeProxyFactory_V1_3_0 - | SafeProxyFactory_V1_1_1 - | SafeProxyFactory_V1_0_0 -): - | SafeProxyFactoryContract_V1_4_1_Web3 - | SafeProxyFactoryContract_V1_3_0_Web3 - | SafeProxyFactoryContract_V1_1_1_Web3 - | SafeProxyFactoryContract_V1_0_0_Web3 { - switch (safeVersion) { - case '1.4.1': - return new SafeProxyFactoryContract_V1_4_1_Web3( - safeProxyFactoryContract as SafeProxyFactory_V1_4_1 - ) - case '1.3.0': - return new SafeProxyFactoryContract_V1_3_0_Web3( - safeProxyFactoryContract as SafeProxyFactory_V1_3_0 - ) - case '1.2.0': - case '1.1.1': - return new SafeProxyFactoryContract_V1_1_1_Web3( - safeProxyFactoryContract as SafeProxyFactory_V1_1_1 - ) - case '1.0.0': - return new SafeProxyFactoryContract_V1_0_0_Web3( - safeProxyFactoryContract as SafeProxyFactory_V1_0_0 - ) - default: - throw new Error('Invalid Safe version') - } -} - -export function getSignMessageLibContractInstance( - safeVersion: SafeVersion, - signMessageLibContract: SignMessageLib_V1_4_1 | SignMessageLib_V1_3_0 -): SignMessageLibContract_V1_4_1_Web3 | SignMessageLibContract_V1_3_0_Web3 { - switch (safeVersion) { - case '1.4.1': - return new SignMessageLibContract_V1_4_1_Web3(signMessageLibContract as SignMessageLib_V1_4_1) - case '1.3.0': - return new SignMessageLibContract_V1_3_0_Web3(signMessageLibContract as SignMessageLib_V1_3_0) - default: - throw new Error('Invalid Safe version') - } -} - -export function getCreateCallContractInstance( - safeVersion: SafeVersion, - createCallContract: CreateCall_V1_4_1 | CreateCall_V1_3_0 -): CreateCallContract_V1_4_1_Web3 | CreateCallContract_V1_3_0_Web3 { - switch (safeVersion) { - case '1.4.1': - return new CreateCallContract_V1_4_1_Web3(createCallContract as CreateCall_V1_4_1) - case '1.3.0': - case '1.2.0': - case '1.1.1': - case '1.0.0': - return new CreateCallContract_V1_3_0_Web3(createCallContract as CreateCall_V1_3_0) - default: - throw new Error('Invalid Safe version') - } -} - -export function getSimulateTxAccessorContractInstance( - safeVersion: SafeVersion, - simulateTxAccessorContract: SimulateTxAccessor_V1_4_1 | SimulateTxAccessor_V1_3_0 -): SimulateTxAccessorContract_V1_4_1_Web3 | SimulateTxAccessorContract_V1_3_0_Web3 { - switch (safeVersion) { - case '1.4.1': - return new SimulateTxAccessorContract_V1_4_1_Web3( - simulateTxAccessorContract as SimulateTxAccessor_V1_4_1 - ) - case '1.3.0': - return new SimulateTxAccessorContract_V1_3_0_Web3( - simulateTxAccessorContract as SimulateTxAccessor_V1_3_0 - ) - default: - throw new Error('Invalid Safe version') - } -} diff --git a/packages/protocol-kit/src/adapters/web3/index.ts b/packages/protocol-kit/src/adapters/web3/index.ts deleted file mode 100644 index b398e5923..000000000 --- a/packages/protocol-kit/src/adapters/web3/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -import Web3Adapter, { Web3AdapterConfig } from './Web3Adapter' -import CreateCallWeb3Contract from './contracts/CreateCall/CreateCallWeb3Contract' -import MultiSendWeb3Contract from './contracts/MultiSend/MultiSendWeb3Contract' -import MultiSendCallOnlyWeb3Contract from './contracts/MultiSendCallOnly/MultiSendCallOnlyWeb3Contract' -import SafeContractWeb3 from './contracts/Safe/SafeContractWeb3' -import SafeProxyFactoryWeb3Contract, { - CreateProxyProps -} from './contracts/SafeProxyFactory/SafeProxyFactoryWeb3Contract' -import SignMessageLibWeb3Contract from './contracts/SignMessageLib/SignMessageLibWeb3Contract' -import { Web3TransactionOptions, Web3TransactionResult } from './types' - -export { - CreateCallWeb3Contract, - CreateProxyProps, - MultiSendCallOnlyWeb3Contract, - MultiSendWeb3Contract, - SafeContractWeb3, - SafeProxyFactoryWeb3Contract, - SignMessageLibWeb3Contract, - Web3Adapter, - Web3AdapterConfig, - Web3TransactionOptions, - Web3TransactionResult -} diff --git a/packages/protocol-kit/src/adapters/web3/types.ts b/packages/protocol-kit/src/adapters/web3/types.ts deleted file mode 100644 index 6e60f9337..000000000 --- a/packages/protocol-kit/src/adapters/web3/types.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { BaseTransactionResult } from '@safe-global/safe-core-sdk-types' -import { PromiEvent, TransactionReceipt } from 'web3-core/types' - -export interface Web3TransactionOptions { - from?: string - gas?: number | string - gasPrice?: number | string - maxFeePerGas?: number | string - maxPriorityFeePerGas?: number | string - nonce?: number -} - -export interface Web3TransactionResult extends BaseTransactionResult { - promiEvent: PromiEvent - options?: Web3TransactionOptions -} diff --git a/packages/protocol-kit/src/adapters/web3/utils/constants.ts b/packages/protocol-kit/src/adapters/web3/utils/constants.ts deleted file mode 100644 index b8a31c39f..000000000 --- a/packages/protocol-kit/src/adapters/web3/utils/constants.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const ZERO_ADDRESS = `0x${'0'.repeat(40)}` -export const EMPTY_DATA = '0x' -export const SENTINEL_ADDRESS = '0x0000000000000000000000000000000000000001' diff --git a/packages/protocol-kit/src/adapters/web3/utils/index.ts b/packages/protocol-kit/src/adapters/web3/utils/index.ts deleted file mode 100644 index 2c36e0712..000000000 --- a/packages/protocol-kit/src/adapters/web3/utils/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { PromiEvent, TransactionReceipt } from 'web3-core/types' -import { - Web3TransactionOptions, - Web3TransactionResult -} from '@safe-global/protocol-kit/adapters/web3/types' - -export function sameString(str1: string, str2: string): boolean { - return str1.toLowerCase() === str2.toLowerCase() -} - -export async function toTxResult( - promiEvent: PromiEvent, - options?: Web3TransactionOptions -): Promise { - return new Promise((resolve, reject) => - promiEvent - .once('transactionHash', (hash: string) => resolve({ hash, promiEvent, options })) - .catch(reject) - ) -} diff --git a/packages/protocol-kit/src/contracts/BaseContract.ts b/packages/protocol-kit/src/contracts/BaseContract.ts new file mode 100644 index 000000000..3041893a1 --- /dev/null +++ b/packages/protocol-kit/src/contracts/BaseContract.ts @@ -0,0 +1,104 @@ +import { Abi } from 'abitype' +import { Contract, ContractRunner, InterfaceAbi } from 'ethers' + +import { contractName, getContractDeployment } from '@safe-global/protocol-kit/contracts/config' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' +import { + EncodeFunction, + EstimateGasFunction, + GetAddressFunction, + SafeVersion +} from '@safe-global/safe-core-sdk-types' + +/** + * Abstract class BaseContract + * It is designed to be instantiated for different contracts. + * + * This abstract class sets up the Ethers v6 Contract object that interacts with the smart contract. + * + * Subclasses of BaseContract are expected to represent specific contracts. + * + * @template ContractAbiType - The ABI type specific to the version of the contract, extending InterfaceAbi from Ethers. + * + * Example subclasses: + * - SafeBaseContract extends BaseContract + * - CreateCallBaseContract extends BaseContract + * - SafeProxyFactoryBaseContract extends BaseContract + */ +class BaseContract { + contractAbi: ContractAbiType + contractAddress: string + contractName: contractName + safeVersion: SafeVersion + safeProvider: SafeProvider + contract!: Contract + runner?: ContractRunner | null + + /** + * @constructor + * Constructs an instance of BaseContract. + * + * @param contractName - The contract name. + * @param chainId - The chain ID of the contract. + * @param safeProvider - An instance of SafeProvider. + * @param defaultAbi - The default ABI for the contract. It should be compatible with the specific version of the contract. + * @param safeVersion - The version of the Safe contract. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the Safe deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the ABI is derived from the Safe deployments or the defaultAbi is used. + */ + constructor( + contractName: contractName, + chainId: bigint, + safeProvider: SafeProvider, + defaultAbi: ContractAbiType, + safeVersion: SafeVersion, + customContractAddress?: string, + customContractAbi?: ContractAbiType, + runner?: ContractRunner | null + ) { + const deployment = getContractDeployment(safeVersion, chainId, contractName) + + const contractAddress = + customContractAddress || + deployment?.networkAddresses[chainId.toString()] || + deployment?.defaultAddress + + if (!contractAddress) { + throw new Error(`Invalid ${contractName.replace('Version', '')} contract address`) + } + + this.contractName = contractName + this.safeVersion = safeVersion + this.contractAddress = contractAddress + this.contractAbi = + customContractAbi || + (deployment?.abi as unknown as ContractAbiType) || // this cast is required because abi is set as any[] in safe-deployments + defaultAbi // if no customAbi and no abi is present in the safe-deployments we use our hardcoded abi + + this.runner = runner || safeProvider.getExternalProvider() + this.safeProvider = safeProvider + } + + async init() { + this.contract = new Contract( + this.contractAddress, + this.contractAbi, + (await this.safeProvider.getExternalSigner()) || this.runner + ) + } + + getAddress: GetAddressFunction = () => { + return this.contract.getAddress() + } + + encode: EncodeFunction = (functionToEncode, args) => { + return this.contract.interface.encodeFunctionData(functionToEncode, args as ReadonlyArray<[]>) + } + + estimateGas: EstimateGasFunction = (functionToEstimate, args, options = {}) => { + const contractMethodToEstimate = this.contract.getFunction(functionToEstimate) + return contractMethodToEstimate.estimateGas(...(args as ReadonlyArray<[]>), options) + } +} + +export default BaseContract diff --git a/packages/protocol-kit/src/contracts/CompatibilityFallbackHandler/CompatibilityFallbackHandlerBaseContract.ts b/packages/protocol-kit/src/contracts/CompatibilityFallbackHandler/CompatibilityFallbackHandlerBaseContract.ts new file mode 100644 index 000000000..2583b1b10 --- /dev/null +++ b/packages/protocol-kit/src/contracts/CompatibilityFallbackHandler/CompatibilityFallbackHandlerBaseContract.ts @@ -0,0 +1,64 @@ +import { Abi } from 'abitype' +import { ContractRunner, InterfaceAbi } from 'ethers' + +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' +import BaseContract from '@safe-global/protocol-kit/contracts/BaseContract' +import { SafeVersion } from '@safe-global/safe-core-sdk-types' +import { contractName } from '@safe-global/protocol-kit/contracts/config' + +/** + * Abstract class CompatibilityFallbackHandlerBaseContract extends BaseContract to specifically integrate with the CompatibilityFallbackHandler contract. + * It is designed to be instantiated for different versions of the Safe contract. + * + * Subclasses of CompatibilityFallbackHandlerBaseContract are expected to represent specific versions of the contract. + * + * @template CompatibilityFallbackHandlerContractAbiType - The ABI type specific to the version of the CompatibilityFallbackHandler contract, extending InterfaceAbi from Ethers. + * @extends BaseContract - Extends the generic BaseContract. + * + * Example subclasses: + * - CompatibilityFallbackHandlerContract_v1_4_1 extends CompatibilityFallbackHandlerBaseContract + * - CompatibilityFallbackHandlerContract_v1_3_0 extends CompatibilityFallbackHandlerBaseContract + */ +abstract class CompatibilityFallbackHandlerBaseContract< + CompatibilityFallbackHandlerContractAbiType extends InterfaceAbi & Abi +> extends BaseContract { + contractName: contractName + + /** + * @constructor + * Constructs an instance of CompatibilityFallbackHandlerBaseContract. + * + * @param chainId - The chain ID of the contract. + * @param safeProvider - An instance of SafeProvider. + * @param defaultAbi - The default ABI for the CompatibilityFallbackHandler contract. It should be compatible with the specific version of the contract. + * @param safeVersion - The version of the Safe contract. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the Safe deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the ABI is derived from the Safe deployments or the defaultAbi is used. + */ + constructor( + chainId: bigint, + safeProvider: SafeProvider, + defaultAbi: CompatibilityFallbackHandlerContractAbiType, + safeVersion: SafeVersion, + customContractAddress?: string, + customContractAbi?: CompatibilityFallbackHandlerContractAbiType, + runner?: ContractRunner | null + ) { + const contractName = 'compatibilityFallbackHandler' + + super( + contractName, + chainId, + safeProvider, + defaultAbi, + safeVersion, + customContractAddress, + customContractAbi, + runner + ) + + this.contractName = contractName + } +} + +export default CompatibilityFallbackHandlerBaseContract diff --git a/packages/protocol-kit/src/contracts/CompatibilityFallbackHandler/v1.3.0/CompatibilityFallbackHandlerContract_v1_3_0.ts b/packages/protocol-kit/src/contracts/CompatibilityFallbackHandler/v1.3.0/CompatibilityFallbackHandlerContract_v1_3_0.ts new file mode 100644 index 000000000..349e010d7 --- /dev/null +++ b/packages/protocol-kit/src/contracts/CompatibilityFallbackHandler/v1.3.0/CompatibilityFallbackHandlerContract_v1_3_0.ts @@ -0,0 +1,47 @@ +import CompatibilityFallbackHandlerBaseContract from '@safe-global/protocol-kit/contracts/CompatibilityFallbackHandler/CompatibilityFallbackHandlerBaseContract' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' +import { + SafeVersion, + CompatibilityFallbackHandlerContract_v1_3_0_Abi, + CompatibilityFallbackHandlerContract_v1_3_0_Contract, + compatibilityFallbackHandler_1_3_0_ContractArtifacts +} from '@safe-global/safe-core-sdk-types' + +/** + * CompatibilityFallbackHandlerContract_v1_3_0 is the implementation specific to the CompatibilityFallbackHandler contract version 1.3.0. + * + * This class specializes in handling interactions with the CompatibilityFallbackHandler contract version 1.3.0 using Ethers.js v6. + * + * @extends CompatibilityFallbackHandlerBaseContract - Inherits from CompatibilityFallbackHandlerBaseContract with ABI specific to CompatibilityFallbackHandler contract version 1.3.0. + * @implements CompatibilityFallbackHandlerContract_v1_3_0_Contract - Implements the interface specific to CompatibilityFallbackHandler contract version 1.3.0. + */ +class CompatibilityFallbackHandlerContract_v1_3_0 + extends CompatibilityFallbackHandlerBaseContract + implements CompatibilityFallbackHandlerContract_v1_3_0_Contract +{ + safeVersion: SafeVersion + + /** + * Constructs an instance of CompatibilityFallbackHandlerContract_v1_3_0 + * + * @param chainId - The chain ID where the contract resides. + * @param safeProvider - An instance of SafeProvider. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the CompatibilityFallbackHandler deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the default ABI for version 1.3.0 is used. + */ + constructor( + chainId: bigint, + safeProvider: SafeProvider, + customContractAddress?: string, + customContractAbi?: CompatibilityFallbackHandlerContract_v1_3_0_Abi + ) { + const safeVersion = '1.3.0' + const defaultAbi = compatibilityFallbackHandler_1_3_0_ContractArtifacts.abi + + super(chainId, safeProvider, defaultAbi, safeVersion, customContractAddress, customContractAbi) + + this.safeVersion = safeVersion + } +} + +export default CompatibilityFallbackHandlerContract_v1_3_0 diff --git a/packages/protocol-kit/src/contracts/CompatibilityFallbackHandler/v1.4.1/CompatibilityFallbackHandlerContract_v1_4_1.ts b/packages/protocol-kit/src/contracts/CompatibilityFallbackHandler/v1.4.1/CompatibilityFallbackHandlerContract_v1_4_1.ts new file mode 100644 index 000000000..3cf7af032 --- /dev/null +++ b/packages/protocol-kit/src/contracts/CompatibilityFallbackHandler/v1.4.1/CompatibilityFallbackHandlerContract_v1_4_1.ts @@ -0,0 +1,47 @@ +import CompatibilityFallbackHandlerBaseContract from '@safe-global/protocol-kit/contracts/CompatibilityFallbackHandler/CompatibilityFallbackHandlerBaseContract' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' +import { + compatibilityFallbackHandler_1_4_1_ContractArtifacts, + CompatibilityFallbackHandlerContract_v1_4_1_Abi, + CompatibilityFallbackHandlerContract_v1_4_1_Contract, + SafeVersion +} from '@safe-global/safe-core-sdk-types' + +/** + * CompatibilityFallbackHandlerContract_v1_4_1 is the implementation specific to the CompatibilityFallbackHandler contract version 1.4.1. + * + * This class specializes in handling interactions with the CompatibilityFallbackHandler contract version 1.4.1 using Ethers.js v6. + * + * @extends CompatibilityFallbackHandlerBaseContract - Inherits from CompatibilityFallbackHandlerBaseContract with ABI specific to CompatibilityFallbackHandler contract version 1.4.1. + * @implements CompatibilityFallbackHandlerContract_v1_4_1_Contract - Implements the interface specific to CompatibilityFallbackHandler contract version 1.4.1. + */ +class CompatibilityFallbackHandlerContract_v1_4_1 + extends CompatibilityFallbackHandlerBaseContract + implements CompatibilityFallbackHandlerContract_v1_4_1_Contract +{ + safeVersion: SafeVersion + + /** + * Constructs an instance of CompatibilityFallbackHandlerContract_v1_4_1 + * + * @param chainId - The chain ID where the contract resides. + * @param safeProvider - An instance of SafeProvider. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the CompatibilityFallbackHandler deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the default ABI for version 1.4.1 is used. + */ + constructor( + chainId: bigint, + safeProvider: SafeProvider, + customContractAddress?: string, + customContractAbi?: CompatibilityFallbackHandlerContract_v1_4_1_Abi + ) { + const safeVersion = '1.4.1' + const defaultAbi = compatibilityFallbackHandler_1_4_1_ContractArtifacts.abi + + super(chainId, safeProvider, defaultAbi, safeVersion, customContractAddress, customContractAbi) + + this.safeVersion = safeVersion + } +} + +export default CompatibilityFallbackHandlerContract_v1_4_1 diff --git a/packages/protocol-kit/src/contracts/CreateCall/CreateCallBaseContract.ts b/packages/protocol-kit/src/contracts/CreateCall/CreateCallBaseContract.ts new file mode 100644 index 000000000..9dc3ae51d --- /dev/null +++ b/packages/protocol-kit/src/contracts/CreateCall/CreateCallBaseContract.ts @@ -0,0 +1,64 @@ +import { Abi } from 'abitype' +import { ContractRunner, InterfaceAbi } from 'ethers' + +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' +import BaseContract from '@safe-global/protocol-kit/contracts/BaseContract' +import { SafeVersion } from '@safe-global/safe-core-sdk-types' +import { contractName } from '@safe-global/protocol-kit/contracts/config' + +/** + * Abstract class CreateCallBaseContract extends BaseContract to specifically integrate with the CreateCall contract. + * It is designed to be instantiated for different versions of the Safe contract. + * + * Subclasses of CreateCallBaseContract are expected to represent specific versions of the contract. + * + * @template CreateCallContractAbiType - The ABI type specific to the version of the CreateCall contract, extending InterfaceAbi from Ethers. + * @extends BaseContract - Extends the generic BaseContract. + * + * Example subclasses: + * - CreateCallContract_v1_4_1 extends CreateCallBaseContract + * - CreateCallContract_v1_3_0 extends CreateCallBaseContract + */ +abstract class CreateCallBaseContract< + CreateCallContractAbiType extends InterfaceAbi & Abi +> extends BaseContract { + contractName: contractName + + /** + * @constructor + * Constructs an instance of CreateCallBaseContract. + * + * @param chainId - The chain ID of the contract. + * @param safeProvider - An instance of SafeProvider. + * @param defaultAbi - The default ABI for the CreateCall contract. It should be compatible with the specific version of the contract. + * @param safeVersion - The version of the Safe contract. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the Safe deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the ABI is derived from the Safe deployments or the defaultAbi is used. + */ + constructor( + chainId: bigint, + safeProvider: SafeProvider, + defaultAbi: CreateCallContractAbiType, + safeVersion: SafeVersion, + customContractAddress?: string, + customContractAbi?: CreateCallContractAbiType, + runner?: ContractRunner | null + ) { + const contractName = 'createCallVersion' + + super( + contractName, + chainId, + safeProvider, + defaultAbi, + safeVersion, + customContractAddress, + customContractAbi, + runner + ) + + this.contractName = contractName + } +} + +export default CreateCallBaseContract diff --git a/packages/protocol-kit/src/contracts/CreateCall/v1.3.0/CreateCallContract_v1_3_0.ts b/packages/protocol-kit/src/contracts/CreateCall/v1.3.0/CreateCallContract_v1_3_0.ts new file mode 100644 index 000000000..9d44b93c7 --- /dev/null +++ b/packages/protocol-kit/src/contracts/CreateCall/v1.3.0/CreateCallContract_v1_3_0.ts @@ -0,0 +1,83 @@ +import CreateCallBaseContract from '@safe-global/protocol-kit/contracts/CreateCall/CreateCallBaseContract' +import { + SafeVersion, + CreateCallContract_v1_3_0_Abi, + CreateCallContract_v1_3_0_Contract, + createCall_1_3_0_ContractArtifacts, + SafeContractFunction +} from '@safe-global/safe-core-sdk-types' +import { toTxResult } from '@safe-global/protocol-kit/contracts/utils' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' + +/** + * CreateCallContract_v1_3_0 is the implementation specific to the CreateCall contract version 1.3.0. + * + * This class specializes in handling interactions with the CreateCall contract version 1.3.0 using Ethers.js v6. + * + * @extends CreateCallBaseContract - Inherits from CreateCallBaseContract with ABI specific to CreateCall contract version 1.3.0. + * @implements CreateCallContract_v1_3_0_Contract - Implements the interface specific to CreateCall contract version 1.3.0. + */ +class CreateCallContract_v1_3_0 + extends CreateCallBaseContract + implements CreateCallContract_v1_3_0_Contract +{ + safeVersion: SafeVersion + + /** + * Constructs an instance of CreateCallContract_v1_3_0 + * + * @param chainId - The chain ID where the contract resides. + * @param safeProvider - An instance of SafeProvider. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the CreateCall deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the default ABI for version 1.3.0 is used. + */ + constructor( + chainId: bigint, + safeProvider: SafeProvider, + customContractAddress?: string, + customContractAbi?: CreateCallContract_v1_3_0_Abi + ) { + const safeVersion = '1.3.0' + const defaultAbi = createCall_1_3_0_ContractArtifacts.abi + + super(chainId, safeProvider, defaultAbi, safeVersion, customContractAddress, customContractAbi) + + this.safeVersion = safeVersion + } + + /** + * @param args - Array[value, deploymentData] + * @param options - TransactionOptions + * @returns Promise + */ + performCreate: SafeContractFunction = async ( + args, + options + ) => { + if (options && !options.gasLimit) { + options.gasLimit = ( + await this.estimateGas('performCreate', [...args], { ...options }) + ).toString() + } + const txResponse = await this.contract.performCreate(...args, { ...options }) + return toTxResult(txResponse, options) + } + + /** + * @param args - Array[value, deploymentData, salt] + * @param options - TransactionOptions + * @returns Promise + */ + performCreate2: SafeContractFunction = async ( + args, + options + ) => { + if (options && !options.gasLimit) { + options.gasLimit = (await this.estimateGas('performCreate2', args, options)).toString() + } + const txResponse = await this.contract.performCreate2(...args) + return toTxResult(txResponse, options) + } +} + +export default CreateCallContract_v1_3_0 diff --git a/packages/protocol-kit/src/contracts/CreateCall/v1.4.1/CreateCallContract_v1_4_1.ts b/packages/protocol-kit/src/contracts/CreateCall/v1.4.1/CreateCallContract_v1_4_1.ts new file mode 100644 index 000000000..f9f1e0094 --- /dev/null +++ b/packages/protocol-kit/src/contracts/CreateCall/v1.4.1/CreateCallContract_v1_4_1.ts @@ -0,0 +1,83 @@ +import CreateCallBaseContract from '@safe-global/protocol-kit/contracts/CreateCall/CreateCallBaseContract' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' +import { + SafeVersion, + CreateCallContract_v1_4_1_Abi, + CreateCallContract_v1_4_1_Contract, + createCall_1_4_1_ContractArtifacts, + SafeContractFunction +} from '@safe-global/safe-core-sdk-types' +import { toTxResult } from '@safe-global/protocol-kit/contracts/utils' + +/** + * CreateCallContract_v1_4_1 is the implementation specific to the CreateCall contract version 1.4.1. + * + * This class specializes in handling interactions with the CreateCall contract version 1.4.1 using Ethers.js v6. + * + * @extends CreateCallBaseContract - Inherits from CreateCallBaseContract with ABI specific to CreateCall contract version 1.4.1. + * @implements CreateCallContract_v1_4_1_Contract - Implements the interface specific to CreateCall contract version 1.4.1. + */ +class CreateCallContract_v1_4_1 + extends CreateCallBaseContract + implements CreateCallContract_v1_4_1_Contract +{ + safeVersion: SafeVersion + + /** + * Constructs an instance of CreateCallContract_v1_4_1 + * + * @param chainId - The chain ID where the contract resides. + * @param safeProvider - An instance of SafeProvider. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the CreateCall deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the default ABI for version 1.4.1 is used. + */ + constructor( + chainId: bigint, + safeProvider: SafeProvider, + customContractAddress?: string, + customContractAbi?: CreateCallContract_v1_4_1_Abi + ) { + const safeVersion = '1.4.1' + const defaultAbi = createCall_1_4_1_ContractArtifacts.abi + + super(chainId, safeProvider, defaultAbi, safeVersion, customContractAddress, customContractAbi) + + this.safeVersion = safeVersion + } + + /** + * @param args - Array[value, deploymentData] + * @param options - TransactionOptions + * @returns Promise + */ + performCreate: SafeContractFunction = async ( + args, + options + ) => { + if (options && !options.gasLimit) { + options.gasLimit = (await this.estimateGas('performCreate', args, options)).toString() + } + const txResponse = await this.contract.performCreate(...args, options) + return toTxResult(txResponse, options) + } + + /** + * @param args - Array[value, deploymentData, salt] + * @param options - TransactionOptions + * @returns Promise + */ + performCreate2: SafeContractFunction = async ( + args, + options + ) => { + if (options && !options.gasLimit) { + options.gasLimit = ( + await this.estimateGas('performCreate2', [...args], { ...options }) + ).toString() + } + const txResponse = await this.contract.performCreate2(...args) + return toTxResult(txResponse, options) + } +} + +export default CreateCallContract_v1_4_1 diff --git a/packages/protocol-kit/src/contracts/MultiSend/MultiSendBaseContract.ts b/packages/protocol-kit/src/contracts/MultiSend/MultiSendBaseContract.ts new file mode 100644 index 000000000..835be1b2f --- /dev/null +++ b/packages/protocol-kit/src/contracts/MultiSend/MultiSendBaseContract.ts @@ -0,0 +1,62 @@ +import { Abi } from 'abitype' +import { InterfaceAbi } from 'ethers' + +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' +import { SafeVersion } from '@safe-global/safe-core-sdk-types' +import BaseContract from '@safe-global/protocol-kit/contracts/BaseContract' +import { contractName } from '@safe-global/protocol-kit/contracts/config' + +/** + * Abstract class MultiSendBaseContract extends BaseContract to specifically integrate with the MultiSend contract. + * It is designed to be instantiated for different versions of the MultiSend contract. + * + * Subclasses of MultiSendBaseContract are expected to represent specific versions of the MultiSend contract. + * + * @template MultiSendContractAbiType - The ABI type specific to the version of the MultiSend contract, extending InterfaceAbi from Ethers. + * @extends BaseContract - Extends the generic BaseContract. + * + * Example subclasses: + * - MultiSendContract_v1_4_1 extends MultiSendBaseContract + * - MultiSendContract_v1_3_0 extends MultiSendBaseContract + */ +abstract class MultiSendBaseContract< + MultiSendContractAbiType extends InterfaceAbi & Abi +> extends BaseContract { + contractName: contractName + + /** + * @constructor + * Constructs an instance of MultiSendBaseContract. + * + * @param chainId - The chain ID of the contract. + * @param safeProvider - An instance of SafeProvider. + * @param defaultAbi - The default ABI for the MultiSend contract. It should be compatible with the specific version of the MultiSend contract. + * @param safeVersion - The version of the MultiSend contract. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the MultiSend deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the ABI is derived from the MultiSend deployments or the defaultAbi is used. + */ + constructor( + chainId: bigint, + safeProvider: SafeProvider, + defaultAbi: MultiSendContractAbiType, + safeVersion: SafeVersion, + customContractAddress?: string, + customContractAbi?: MultiSendContractAbiType + ) { + const contractName = 'multiSendVersion' + + super( + contractName, + chainId, + safeProvider, + defaultAbi, + safeVersion, + customContractAddress, + customContractAbi + ) + + this.contractName = contractName + } +} + +export default MultiSendBaseContract diff --git a/packages/protocol-kit/src/contracts/MultiSend/MultiSendCallOnlyBaseContract.ts b/packages/protocol-kit/src/contracts/MultiSend/MultiSendCallOnlyBaseContract.ts new file mode 100644 index 000000000..bd69961e1 --- /dev/null +++ b/packages/protocol-kit/src/contracts/MultiSend/MultiSendCallOnlyBaseContract.ts @@ -0,0 +1,62 @@ +import { Abi } from 'abitype' +import { InterfaceAbi } from 'ethers' + +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' +import { SafeVersion } from '@safe-global/safe-core-sdk-types' +import BaseContract from '@safe-global/protocol-kit/contracts/BaseContract' +import { contractName } from '@safe-global/protocol-kit/contracts/config' + +/** + * Abstract class MultiSendCallOnlyBaseContract extends BaseContract to specifically integrate with the MultiSendCallOnly contract. + * It is designed to be instantiated for different versions of the MultiSendCallOnly contract. + * + * Subclasses of MultiSendCallOnlyBaseContract are expected to represent specific versions of the MultiSendCallOnly contract. + * + * @template MultiSendCallOnlyContractAbiType - The ABI type specific to the version of the MultiSendCallOnly contract, extending InterfaceAbi from Ethers. + * @extends BaseContract - Extends the generic BaseContract. + * + * Example subclasses: + * - MultiSendCallOnlyContract_v1_4_1 extends MultiSendCallOnlyBaseContract + * - MultiSendCallOnlyContract_v1_3_0 extends MultiSendCallOnlyBaseContract + */ +abstract class MultiSendCallOnlyBaseContract< + MultiSendCallOnlyContractAbiType extends InterfaceAbi & Abi +> extends BaseContract { + contractName: contractName + + /** + * @constructor + * Constructs an instance of MultiSendCallOnlyBaseContract. + * + * @param chainId - The chain ID of the contract. + * @param safeProvider - An instance of SafeProvider. + * @param defaultAbi - The default ABI for the MultiSendCallOnly contract. It should be compatible with the specific version of the MultiSendCallOnly contract. + * @param safeVersion - The version of the MultiSendCallOnly contract. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the MultiSendCallOnly deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the ABI is derived from the MultiSendCallOnly deployments or the defaultAbi is used. + */ + constructor( + chainId: bigint, + safeProvider: SafeProvider, + defaultAbi: MultiSendCallOnlyContractAbiType, + safeVersion: SafeVersion, + customContractAddress?: string, + customContractAbi?: MultiSendCallOnlyContractAbiType + ) { + const contractName = 'multiSendCallOnlyVersion' + + super( + contractName, + chainId, + safeProvider, + defaultAbi, + safeVersion, + customContractAddress, + customContractAbi + ) + + this.contractName = contractName + } +} + +export default MultiSendCallOnlyBaseContract diff --git a/packages/protocol-kit/src/contracts/MultiSend/v1.1.1/MultiSendContract_v1_1_1.ts b/packages/protocol-kit/src/contracts/MultiSend/v1.1.1/MultiSendContract_v1_1_1.ts new file mode 100644 index 000000000..9f7897565 --- /dev/null +++ b/packages/protocol-kit/src/contracts/MultiSend/v1.1.1/MultiSendContract_v1_1_1.ts @@ -0,0 +1,47 @@ +import MultiSendBaseContract from '@safe-global/protocol-kit/contracts/MultiSend/MultiSendBaseContract' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' +import { + SafeVersion, + multisend_1_1_1_ContractArtifacts, + MultiSendContract_v1_1_1_Abi, + MultiSendContract_v1_1_1_Contract +} from '@safe-global/safe-core-sdk-types' + +/** + * MultiSendContract_v1_1_1 is the implementation specific to the MultiSend contract version 1.1.1. + * + * This class specializes in handling interactions with the MultiSend contract version 1.1.1 using Ethers.js v6. + * + * @extends MultiSendBaseContract - Inherits from MultiSendBaseContract with ABI specific to MultiSend contract version 1.1.1. + * @implements MultiSendContract_v1_1_1_Contract - Implements the interface specific to MultiSend contract version 1.1.1. + */ +class MultiSendContract_v1_1_1 + extends MultiSendBaseContract + implements MultiSendContract_v1_1_1_Contract +{ + safeVersion: SafeVersion + + /** + * Constructs an instance of MultiSendContract_v1_1_1 + * + * @param chainId - The chain ID where the contract resides. + * @param safeProvider - An instance of SafeProvider. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the MultiSend deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the default ABI for version 1.1.1 is used. + */ + constructor( + chainId: bigint, + safeProvider: SafeProvider, + customContractAddress?: string, + customContractAbi?: MultiSendContract_v1_1_1_Abi + ) { + const safeVersion = '1.1.1' + const defaultAbi = multisend_1_1_1_ContractArtifacts.abi + + super(chainId, safeProvider, defaultAbi, safeVersion, customContractAddress, customContractAbi) + + this.safeVersion = safeVersion + } +} + +export default MultiSendContract_v1_1_1 diff --git a/packages/protocol-kit/src/contracts/MultiSend/v1.3.0/MultiSendCallOnlyContract_v1_3_0.ts b/packages/protocol-kit/src/contracts/MultiSend/v1.3.0/MultiSendCallOnlyContract_v1_3_0.ts new file mode 100644 index 000000000..74e8ffb8f --- /dev/null +++ b/packages/protocol-kit/src/contracts/MultiSend/v1.3.0/MultiSendCallOnlyContract_v1_3_0.ts @@ -0,0 +1,47 @@ +import MultiSendCallOnlyBaseContract from '@safe-global/protocol-kit/contracts/MultiSend/MultiSendCallOnlyBaseContract' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' +import { + SafeVersion, + MultiSendCallOnlyContract_v1_3_0_Abi, + MultiSendCallOnlyContract_v1_3_0_Contract, + multiSendCallOnly_1_3_0_ContractArtifacts +} from '@safe-global/safe-core-sdk-types' + +/** + * MultiSendCallOnlyContract_v1_3_0 is the implementation specific to the MultiSendCallOnly contract version 1.3.0. + * + * This class specializes in handling interactions with the MultiSendCallOnly contract version 1.3.0 using Ethers.js v6. + * + * @extends MultiSendCallOnlyBaseContract - Inherits from MultiSendCallOnlyBaseContract with ABI specific to MultiSendCallOnly contract version 1.3.0. + * @implements MultiSendCallOnlyContract_v1_3_0_Contract - Implements the interface specific to MultiSendCallOnly contract version 1.3.0. + */ +class MultiSendCallOnlyContract_v1_3_0 + extends MultiSendCallOnlyBaseContract + implements MultiSendCallOnlyContract_v1_3_0_Contract +{ + safeVersion: SafeVersion + + /** + * Constructs an instance of MultiSendCallOnlyContract_v1_3_0 + * + * @param chainId - The chain ID where the contract resides. + * @param safeProvider - An instance of SafeProvider. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the MultiSendCallOnly deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the default ABI for version 1.3.0 is used. + */ + constructor( + chainId: bigint, + safeProvider: SafeProvider, + customContractAddress?: string, + customContractAbi?: MultiSendCallOnlyContract_v1_3_0_Abi + ) { + const safeVersion = '1.3.0' + const defaultAbi = multiSendCallOnly_1_3_0_ContractArtifacts.abi + + super(chainId, safeProvider, defaultAbi, safeVersion, customContractAddress, customContractAbi) + + this.safeVersion = safeVersion + } +} + +export default MultiSendCallOnlyContract_v1_3_0 diff --git a/packages/protocol-kit/src/contracts/MultiSend/v1.3.0/MultiSendContract_v1_3_0.ts b/packages/protocol-kit/src/contracts/MultiSend/v1.3.0/MultiSendContract_v1_3_0.ts new file mode 100644 index 000000000..ac5146f6e --- /dev/null +++ b/packages/protocol-kit/src/contracts/MultiSend/v1.3.0/MultiSendContract_v1_3_0.ts @@ -0,0 +1,47 @@ +import MultiSendBaseContract from '@safe-global/protocol-kit/contracts/MultiSend/MultiSendBaseContract' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' +import { + SafeVersion, + multisend_1_3_0_ContractArtifacts, + MultiSendContract_v1_3_0_Abi, + MultiSendContract_v1_3_0_Contract +} from '@safe-global/safe-core-sdk-types' + +/** + * MultiSendContract_v1_3_0 is the implementation specific to the MultiSend contract version 1.3.0. + * + * This class specializes in handling interactions with the MultiSend contract version 1.3.0 using Ethers.js v6. + * + * @extends MultiSendBaseContract - Inherits from MultiSendBaseContract with ABI specific to MultiSend contract version 1.3.0. + * @implements MultiSendContract_v1_3_0_Contract - Implements the interface specific to MultiSend contract version 1.3.0. + */ +class MultiSendContract_v1_3_0 + extends MultiSendBaseContract + implements MultiSendContract_v1_3_0_Contract +{ + safeVersion: SafeVersion + + /** + * Constructs an instance of MultiSendContract_v1_3_0 + * + * @param chainId - The chain ID where the contract resides. + * @param safeProvider - An instance of SafeProvider. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the MultiSend deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the default ABI for version 1.3.0 is used. + */ + constructor( + chainId: bigint, + safeProvider: SafeProvider, + customContractAddress?: string, + customContractAbi?: MultiSendContract_v1_3_0_Abi + ) { + const safeVersion = '1.3.0' + const defaultAbi = multisend_1_3_0_ContractArtifacts.abi + + super(chainId, safeProvider, defaultAbi, safeVersion, customContractAddress, customContractAbi) + + this.safeVersion = safeVersion + } +} + +export default MultiSendContract_v1_3_0 diff --git a/packages/protocol-kit/src/contracts/MultiSend/v1.4.1/MultiSendCallOnlyContract_v1_4_1.ts b/packages/protocol-kit/src/contracts/MultiSend/v1.4.1/MultiSendCallOnlyContract_v1_4_1.ts new file mode 100644 index 000000000..339502906 --- /dev/null +++ b/packages/protocol-kit/src/contracts/MultiSend/v1.4.1/MultiSendCallOnlyContract_v1_4_1.ts @@ -0,0 +1,47 @@ +import MultiSendCallOnlyBaseContract from '@safe-global/protocol-kit/contracts/MultiSend/MultiSendCallOnlyBaseContract' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' +import { + SafeVersion, + multiSendCallOnly_1_4_1_ContractArtifacts, + MultiSendCallOnlyContract_v1_4_1_Abi, + MultiSendCallOnlyContract_v1_4_1_Contract +} from '@safe-global/safe-core-sdk-types' + +/** + * MultiSendCallOnlyContract_v1_4_1 is the implementation specific to the MultiSend contract version 1.4.1. + * + * This class specializes in handling interactions with the MultiSendCallOnly contract version 1.4.1 using Ethers.js v6. + * + * @extends MultiSendCallOnlyBaseContract - Inherits from MultiSendBaseContract with ABI specific to MultiSendCallOnly contract version 1.4.1. + * @implements MultiSendCallOnlyContract_v1_4_1_Contract - Implements the interface specific to MultiSendCallOnly contract version 1.4.1. + */ +class MultiSendCallOnlyContract_v1_4_1 + extends MultiSendCallOnlyBaseContract + implements MultiSendCallOnlyContract_v1_4_1_Contract +{ + safeVersion: SafeVersion + + /** + * Constructs an instance of MultiSendCallOnlyContract_v1_4_1 + * + * @param chainId - The chain ID where the contract resides. + * @param safeProvider - An instance of SafeProvider. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the MultiSendCallOnly deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the default ABI for version 1.4.1 is used. + */ + constructor( + chainId: bigint, + safeProvider: SafeProvider, + customContractAddress?: string, + customContractAbi?: MultiSendCallOnlyContract_v1_4_1_Abi + ) { + const safeVersion = '1.4.1' + const defaultAbi = multiSendCallOnly_1_4_1_ContractArtifacts.abi + + super(chainId, safeProvider, defaultAbi, safeVersion, customContractAddress, customContractAbi) + + this.safeVersion = safeVersion + } +} + +export default MultiSendCallOnlyContract_v1_4_1 diff --git a/packages/protocol-kit/src/contracts/MultiSend/v1.4.1/MultiSendContract_v1_4_1.ts b/packages/protocol-kit/src/contracts/MultiSend/v1.4.1/MultiSendContract_v1_4_1.ts new file mode 100644 index 000000000..845ca5c4b --- /dev/null +++ b/packages/protocol-kit/src/contracts/MultiSend/v1.4.1/MultiSendContract_v1_4_1.ts @@ -0,0 +1,47 @@ +import MultiSendBaseContract from '@safe-global/protocol-kit/contracts/MultiSend/MultiSendBaseContract' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' +import { + SafeVersion, + MultiSendContract_v1_4_1_Abi, + MultiSendContract_v1_4_1_Contract, + multisend_1_4_1_ContractArtifacts +} from '@safe-global/safe-core-sdk-types' + +/** + * MultiSendContract_v1_4_1 is the implementation specific to the MultiSend contract version 1.4.1. + * + * This class specializes in handling interactions with the MultiSend contract version 1.4.1 using Ethers.js v6. + * + * @extends MultiSendBaseContract - Inherits from MultiSendBaseContract with ABI specific to MultiSend contract version 1.4.1. + * @implements MultiSendContract_v1_4_1_Contract - Implements the interface specific to MultiSend contract version 1.4.1. + */ +class MultiSendContract_v1_4_1 + extends MultiSendBaseContract + implements MultiSendContract_v1_4_1_Contract +{ + safeVersion: SafeVersion + + /** + * Constructs an instance of MultiSendContract_v1_4_1 + * + * @param chainId - The chain ID where the contract resides. + * @param safeProvider - An instance of SafeProvider. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the MultiSend deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the default ABI for version 1.4.1 is used. + */ + constructor( + chainId: bigint, + safeProvider: SafeProvider, + customContractAddress?: string, + customContractAbi?: MultiSendContract_v1_4_1_Abi + ) { + const safeVersion = '1.4.1' + const defaultAbi = multisend_1_4_1_ContractArtifacts.abi + + super(chainId, safeProvider, defaultAbi, safeVersion, customContractAddress, customContractAbi) + + this.safeVersion = safeVersion + } +} + +export default MultiSendContract_v1_4_1 diff --git a/packages/protocol-kit/src/contracts/Safe/SafeBaseContract.ts b/packages/protocol-kit/src/contracts/Safe/SafeBaseContract.ts new file mode 100644 index 000000000..ed826fa3d --- /dev/null +++ b/packages/protocol-kit/src/contracts/Safe/SafeBaseContract.ts @@ -0,0 +1,68 @@ +import { Abi } from 'abitype' +import { InterfaceAbi } from 'ethers' + +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' +import { SafeVersion } from '@safe-global/safe-core-sdk-types' +import BaseContract from '@safe-global/protocol-kit/contracts/BaseContract' +import { contractName, safeDeploymentsL1ChainIds } from '@safe-global/protocol-kit/contracts/config' + +/** + * Abstract class SafeBaseContract extends BaseContract to specifically integrate with the Safe contract. + * It is designed to be instantiated for different versions of the Safe contract. + * + * Subclasses of SafeBaseContract are expected to represent specific versions of the Safe contract. + * + * @template SafeContractAbiType - The ABI type specific to the version of the Safe contract, extending InterfaceAbi from Ethers. + * @extends BaseContract - Extends the generic BaseContract. + * + * Example subclasses: + * - SafeContract_v1_4_1 extends SafeBaseContract + * - SafeContract_v1_3_0 extends SafeBaseContract + * - SafeContract_v1_2_0 extends SafeBaseContract + * - SafeContract_v1_1_1 extends SafeBaseContract + * - SafeContract_v1_0_0 extends SafeBaseContract + */ +abstract class SafeBaseContract< + SafeContractAbiType extends InterfaceAbi & Abi +> extends BaseContract { + contractName: contractName + + /** + * @constructor + * Constructs an instance of SafeBaseContract. + * + * @param chainId - The chain ID of the contract. + * @param safeProvider - An instance of SafeProvider. + * @param defaultAbi - The default ABI for the Safe contract. It should be compatible with the specific version of the Safe contract. + * @param safeVersion - The version of the Safe contract. + * @param isL1SafeSingleton - A flag indicating if the contract is a L1 Safe Singleton. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the Safe deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the ABI is derived from the Safe deployments or the defaultAbi is used. + */ + constructor( + chainId: bigint, + safeProvider: SafeProvider, + defaultAbi: SafeContractAbiType, + safeVersion: SafeVersion, + isL1SafeSingleton = false, + customContractAddress?: string, + customContractAbi?: SafeContractAbiType + ) { + const isL1Contract = safeDeploymentsL1ChainIds.includes(chainId) || isL1SafeSingleton + const contractName = isL1Contract ? 'safeSingletonVersion' : 'safeSingletonL2Version' + + super( + contractName, + chainId, + safeProvider, + defaultAbi, + safeVersion, + customContractAddress, + customContractAbi + ) + + this.contractName = contractName + } +} + +export default SafeBaseContract diff --git a/packages/protocol-kit/src/contracts/Safe/v1.0.0/SafeContract_v1_0_0.ts b/packages/protocol-kit/src/contracts/Safe/v1.0.0/SafeContract_v1_0_0.ts new file mode 100644 index 000000000..c969d0446 --- /dev/null +++ b/packages/protocol-kit/src/contracts/Safe/v1.0.0/SafeContract_v1_0_0.ts @@ -0,0 +1,354 @@ +import SafeBaseContract from '@safe-global/protocol-kit/contracts/Safe/SafeBaseContract' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' +import { toTxResult } from '@safe-global/protocol-kit/contracts/utils' +import { sameString, isSentinelAddress } from '@safe-global/protocol-kit/utils' +import { + SafeVersion, + SafeContract_v1_0_0_Abi, + SafeContract_v1_0_0_Function, + SafeTransaction, + SafeContract_v1_0_0_Contract, + safe_1_0_0_ContractArtifacts, + TransactionOptions, + TransactionResult +} from '@safe-global/safe-core-sdk-types' +import { SENTINEL_ADDRESS } from '@safe-global/protocol-kit/utils/constants' + +/** + * SafeContract_v1_0_0 is the implementation specific to the Safe contract version 1.0.0. + * + * This class specializes in handling interactions with the Safe contract version 1.0.0 using Ethers.js v6. + * + * @extends SafeBaseContract - Inherits from SafeBaseContract with ABI specific to Safe contract version 1.0.0. + * @implements SafeContract_v1_0_0_Contract - Implements the interface specific to Safe contract version 1.0.0. + */ +class SafeContract_v1_0_0 + extends SafeBaseContract + implements SafeContract_v1_0_0_Contract +{ + safeVersion: SafeVersion + + /** + * Constructs an instance of SafeContract_v1_0_0 + * + * @param chainId - The chain ID where the contract resides. + * @param safeProvider - An instance of SafeProvider. + * @param isL1SafeSingleton - A flag indicating if the contract is a L1 Safe Singleton. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the Safe deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the default ABI for version 1.0.0 is used. + */ + constructor( + chainId: bigint, + safeProvider: SafeProvider, + isL1SafeSingleton = false, + customContractAddress?: string, + customContractAbi?: SafeContract_v1_0_0_Abi + ) { + const safeVersion = '1.0.0' + const defaultAbi = safe_1_0_0_ContractArtifacts.abi + + super( + chainId, + safeProvider, + defaultAbi, + safeVersion, + isL1SafeSingleton, + customContractAddress, + customContractAbi + ) + + this.safeVersion = safeVersion + } + + /* ----- Specific v1.0.0 properties ----- */ + DOMAIN_SEPARATOR_TYPEHASH: SafeContract_v1_0_0_Function<'DOMAIN_SEPARATOR_TYPEHASH'> = + async () => { + return [await this.contract.DOMAIN_SEPARATOR_TYPEHASH()] + } + + SENTINEL_MODULES: SafeContract_v1_0_0_Function<'SENTINEL_MODULES'> = async () => { + return [await this.contract.SENTINEL_MODULES()] + } + + SENTINEL_OWNERS: SafeContract_v1_0_0_Function<'SENTINEL_OWNERS'> = async () => { + return [await this.contract.SENTINEL_OWNERS()] + } + + SAFE_MSG_TYPEHASH: SafeContract_v1_0_0_Function<'SAFE_MSG_TYPEHASH'> = async () => { + return [await this.contract.SAFE_MSG_TYPEHASH()] + } + + SAFE_TX_TYPEHASH: SafeContract_v1_0_0_Function<'SAFE_TX_TYPEHASH'> = async () => { + return [await this.contract.SAFE_TX_TYPEHASH()] + } + /* ----- End of specific v1.0.0 properties ----- */ + + /** + * @returns Array[contractName] + */ + NAME: SafeContract_v1_0_0_Function<'NAME'> = async () => { + return [await this.contract.NAME()] + } + + /** + * @returns Array[safeContractVersion] + */ + VERSION: SafeContract_v1_0_0_Function<'VERSION'> = async () => { + return [await this.contract.VERSION()] + } + + /** + * @param args - Array[owner, txHash] + * @returns Array[approvedHashes] + */ + approvedHashes: SafeContract_v1_0_0_Function<'approvedHashes'> = async (args) => { + return [await this.contract.approvedHashes(...args)] + } + + /** + * @returns Array[domainSeparator] + */ + domainSeparator: SafeContract_v1_0_0_Function<'domainSeparator'> = async () => { + return [await this.contract.domainSeparator()] + } + + /** + * Returns array of modules. + * @returns Array[Array[modules]] + */ + getModules: SafeContract_v1_0_0_Function<'getModules'> = async () => { + return [await this.contract.getModules()] + } + + /** + * Returns the list of Safe owner accounts. + * @returns Array[Array[owners]] + */ + getOwners: SafeContract_v1_0_0_Function<'getOwners'> = async () => { + return [await this.contract.getOwners()] + } + + /** + * Returns the Safe threshold. + * @returns Array[threshold] + */ + getThreshold: SafeContract_v1_0_0_Function<'getThreshold'> = async () => { + return [await this.contract.getThreshold()] + } + + /** + * Checks if a specific address is an owner of the current Safe. + * @param args - Array[address] + * @returns Array[isOwner] + */ + isOwner: SafeContract_v1_0_0_Function<'isOwner'> = async (args) => { + return [await this.contract.isOwner(...args)] + } + + /** + * Returns the Safe nonce. + * @returns Array[nonce] + */ + nonce: SafeContract_v1_0_0_Function<'nonce'> = async () => { + return [await this.contract.nonce()] + } + + /** + * @param args - Array[messageHash] + * @returns Array[signedMessages] + */ + signedMessages: SafeContract_v1_0_0_Function<'signedMessages'> = async (args) => { + return [await this.contract.signedMessages(...args)] + } + + /** + * Returns hash of a message that can be signed by owners. + * @param args - Array[message] + * @returns Array[messageHash] + */ + getMessageHash: SafeContract_v1_0_0_Function<'getMessageHash'> = async (args) => { + return [await this.contract.getMessageHash(...args)] + } + + /** + * Returns the bytes that are hashed to be signed by owners. + * @param args - Array[to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce] + * @returns Array[encodedData] + */ + encodeTransactionData: SafeContract_v1_0_0_Function<'encodeTransactionData'> = async (args) => { + return [await this.contract.encodeTransactionData(...args)] + } + + /** + * Returns hash to be signed by owners. + * @param args - Array[to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce] + * @returns Array[transactionHash] + */ + getTransactionHash: SafeContract_v1_0_0_Function<'getTransactionHash'> = async (args) => { + return [await this.contract.getTransactionHash(...args)] + } + + /** + * Marks a hash as approved. This can be used to validate a hash that is used by a signature. + * @param hash - The hash that should be marked as approved for signatures that are verified by this contract. + * @param options - Optional transaction options. + * @returns Transaction result. + */ + async approveHash(hash: string, options?: TransactionOptions): Promise { + const gasLimit = options?.gasLimit || (await this.estimateGas('approveHash', [hash], options)) + const txResponse = await this.contract.approveHash(hash, { ...options, gasLimit }) + + return toTxResult(txResponse, options) + } + + /** + * Executes a transaction. + * @param safeTransaction - The Safe transaction to execute. + * @param options - Transaction options. + * @returns Transaction result. + */ + async execTransaction( + safeTransaction: SafeTransaction, + options?: TransactionOptions + ): Promise { + const gasLimit = + options?.gasLimit || + (await this.estimateGas( + 'execTransaction', + [ + safeTransaction.data.to, + BigInt(safeTransaction.data.value), + safeTransaction.data.data, + safeTransaction.data.operation, + BigInt(safeTransaction.data.safeTxGas), + BigInt(safeTransaction.data.baseGas), + BigInt(safeTransaction.data.gasPrice), + safeTransaction.data.gasToken, + safeTransaction.data.refundReceiver, + safeTransaction.encodedSignatures() + ], + options + )) + + const txResponse = await this.contract.execTransaction( + safeTransaction.data.to, + safeTransaction.data.value, + safeTransaction.data.data, + safeTransaction.data.operation, + safeTransaction.data.safeTxGas, + safeTransaction.data.baseGas, + safeTransaction.data.gasPrice, + safeTransaction.data.gasToken, + safeTransaction.data.refundReceiver, + safeTransaction.encodedSignatures(), + { ...options, gasLimit } + ) + + return toTxResult(txResponse, options) + } + + async getModulesPaginated([start, pageSize]: [string, bigint]): Promise<[string[], string]> { + if (pageSize <= 0) throw new Error('Invalid page size for fetching paginated modules') + + const size = Number(pageSize) + const [array] = await this.getModules() + + if (isSentinelAddress(start)) { + const next = pageSize < array.length ? array[size] : SENTINEL_ADDRESS + return [array.slice(0, size), next] + } else { + const moduleIndex = array.findIndex((module: string) => sameString(module, start)) + if (moduleIndex === -1) { + return [[], SENTINEL_ADDRESS] + } + + const nextElementIndex = moduleIndex + 1 + const nextPageAddress = + nextElementIndex + size < array.length ? array[nextElementIndex + size] : SENTINEL_ADDRESS + return [array.slice(moduleIndex + 1, nextElementIndex + size), nextPageAddress] + } + } + + /** + * Checks if a specific Safe module is enabled for the current Safe. + * @param moduleAddress - The module address to check. + * @returns True, if the module with the given address is enabled. + */ + async isModuleEnabled([moduleAddress]: [string]): Promise<[boolean]> { + const [modules] = await this.getModules() + const isModuleEnabled = modules.some((enabledModuleAddress) => + sameString(enabledModuleAddress, moduleAddress) + ) + return [isModuleEnabled] + } + + /** + * Checks whether a given Safe transaction can be executed successfully with no errors. + * @param safeTransaction - The Safe transaction to check. + * @param options - Optional transaction options. + * @returns True, if the given transactions is valid. + */ + async isValidTransaction( + safeTransaction: SafeTransaction, + options: TransactionOptions = {} + ): Promise { + try { + const gasLimit = + options?.gasLimit || + (await this.estimateGas( + 'execTransaction', + [ + safeTransaction.data.to, + BigInt(safeTransaction.data.value), + safeTransaction.data.data, + safeTransaction.data.operation, + BigInt(safeTransaction.data.safeTxGas), + BigInt(safeTransaction.data.baseGas), + BigInt(safeTransaction.data.gasPrice), + safeTransaction.data.gasToken, + safeTransaction.data.refundReceiver, + safeTransaction.encodedSignatures() + ], + options + )) + + return await this.contract.execTransaction.staticCall( + safeTransaction.data.to, + BigInt(safeTransaction.data.value), + safeTransaction.data.data, + safeTransaction.data.operation, + BigInt(safeTransaction.data.safeTxGas), + BigInt(safeTransaction.data.baseGas), + BigInt(safeTransaction.data.gasPrice), + safeTransaction.data.gasToken, + safeTransaction.data.refundReceiver, + safeTransaction.encodedSignatures(), + { ...options, gasLimit } + ) + } catch (error) { + return false + } + } + + /** + * returns the version of the Safe contract. + * + * @returns {Promise} A promise that resolves to the version of the Safe contract as string. + */ + async getVersion(): Promise { + const [safeVersion] = await this.VERSION() + return safeVersion as SafeVersion + } + + /** + * returns the nonce of the Safe contract. + * + * @returns {Promise} A promise that resolves to the nonce of the Safe contract. + */ + async getNonce(): Promise { + const [nonce] = await this.nonce() + return nonce + } +} + +export default SafeContract_v1_0_0 diff --git a/packages/protocol-kit/src/contracts/Safe/v1.1.1/SafeContract_v1_1_1.ts b/packages/protocol-kit/src/contracts/Safe/v1.1.1/SafeContract_v1_1_1.ts new file mode 100644 index 000000000..970eb6b5a --- /dev/null +++ b/packages/protocol-kit/src/contracts/Safe/v1.1.1/SafeContract_v1_1_1.ts @@ -0,0 +1,318 @@ +import SafeBaseContract from '@safe-global/protocol-kit/contracts/Safe/SafeBaseContract' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' +import { toTxResult } from '@safe-global/protocol-kit/contracts/utils' +import { sameString } from '@safe-global/protocol-kit/utils' +import { + SafeVersion, + SafeContract_v1_1_1_Abi, + SafeContract_v1_1_1_Contract, + SafeContract_v1_1_1_Function, + SafeTransaction, + safe_1_1_1_ContractArtifacts, + TransactionOptions, + TransactionResult +} from '@safe-global/safe-core-sdk-types' + +/** + * SafeContract_v1_1_1 is the implementation specific to the Safe contract version 1.1.1. + * + * This class specializes in handling interactions with the Safe contract version 1.1.1 using Ethers.js v6. + * + * @extends SafeBaseContract - Inherits from SafeBaseContract with ABI specific to Safe contract version 1.1.1. + * @implements SafeContract_v1_1_1_Contract - Implements the interface specific to Safe contract version 1.1.1. + */ +class SafeContract_v1_1_1 + extends SafeBaseContract + implements SafeContract_v1_1_1_Contract +{ + safeVersion: SafeVersion + + /** + * Constructs an instance of SafeContract_v1_1_1 + * + * @param chainId - The chain ID where the contract resides. + * @param safeProvider - An instance of SafeProvider. + * @param isL1SafeSingleton - A flag indicating if the contract is a L1 Safe Singleton. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the Safe deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the default ABI for version 1.1.1 is used. + */ + constructor( + chainId: bigint, + safeProvider: SafeProvider, + isL1SafeSingleton = false, + customContractAddress?: string, + customContractAbi?: SafeContract_v1_1_1_Abi + ) { + const safeVersion = '1.1.1' + const defaultAbi = safe_1_1_1_ContractArtifacts.abi + + super( + chainId, + safeProvider, + defaultAbi, + safeVersion, + isL1SafeSingleton, + customContractAddress, + customContractAbi + ) + + this.safeVersion = safeVersion + } + + /** + * @returns Array[contractName] + */ + NAME: SafeContract_v1_1_1_Function<'NAME'> = async () => { + return [await this.contract.NAME()] + } + + /** + * @returns Array[safeContractVersion] + */ + VERSION: SafeContract_v1_1_1_Function<'VERSION'> = async () => { + return [await this.contract.VERSION()] + } + + /** + * @param args - Array[owner, txHash] + * @returns Array[approvedHashes] + */ + approvedHashes: SafeContract_v1_1_1_Function<'approvedHashes'> = async (args) => { + return [await this.contract.approvedHashes(...args)] + } + + /** + * @returns Array[domainSeparator] + */ + domainSeparator: SafeContract_v1_1_1_Function<'domainSeparator'> = async () => { + return [await this.contract.domainSeparator()] + } + + /** + * Returns array of first 10 modules. + * @returns Array[Array[modules]] + */ + getModules: SafeContract_v1_1_1_Function<'getModules'> = async () => { + return [await this.contract.getModules()] + } + + /** + * Returns array of modules. + * @param args - Array[start, pageSize] + * @returns Array[Array[modules], next] + */ + getModulesPaginated: SafeContract_v1_1_1_Function<'getModulesPaginated'> = async (args) => { + const res = await this.contract.getModulesPaginated(...args) + return [res.array, res.next] + } + + /** + * Returns the list of Safe owner accounts. + * @returns Array[Array[owners]] + */ + getOwners: SafeContract_v1_1_1_Function<'getOwners'> = async () => { + return [await this.contract.getOwners()] + } + + /** + * Returns the Safe threshold. + * @returns Array[threshold] + */ + getThreshold: SafeContract_v1_1_1_Function<'getThreshold'> = async () => { + return [await this.contract.getThreshold()] + } + + /** + * Checks if a specific address is an owner of the current Safe. + * @param args - Array[address] + * @returns Array[isOwner] + */ + isOwner: SafeContract_v1_1_1_Function<'isOwner'> = async (args) => { + return [await this.contract.isOwner(...args)] + } + + /** + * Returns the Safe nonce. + * @returns Array[nonce] + */ + nonce: SafeContract_v1_1_1_Function<'nonce'> = async () => { + return [await this.contract.nonce()] + } + + /** + * @param args - Array[messageHash] + * @returns Array[signedMessages] + */ + signedMessages: SafeContract_v1_1_1_Function<'signedMessages'> = async (args) => { + return [await this.contract.signedMessages(...args)] + } + + /** + * Returns hash of a message that can be signed by owners. + * @param args - Array[message] + * @returns Array[messageHash] + */ + getMessageHash: SafeContract_v1_1_1_Function<'getMessageHash'> = async (args) => { + return [await this.contract.getMessageHash(...args)] + } + + /** + * Returns the bytes that are hashed to be signed by owners. + * @param args - Array[to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce] + * @returns Array[encodedData] + */ + encodeTransactionData: SafeContract_v1_1_1_Function<'encodeTransactionData'> = async (args) => { + return [await this.contract.encodeTransactionData(...args)] + } + + /** + * Returns hash to be signed by owners. + * @param args - Array[to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce] + * @returns Array[transactionHash] + */ + getTransactionHash: SafeContract_v1_1_1_Function<'getTransactionHash'> = async (args) => { + return [await this.contract.getTransactionHash(...args)] + } + + /** + * Marks a hash as approved. This can be used to validate a hash that is used by a signature. + * @param hash - The hash that should be marked as approved for signatures that are verified by this contract. + * @param options - Optional transaction options. + * @returns Transaction result. + */ + async approveHash(hash: string, options?: TransactionOptions): Promise { + const gasLimit = options?.gasLimit || (await this.estimateGas('approveHash', [hash], options)) + const txResponse = await this.contract.approveHash(hash, { ...options, gasLimit }) + + return toTxResult(txResponse, options) + } + + /** + * Executes a transaction. + * @param safeTransaction - The Safe transaction to execute. + * @param options - Transaction options. + * @returns Transaction result. + */ + async execTransaction( + safeTransaction: SafeTransaction, + options?: TransactionOptions + ): Promise { + const gasLimit = + options?.gasLimit || + (await this.estimateGas( + 'execTransaction', + [ + safeTransaction.data.to, + BigInt(safeTransaction.data.value), + safeTransaction.data.data, + safeTransaction.data.operation, + BigInt(safeTransaction.data.safeTxGas), + BigInt(safeTransaction.data.baseGas), + BigInt(safeTransaction.data.gasPrice), + safeTransaction.data.gasToken, + safeTransaction.data.refundReceiver, + safeTransaction.encodedSignatures() + ], + options + )) + + const txResponse = await this.contract.execTransaction( + safeTransaction.data.to, + safeTransaction.data.value, + safeTransaction.data.data, + safeTransaction.data.operation, + safeTransaction.data.safeTxGas, + safeTransaction.data.baseGas, + safeTransaction.data.gasPrice, + safeTransaction.data.gasToken, + safeTransaction.data.refundReceiver, + safeTransaction.encodedSignatures(), + { ...options, gasLimit } + ) + + return toTxResult(txResponse, options) + } + + /** + * Checks if a specific Safe module is enabled for the current Safe. + * @param moduleAddress - The module address to check. + * @returns True, if the module with the given address is enabled. + */ + async isModuleEnabled([moduleAddress]: [string]): Promise<[boolean]> { + const [modules] = await this.getModules() + const isModuleEnabled = modules.some((enabledModuleAddress) => + sameString(enabledModuleAddress, moduleAddress) + ) + return [isModuleEnabled] + } + + /** + * Checks whether a given Safe transaction can be executed successfully with no errors. + * @param safeTransaction - The Safe transaction to check. + * @param options - Optional transaction options. + * @returns True, if the given transactions is valid. + */ + async isValidTransaction( + safeTransaction: SafeTransaction, + options: TransactionOptions = {} + ): Promise { + try { + const gasLimit = + options?.gasLimit || + (await this.estimateGas( + 'execTransaction', + [ + safeTransaction.data.to, + BigInt(safeTransaction.data.value), + safeTransaction.data.data, + safeTransaction.data.operation, + BigInt(safeTransaction.data.safeTxGas), + BigInt(safeTransaction.data.baseGas), + BigInt(safeTransaction.data.gasPrice), + safeTransaction.data.gasToken, + safeTransaction.data.refundReceiver, + safeTransaction.encodedSignatures() + ], + options + )) + + return await this.contract.execTransaction.staticCall( + safeTransaction.data.to, + BigInt(safeTransaction.data.value), + safeTransaction.data.data, + safeTransaction.data.operation, + BigInt(safeTransaction.data.safeTxGas), + BigInt(safeTransaction.data.baseGas), + BigInt(safeTransaction.data.gasPrice), + safeTransaction.data.gasToken, + safeTransaction.data.refundReceiver, + safeTransaction.encodedSignatures(), + { ...options, gasLimit } + ) + } catch (error) { + return false + } + } + + /** + * returns the version of the Safe contract. + * + * @returns {Promise} A promise that resolves to the version of the Safe contract as string. + */ + async getVersion(): Promise { + const [safeVersion] = await this.VERSION() + return safeVersion as SafeVersion + } + + /** + * returns the nonce of the Safe contract. + * + * @returns {Promise} A promise that resolves to the nonce of the Safe contract. + */ + async getNonce(): Promise { + const [nonce] = await this.nonce() + return nonce + } +} + +export default SafeContract_v1_1_1 diff --git a/packages/protocol-kit/src/contracts/Safe/v1.2.0/SafeContract_v1_2_0.ts b/packages/protocol-kit/src/contracts/Safe/v1.2.0/SafeContract_v1_2_0.ts new file mode 100644 index 000000000..e6f130ad6 --- /dev/null +++ b/packages/protocol-kit/src/contracts/Safe/v1.2.0/SafeContract_v1_2_0.ts @@ -0,0 +1,319 @@ +import SafeBaseContract from '@safe-global/protocol-kit/contracts/Safe/SafeBaseContract' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' +import { toTxResult } from '@safe-global/protocol-kit/contracts/utils' +import { + SafeVersion, + SafeContract_v1_2_0_Abi, + SafeContract_v1_2_0_Contract, + SafeContract_v1_2_0_Function, + SafeTransaction, + safe_1_2_0_ContractArtifacts, + TransactionOptions, + TransactionResult +} from '@safe-global/safe-core-sdk-types' + +/** + * SafeContract_v1_2_0 is the implementation specific to the Safe contract version 1.2.0. + * + * This class specializes in handling interactions with the Safe contract version 1.2.0 using Ethers.js v6. + * + * @extends SafeBaseContract - Inherits from SafeBaseContract with ABI specific to Safe contract version 1.2.0. + * @implements SafeContract_v1_2_0_Contract - Implements the interface specific to Safe contract version 1.2.0. + */ +class SafeContract_v1_2_0 + extends SafeBaseContract + implements SafeContract_v1_2_0_Contract +{ + safeVersion: SafeVersion + + /** + * Constructs an instance of SafeContract_v1_2_0 + * + * @param chainId - The chain ID where the contract resides. + * @param safeProvider - An instance of SafeProvider. + * @param isL1SafeSingleton - A flag indicating if the contract is a L1 Safe Singleton. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the Safe deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the default ABI for version 1.2.0 is used. + */ + constructor( + chainId: bigint, + safeProvider: SafeProvider, + isL1SafeSingleton = false, + customContractAddress?: string, + customContractAbi?: SafeContract_v1_2_0_Abi + ) { + const safeVersion = '1.2.0' + const defaultAbi = safe_1_2_0_ContractArtifacts.abi + + super( + chainId, + safeProvider, + defaultAbi, + safeVersion, + isL1SafeSingleton, + customContractAddress, + customContractAbi + ) + + this.safeVersion = safeVersion + } + + /** + * @returns Array[contractName] + */ + NAME: SafeContract_v1_2_0_Function<'NAME'> = async () => { + return [await this.contract.NAME()] + } + + /** + * @returns Array[safeContractVersion] + */ + VERSION: SafeContract_v1_2_0_Function<'VERSION'> = async () => { + return [await this.contract.VERSION()] + } + + /** + * @param args - Array[owner, txHash] + * @returns Array[approvedHashes] + */ + approvedHashes: SafeContract_v1_2_0_Function<'approvedHashes'> = async (args) => { + return [await this.contract.approvedHashes(...args)] + } + + /** + * @returns Array[domainSeparator] + */ + domainSeparator: SafeContract_v1_2_0_Function<'domainSeparator'> = async () => { + return [await this.contract.domainSeparator()] + } + + /** + * Returns array of first 10 modules. + * @returns Array[Array[modules]] + */ + getModules: SafeContract_v1_2_0_Function<'getModules'> = async () => { + return [await this.contract.getModules()] + } + + /** + * Returns array of modules. + * @param args - Array[start, pageSize] + * @returns Array[Array[modules], next] + */ + getModulesPaginated: SafeContract_v1_2_0_Function<'getModulesPaginated'> = async (args) => { + const res = await this.contract.getModulesPaginated(...args) + return [res.array, res.next] + } + + /** + * Returns the list of Safe owner accounts. + * @returns Array[Array[owners]] + */ + getOwners: SafeContract_v1_2_0_Function<'getOwners'> = async () => { + return [await this.contract.getOwners()] + } + + /** + * Returns the Safe threshold. + * @returns Array[threshold] + */ + getThreshold: SafeContract_v1_2_0_Function<'getThreshold'> = async () => { + return [await this.contract.getThreshold()] + } + + /** + * Checks if a specific Safe module is enabled for the current Safe. + * @param args - Array[moduleAddress] + * @returns Array[isEnabled] + */ + isModuleEnabled: SafeContract_v1_2_0_Function<'isModuleEnabled'> = async (args) => { + return [await this.contract.isModuleEnabled(...args)] + } + + /** + * Checks if a specific address is an owner of the current Safe. + * @param args - Array[address] + * @returns Array[isOwner] + */ + isOwner: SafeContract_v1_2_0_Function<'isOwner'> = async (args) => { + return [await this.contract.isOwner(...args)] + } + + /** + * Returns the Safe nonce. + * @returns Array[nonce] + */ + nonce: SafeContract_v1_2_0_Function<'nonce'> = async () => { + return [await this.contract.nonce()] + } + + /** + * @param args - Array[messageHash] + * @returns Array[signedMessages] + */ + signedMessages: SafeContract_v1_2_0_Function<'signedMessages'> = async (args) => { + return [await this.contract.signedMessages(...args)] + } + + /** + * @param args - Array[message] + * @returns Array[messageHash] + */ + getMessageHash: SafeContract_v1_2_0_Function<'getMessageHash'> = async (args) => { + return [await this.contract.getMessageHash(...args)] + } + + /** + * Encodes the data for a transaction to the Safe contract. + * + * @param args - Array[to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce] + * @returns Array[encodedData] + */ + encodeTransactionData: SafeContract_v1_2_0_Function<'encodeTransactionData'> = async (args) => { + return [await this.contract.encodeTransactionData(...args)] + } + + /** + * Returns hash to be signed by owners. + * + * @param args - Array[to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce] + * @returns Array[transactionHash] + */ + getTransactionHash: SafeContract_v1_2_0_Function<'getTransactionHash'> = async (args) => { + return [await this.contract.getTransactionHash(...args)] + } + + /** + * Marks a hash as approved. This can be used to validate a hash that is used by a signature. + * @param hash - The hash that should be marked as approved for signatures that are verified by this contract. + * @param options - Optional transaction options. + * @returns Transaction result. + */ + async approveHash(hash: string, options?: TransactionOptions): Promise { + const gasLimit = options?.gasLimit || (await this.estimateGas('approveHash', [hash], options)) + const txResponse = await this.contract.approveHash(hash, { ...options, gasLimit }) + + return toTxResult(txResponse, options) + } + + /** + * Executes a transaction. + * @param safeTransaction - The Safe transaction to execute. + * @param options - Transaction options. + * @returns Transaction result. + */ + async execTransaction( + safeTransaction: SafeTransaction, + options?: TransactionOptions + ): Promise { + const gasLimit = + options?.gasLimit || + (await this.estimateGas( + 'execTransaction', + [ + safeTransaction.data.to, + BigInt(safeTransaction.data.value), + safeTransaction.data.data, + safeTransaction.data.operation, + BigInt(safeTransaction.data.safeTxGas), + BigInt(safeTransaction.data.baseGas), + BigInt(safeTransaction.data.gasPrice), + safeTransaction.data.gasToken, + safeTransaction.data.refundReceiver, + safeTransaction.encodedSignatures() + ], + options + )) + + const txResponse = await this.contract.execTransaction( + safeTransaction.data.to, + safeTransaction.data.value, + safeTransaction.data.data, + safeTransaction.data.operation, + safeTransaction.data.safeTxGas, + safeTransaction.data.baseGas, + safeTransaction.data.gasPrice, + safeTransaction.data.gasToken, + safeTransaction.data.refundReceiver, + safeTransaction.encodedSignatures(), + { ...options, gasLimit } + ) + + return toTxResult(txResponse, options) + } + + /** + * Returns the chain id of the Safe contract. (Custom method - not defined in the Safe Contract) + * @returns Array[chainId] + */ + async getChainId(): Promise<[bigint]> { + return [await this.contract.getChainId()] + } + + /** + * Checks whether a given Safe transaction can be executed successfully with no errors. + * @param safeTransaction - The Safe transaction to check. + * @param options - Optional transaction options. + * @returns True, if the given transactions is valid. + */ + async isValidTransaction(safeTransaction: SafeTransaction, options: TransactionOptions = {}) { + try { + const gasLimit = + options?.gasLimit || + (await this.estimateGas( + 'execTransaction', + [ + safeTransaction.data.to, + BigInt(safeTransaction.data.value), + safeTransaction.data.data, + safeTransaction.data.operation, + BigInt(safeTransaction.data.safeTxGas), + BigInt(safeTransaction.data.baseGas), + BigInt(safeTransaction.data.gasPrice), + safeTransaction.data.gasToken, + safeTransaction.data.refundReceiver, + safeTransaction.encodedSignatures() + ], + options + )) + + return await this.contract.execTransaction.staticCall( + safeTransaction.data.to, + BigInt(safeTransaction.data.value), + safeTransaction.data.data, + safeTransaction.data.operation, + BigInt(safeTransaction.data.safeTxGas), + BigInt(safeTransaction.data.baseGas), + BigInt(safeTransaction.data.gasPrice), + safeTransaction.data.gasToken, + safeTransaction.data.refundReceiver, + safeTransaction.encodedSignatures(), + { ...options, gasLimit } + ) + } catch (error) { + return false + } + } + + /** + * returns the version of the Safe contract. + * + * @returns {Promise} A promise that resolves to the version of the Safe contract as string. + */ + async getVersion(): Promise { + const [safeVersion] = await this.VERSION() + return safeVersion as SafeVersion + } + + /** + * returns the nonce of the Safe contract. + * + * @returns {Promise} A promise that resolves to the nonce of the Safe contract. + */ + async getNonce(): Promise { + const [nonce] = await this.nonce() + return nonce + } +} + +export default SafeContract_v1_2_0 diff --git a/packages/protocol-kit/src/contracts/Safe/v1.3.0/SafeContract_v1_3_0.ts b/packages/protocol-kit/src/contracts/Safe/v1.3.0/SafeContract_v1_3_0.ts new file mode 100644 index 000000000..66d48071e --- /dev/null +++ b/packages/protocol-kit/src/contracts/Safe/v1.3.0/SafeContract_v1_3_0.ts @@ -0,0 +1,333 @@ +import SafeBaseContract from '@safe-global/protocol-kit/contracts/Safe/SafeBaseContract' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' +import { toTxResult } from '@safe-global/protocol-kit/contracts/utils' +import { SENTINEL_ADDRESS } from '@safe-global/protocol-kit/utils/constants' +import { + SafeVersion, + SafeContract_v1_3_0_Abi, + SafeContract_v1_3_0_Contract, + SafeContract_v1_3_0_Function, + SafeTransaction, + safe_1_3_0_ContractArtifacts, + TransactionOptions, + TransactionResult +} from '@safe-global/safe-core-sdk-types' +/** + * SafeContract_v1_3_0 is the implementation specific to the Safe contract version 1.3.0. + * + * This class specializes in handling interactions with the Safe contract version 1.3.0 using Ethers.js v6. + * + * @extends SafeBaseContract - Inherits from SafeBaseContract with ABI specific to Safe contract version 1.3.0. + * @implements SafeContract_v1_3_0_Contract - Implements the interface specific to Safe contract version 1.3.0. + */ +class SafeContract_v1_3_0 + extends SafeBaseContract + implements SafeContract_v1_3_0_Contract +{ + safeVersion: SafeVersion + + /** + * Constructs an instance of SafeContract_v1_3_0 + * + * @param chainId - The chain ID where the contract resides. + * @param safeProvider - An instance of SafeProvider. + * @param isL1SafeSingleton - A flag indicating if the contract is a L1 Safe Singleton. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the Safe deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the default ABI for version 1.3.0 is used. + */ + constructor( + chainId: bigint, + safeProvider: SafeProvider, + isL1SafeSingleton = false, + customContractAddress?: string, + customContractAbi?: SafeContract_v1_3_0_Abi + ) { + const safeVersion = '1.3.0' + const defaultAbi = safe_1_3_0_ContractArtifacts.abi + + super( + chainId, + safeProvider, + defaultAbi, + safeVersion, + isL1SafeSingleton, + customContractAddress, + customContractAbi + ) + + this.safeVersion = safeVersion + } + + /** + * @returns Array[safeContractVersion] + */ + VERSION: SafeContract_v1_3_0_Function<'VERSION'> = async () => { + return [await this.contract.VERSION()] + } + + /** + * @param args - Array[owner, txHash] + * @returns Array[approvedHashes] + */ + approvedHashes: SafeContract_v1_3_0_Function<'approvedHashes'> = async (args) => { + return [await this.contract.approvedHashes(...args)] + } + + /** + * Checks whether the signature provided is valid for the provided data, hash and number of required signatures. + * Will revert otherwise. + * @param args - Array[dataHash, data, signatures, requiredSignatures] + * @returns Empty array + */ + checkNSignatures: SafeContract_v1_3_0_Function<'checkNSignatures'> = async (args) => { + await this.contract.checkNSignatures(...args) + return [] + } + + /** + * Checks whether the signature provided is valid for the provided data and hash. Will revert otherwise. + * @param args - Array[dataHash, data, signatures] + * @returns Empty array + */ + checkSignatures: SafeContract_v1_3_0_Function<'checkSignatures'> = async (args) => { + await this.contract.checkSignatures(...args) + return [] + } + + /** + * @returns Array[domainSeparator] + */ + domainSeparator: SafeContract_v1_3_0_Function<'domainSeparator'> = async () => { + return [await this.contract.domainSeparator()] + } + + /** + * Encodes the data for a transaction to the Safe contract. + * @param args - Array[to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce] + * @returns Array[encodedData] + */ + encodeTransactionData: SafeContract_v1_3_0_Function<'encodeTransactionData'> = async (args) => { + return [await this.contract.encodeTransactionData(...args)] + } + + /** + * Returns array of modules. + * @param args - Array[start, pageSize] + * @returns Array[Array[modules], next] + */ + getModulesPaginated: SafeContract_v1_3_0_Function<'getModulesPaginated'> = async (args) => { + const res = await this.contract.getModulesPaginated(...args) + return [res.array, res.next] + } + + /** + * Returns the list of Safe owner accounts. + * @returns Array[Array[owners]] + */ + getOwners: SafeContract_v1_3_0_Function<'getOwners'> = async () => { + return [await this.contract.getOwners()] + } + + /** + * Reads `length` bytes of storage in the currents contract + * @param args - Array[offset, length] + * @returns Array[storage] + */ + getStorageAt: SafeContract_v1_3_0_Function<'getStorageAt'> = async (args) => { + return [await this.contract.getStorageAt(...args)] + } + + /** + * Returns the Safe threshold. + * @returns Array[threshold] + */ + getThreshold: SafeContract_v1_3_0_Function<'getThreshold'> = async () => { + return [await this.contract.getThreshold()] + } + + /** + * Returns hash to be signed by owners. + * @param args - Array[to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce] + * @returns Array[transactionHash] + */ + getTransactionHash: SafeContract_v1_3_0_Function<'getTransactionHash'> = async (args) => { + return [await this.contract.getTransactionHash(...args)] + } + + /** + * Checks if a specific Safe module is enabled for the current Safe. + * @param args - Array[moduleAddress] + * @returns Array[isEnabled] + */ + isModuleEnabled: SafeContract_v1_3_0_Function<'isModuleEnabled'> = async (args) => { + return [await this.contract.isModuleEnabled(...args)] + } + + /** + * Checks if a specific address is an owner of the current Safe. + * @param args - Array[address] + * @returns Array[isOwner] + */ + isOwner: SafeContract_v1_3_0_Function<'isOwner'> = async (args) => { + return [await this.contract.isOwner(...args)] + } + + /** + * Returns the Safe nonce. + * @returns Array[nonce] + */ + nonce: SafeContract_v1_3_0_Function<'nonce'> = async () => { + return [await this.contract.nonce()] + } + + /** + * @param args - Array[messageHash] + * @returns Array[signedMessages] + */ + signedMessages: SafeContract_v1_3_0_Function<'signedMessages'> = async (args) => { + return [await this.contract.signedMessages(...args)] + } + + /** + * Checks whether a given Safe transaction can be executed successfully with no errors. + * @param safeTransaction - The Safe transaction to check. + * @param options - Optional transaction options. + * @returns True, if the given transactions is valid. + */ + async isValidTransaction(safeTransaction: SafeTransaction, options: TransactionOptions = {}) { + try { + const gasLimit = + options?.gasLimit || + (await this.estimateGas( + 'execTransaction', + [ + safeTransaction.data.to, + BigInt(safeTransaction.data.value), + safeTransaction.data.data, + safeTransaction.data.operation, + BigInt(safeTransaction.data.safeTxGas), + BigInt(safeTransaction.data.baseGas), + BigInt(safeTransaction.data.gasPrice), + safeTransaction.data.gasToken, + safeTransaction.data.refundReceiver, + safeTransaction.encodedSignatures() + ], + options + )) + + return await this.contract.execTransaction.staticCall( + safeTransaction.data.to, + BigInt(safeTransaction.data.value), + safeTransaction.data.data, + safeTransaction.data.operation, + BigInt(safeTransaction.data.safeTxGas), + BigInt(safeTransaction.data.baseGas), + BigInt(safeTransaction.data.gasPrice), + safeTransaction.data.gasToken, + safeTransaction.data.refundReceiver, + safeTransaction.encodedSignatures(), + { ...options, gasLimit } + ) + } catch (error) { + return false + } + } + + /** + * Executes a transaction. + * @param safeTransaction - The Safe transaction to execute. + * @param options - Transaction options. + * @returns Transaction result. + */ + async execTransaction( + safeTransaction: SafeTransaction, + options?: TransactionOptions + ): Promise { + const gasLimit = + options?.gasLimit || + (await this.estimateGas( + 'execTransaction', + [ + safeTransaction.data.to, + BigInt(safeTransaction.data.value), + safeTransaction.data.data, + safeTransaction.data.operation, + BigInt(safeTransaction.data.safeTxGas), + BigInt(safeTransaction.data.baseGas), + BigInt(safeTransaction.data.gasPrice), + safeTransaction.data.gasToken, + safeTransaction.data.refundReceiver, + safeTransaction.encodedSignatures() + ], + options + )) + + const txResponse = await this.contract.execTransaction( + safeTransaction.data.to, + safeTransaction.data.value, + safeTransaction.data.data, + safeTransaction.data.operation, + safeTransaction.data.safeTxGas, + safeTransaction.data.baseGas, + safeTransaction.data.gasPrice, + safeTransaction.data.gasToken, + safeTransaction.data.refundReceiver, + safeTransaction.encodedSignatures(), + { ...options, gasLimit } + ) + + return toTxResult(txResponse, options) + } + + /** + * Returns array of first 10 modules. + * @returns Array[modules] + */ + async getModules(): Promise<[string[]]> { + const [modules] = await this.getModulesPaginated([SENTINEL_ADDRESS, BigInt(10)]) + return [modules.map((module) => module)] + } + + /** + * Marks a hash as approved. This can be used to validate a hash that is used by a signature. + * @param hash - The hash that should be marked as approved for signatures that are verified by this contract. + * @param options - Optional transaction options. + * @returns Transaction result. + */ + async approveHash(hash: string, options?: TransactionOptions): Promise { + const gasLimit = options?.gasLimit || (await this.estimateGas('approveHash', [hash], options)) + const txResponse = await this.contract.approveHash(hash, { ...options, gasLimit }) + + return toTxResult(txResponse, options) + } + + /** + * Returns the chain id of the Safe contract. (Custom method - not defined in the Safe Contract) + * @returns Array[chainId] + */ + async getChainId(): Promise<[bigint]> { + return [await this.contract.getChainId()] + } + + /** + * returns the version of the Safe contract. + * + * @returns {Promise} A promise that resolves to the version of the Safe contract as string. + */ + async getVersion(): Promise { + const [safeVersion] = await this.VERSION() + return safeVersion as SafeVersion + } + + /** + * returns the nonce of the Safe contract. + * + * @returns {Promise} A promise that resolves to the nonce of the Safe contract. + */ + async getNonce(): Promise { + const [nonce] = await this.nonce() + return nonce + } +} + +export default SafeContract_v1_3_0 diff --git a/packages/protocol-kit/src/contracts/Safe/v1.4.1/SafeContract_v1_4_1.ts b/packages/protocol-kit/src/contracts/Safe/v1.4.1/SafeContract_v1_4_1.ts new file mode 100644 index 000000000..c77c1131a --- /dev/null +++ b/packages/protocol-kit/src/contracts/Safe/v1.4.1/SafeContract_v1_4_1.ts @@ -0,0 +1,334 @@ +import SafeBaseContract from '@safe-global/protocol-kit/contracts/Safe/SafeBaseContract' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' +import { toTxResult } from '@safe-global/protocol-kit/contracts/utils' +import { SENTINEL_ADDRESS } from '@safe-global/protocol-kit/utils/constants' +import { + SafeVersion, + SafeContract_v1_4_1_Abi, + SafeContract_v1_4_1_Contract, + SafeContract_v1_4_1_Function, + SafeTransaction, + safe_1_4_1_ContractArtifacts, + TransactionOptions, + TransactionResult +} from '@safe-global/safe-core-sdk-types' + +/** + * SafeContract_v1_4_1 is the implementation specific to the Safe contract version 1.4.1. + * + * This class specializes in handling interactions with the Safe contract version 1.4.1 using Ethers.js v6. + * + * @extends SafeBaseContract - Inherits from SafeBaseContract with ABI specific to Safe contract version 1.4.1. + * @implements SafeContract_v1_4_1_Contract - Implements the interface specific to Safe contract version 1.4.1. + */ +class SafeContract_v1_4_1 + extends SafeBaseContract + implements SafeContract_v1_4_1_Contract +{ + safeVersion: SafeVersion + + /** + * Constructs an instance of SafeContract_v1_4_1 + * + * @param chainId - The chain ID where the contract resides. + * @param safeProvider - An instance of SafeProvider. + * @param isL1SafeSingleton - A flag indicating if the contract is a L1 Safe Singleton. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the Safe deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the default ABI for version 1.4.1 is used. + */ + constructor( + chainId: bigint, + safeProvider: SafeProvider, + isL1SafeSingleton = false, + customContractAddress?: string, + customContractAbi?: SafeContract_v1_4_1_Abi + ) { + const safeVersion = '1.4.1' + const defaultAbi = safe_1_4_1_ContractArtifacts.abi + + super( + chainId, + safeProvider, + defaultAbi, + safeVersion, + isL1SafeSingleton, + customContractAddress, + customContractAbi + ) + + this.safeVersion = safeVersion + } + + /** + * @returns Array[safeContractVersion] + */ + VERSION: SafeContract_v1_4_1_Function<'VERSION'> = async () => { + return [await this.contract.VERSION()] + } + + /** + * @param args - Array[owner, txHash] + * @returns Array[approvedHashes] + */ + approvedHashes: SafeContract_v1_4_1_Function<'approvedHashes'> = async (args) => { + return [await this.contract.approvedHashes(...args)] + } + + /** + * Checks whether the signature provided is valid for the provided data, hash and number of required signatures. + * Will revert otherwise. + * @param args - Array[dataHash, data, signatures, requiredSignatures] + * @returns Empty array + */ + checkNSignatures: SafeContract_v1_4_1_Function<'checkNSignatures'> = async (args) => { + await this.contract.checkNSignatures(...args) + return [] + } + + /** + * Checks whether the signature provided is valid for the provided data and hash. Will revert otherwise. + * @param args - Array[dataHash, data, signatures] + * @returns Empty array + */ + checkSignatures: SafeContract_v1_4_1_Function<'checkSignatures'> = async (args) => { + await this.contract.checkSignatures(...args) + return [] + } + + /** + * @returns Array[domainSeparator] + */ + domainSeparator: SafeContract_v1_4_1_Function<'domainSeparator'> = async () => { + return [await this.contract.domainSeparator()] + } + + /** + * Encodes the data for a transaction to the Safe contract. + * @param args - Array[to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce] + * @returns Array[encodedData] + */ + encodeTransactionData: SafeContract_v1_4_1_Function<'encodeTransactionData'> = async (args) => { + return [await this.contract.encodeTransactionData(...args)] + } + + /** + * Returns array of modules. + * @param args - Array[start, pageSize] + * @returns Array[Array[modules], next] + */ + getModulesPaginated: SafeContract_v1_4_1_Function<'getModulesPaginated'> = async (args) => { + const res = await this.contract.getModulesPaginated(...args) + return [res.array, res.next] + } + + /** + * Returns the list of Safe owner accounts. + * @returns Array[Array[owners]] + */ + getOwners: SafeContract_v1_4_1_Function<'getOwners'> = async () => { + return [await this.contract.getOwners()] + } + + /** + * Reads `length` bytes of storage in the currents contract + * @param args - Array[offset, length] + * @returns Array[storage] + */ + getStorageAt: SafeContract_v1_4_1_Function<'getStorageAt'> = async (args) => { + return [await this.contract.getStorageAt(...args)] + } + + /** + * Returns the Safe threshold. + * @returns Array[threshold] + */ + getThreshold: SafeContract_v1_4_1_Function<'getThreshold'> = async () => { + return [await this.contract.getThreshold()] + } + + /** + * Returns hash to be signed by owners. + * @param args - Array[to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce] + * @returns Array[transactionHash] + */ + getTransactionHash: SafeContract_v1_4_1_Function<'getTransactionHash'> = async (args) => { + return [await this.contract.getTransactionHash(...args)] + } + + /** + * Checks if a specific Safe module is enabled for the current Safe. + * @param args - Array[moduleAddress] + * @returns Array[isEnabled] + */ + isModuleEnabled: SafeContract_v1_4_1_Function<'isModuleEnabled'> = async (args) => { + return [await this.contract.isModuleEnabled(...args)] + } + + /** + * Checks if a specific address is an owner of the current Safe. + * @param args - Array[address] + * @returns Array[isOwner] + */ + isOwner: SafeContract_v1_4_1_Function<'isOwner'> = async (args) => { + return [await this.contract.isOwner(...args)] + } + + /** + * Returns the Safe nonce. + * @returns Array[nonce] + */ + nonce: SafeContract_v1_4_1_Function<'nonce'> = async () => { + return [await this.contract.nonce()] + } + + /** + * @param args - Array[messageHash] + * @returns Array[signedMessages] + */ + signedMessages: SafeContract_v1_4_1_Function<'signedMessages'> = async (args) => { + return [await this.contract.signedMessages(...args)] + } + + /** + * Checks whether a given Safe transaction can be executed successfully with no errors. + * @param safeTransaction - The Safe transaction to check. + * @param options - Optional transaction options. + * @returns True, if the given transactions is valid. + */ + async isValidTransaction(safeTransaction: SafeTransaction, options: TransactionOptions = {}) { + try { + const gasLimit = + options?.gasLimit || + (await this.estimateGas( + 'execTransaction', + [ + safeTransaction.data.to, + BigInt(safeTransaction.data.value), + safeTransaction.data.data, + safeTransaction.data.operation, + BigInt(safeTransaction.data.safeTxGas), + BigInt(safeTransaction.data.baseGas), + BigInt(safeTransaction.data.gasPrice), + safeTransaction.data.gasToken, + safeTransaction.data.refundReceiver, + safeTransaction.encodedSignatures() + ], + options + )) + + return await this.contract.execTransaction.staticCall( + safeTransaction.data.to, + BigInt(safeTransaction.data.value), + safeTransaction.data.data, + safeTransaction.data.operation, + BigInt(safeTransaction.data.safeTxGas), + BigInt(safeTransaction.data.baseGas), + BigInt(safeTransaction.data.gasPrice), + safeTransaction.data.gasToken, + safeTransaction.data.refundReceiver, + safeTransaction.encodedSignatures(), + { ...options, gasLimit } + ) + } catch (error) { + return false + } + } + + /** + * Executes a transaction. + * @param safeTransaction - The Safe transaction to execute. + * @param options - Transaction options. + * @returns Transaction result. + */ + async execTransaction( + safeTransaction: SafeTransaction, + options?: TransactionOptions + ): Promise { + const gasLimit = + options?.gasLimit || + (await this.estimateGas( + 'execTransaction', + [ + safeTransaction.data.to, + BigInt(safeTransaction.data.value), + safeTransaction.data.data, + safeTransaction.data.operation, + BigInt(safeTransaction.data.safeTxGas), + BigInt(safeTransaction.data.baseGas), + BigInt(safeTransaction.data.gasPrice), + safeTransaction.data.gasToken, + safeTransaction.data.refundReceiver, + safeTransaction.encodedSignatures() + ], + options + )) + + const txResponse = await this.contract.execTransaction( + safeTransaction.data.to, + safeTransaction.data.value, + safeTransaction.data.data, + safeTransaction.data.operation, + safeTransaction.data.safeTxGas, + safeTransaction.data.baseGas, + safeTransaction.data.gasPrice, + safeTransaction.data.gasToken, + safeTransaction.data.refundReceiver, + safeTransaction.encodedSignatures(), + { ...options, gasLimit } + ) + + return toTxResult(txResponse, options) + } + + /** + * Returns array of first 10 modules. + * @returns Array[modules] + */ + async getModules(): Promise<[string[]]> { + const [modules] = await this.getModulesPaginated([SENTINEL_ADDRESS, BigInt(10)]) + return [modules.map((module) => module)] + } + + /** + * Marks a hash as approved. This can be used to validate a hash that is used by a signature. + * @param hash - The hash that should be marked as approved for signatures that are verified by this contract. + * @param options - Optional transaction options. + * @returns Transaction result. + */ + async approveHash(hash: string, options?: TransactionOptions): Promise { + const gasLimit = options?.gasLimit || (await this.estimateGas('approveHash', [hash], options)) + const txResponse = await this.contract.approveHash(hash, { ...options, gasLimit }) + + return toTxResult(txResponse, options) + } + + /** + * Returns the chain id of the Safe contract. (Custom method - not defined in the Safe Contract) + * @returns Array[chainId] + */ + async getChainId(): Promise<[bigint]> { + return [await this.contract.getChainId()] + } + + /** + * returns the version of the Safe contract. + * + * @returns {Promise} A promise that resolves to the version of the Safe contract as string. + */ + async getVersion(): Promise { + const [safeVersion] = await this.VERSION() + return safeVersion as SafeVersion + } + + /** + * returns the nonce of the Safe contract. + * + * @returns {Promise} A promise that resolves to the nonce of the Safe contract. + */ + async getNonce(): Promise { + const [nonce] = await this.nonce() + return nonce + } +} + +export default SafeContract_v1_4_1 diff --git a/packages/protocol-kit/src/contracts/SafeProxyFactory/SafeProxyFactoryBaseContract.ts b/packages/protocol-kit/src/contracts/SafeProxyFactory/SafeProxyFactoryBaseContract.ts new file mode 100644 index 000000000..67d8c9e4e --- /dev/null +++ b/packages/protocol-kit/src/contracts/SafeProxyFactory/SafeProxyFactoryBaseContract.ts @@ -0,0 +1,74 @@ +import { Abi } from 'abitype' +import { ContractRunner, InterfaceAbi } from 'ethers' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' +import BaseContract from '@safe-global/protocol-kit/contracts/BaseContract' +import { + SafeVersion, + TransactionOptions, + CreateProxyProps as CreateProxyPropsGeneral +} from '@safe-global/safe-core-sdk-types' +import { contractName } from '@safe-global/protocol-kit/contracts/config' + +export interface CreateProxyProps extends CreateProxyPropsGeneral { + options?: TransactionOptions +} + +/** + * Abstract class SafeProxyFactoryBaseContract extends BaseContract to specifically integrate with the SafeProxyFactory contract. + * It is designed to be instantiated for different versions of the Safe contract. + * + * Subclasses of SafeProxyFactoryBaseContract are expected to represent specific versions of the contract. + * + * @template SafeProxyFactoryContractAbiType - The ABI type specific to the version of the Safe Proxy Factory contract, extending InterfaceAbi from Ethers. + * @extends BaseContract - Extends the generic BaseContract. + * + * Example subclasses: + * - SafeProxyFactoryContract_v1_4_1 extends SafeProxyFactoryBaseContract + * - SafeProxyFactoryContract_v1_3_0 extends SafeProxyFactoryBaseContract + * - SafeProxyFactoryContract_v1_2_0 extends SafeProxyFactoryBaseContract + * - SafeProxyFactoryContract_v1_1_1 extends SafeProxyFactoryBaseContract + * - SafeProxyFactoryContract_v1_0_0 extends SafeProxyFactoryBaseContract + */ +abstract class SafeProxyFactoryBaseContract< + SafeProxyFactoryContractAbiType extends InterfaceAbi & Abi +> extends BaseContract { + contractName: contractName + + /** + * @constructor + * Constructs an instance of SafeProxyFactoryBaseContract. + * + * @param chainId - The chain ID of the contract. + * @param safeProvider - An instance of SafeProvider. + * @param defaultAbi - The default ABI for the Safe contract. It should be compatible with the specific version of the contract. + * @param safeVersion - The version of the Safe contract. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the Safe deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the ABI is derived from the Safe deployments or the defaultAbi is used. + */ + constructor( + chainId: bigint, + safeProvider: SafeProvider, + defaultAbi: SafeProxyFactoryContractAbiType, + safeVersion: SafeVersion, + customContractAddress?: string, + customContractAbi?: SafeProxyFactoryContractAbiType, + runner?: ContractRunner | null + ) { + const contractName = 'safeProxyFactoryVersion' + + super( + contractName, + chainId, + safeProvider, + defaultAbi, + safeVersion, + customContractAddress, + customContractAbi, + runner + ) + + this.contractName = contractName + } +} + +export default SafeProxyFactoryBaseContract diff --git a/packages/protocol-kit/src/contracts/SafeProxyFactory/v1.0.0/SafeProxyFactoryContract_v1_0_0.ts b/packages/protocol-kit/src/contracts/SafeProxyFactory/v1.0.0/SafeProxyFactoryContract_v1_0_0.ts new file mode 100644 index 000000000..100e61e67 --- /dev/null +++ b/packages/protocol-kit/src/contracts/SafeProxyFactory/v1.0.0/SafeProxyFactoryContract_v1_0_0.ts @@ -0,0 +1,140 @@ +import { ContractRunner, EventLog } from 'ethers' +import SafeProxyFactoryBaseContract, { + CreateProxyProps +} from '@safe-global/protocol-kit/contracts/SafeProxyFactory/SafeProxyFactoryBaseContract' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' +import { + SafeVersion, + SafeProxyFactoryContract_v1_0_0_Abi, + SafeProxyFactoryContract_v1_0_0_Contract, + SafeProxyFactoryContract_v1_0_0_Function, + safeProxyFactory_1_0_0_ContractArtifacts +} from '@safe-global/safe-core-sdk-types' + +/** + * SafeProxyFactoryContract_v1_0_0 is the implementation specific to the Safe Proxy Factory contract version 1.0.0. + * + * This class specializes in handling interactions with the Safe Proxy Factory contract version 1.0.0 using Ethers.js v6. + * + * @extends SafeProxyFactoryBaseContract - Inherits from SafeProxyFactoryBaseContract with ABI specific to Safe Proxy Factory contract version 1.0.0. + * @implements SafeProxyFactoryContract_v1_0_0_Contract - Implements the interface specific to Safe Proxy Factory contract version 1.0.0. + */ +class SafeProxyFactoryContract_v1_0_0 + extends SafeProxyFactoryBaseContract + implements SafeProxyFactoryContract_v1_0_0_Contract +{ + safeVersion: SafeVersion + + /** + * Constructs an instance of SafeProxyFactoryContract_v1_0_0 + * + * @param chainId - The chain ID where the contract resides. + * @param safeProvider - An instance of SafeProvider. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the Safe deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the default ABI for version 1.0.0 is used. + */ + constructor( + chainId: bigint, + safeProvider: SafeProvider, + customContractAddress?: string, + customContractAbi?: SafeProxyFactoryContract_v1_0_0_Abi, + runner?: ContractRunner | null + ) { + const safeVersion = '1.0.0' + const defaultAbi = safeProxyFactory_1_0_0_ContractArtifacts.abi + + super( + chainId, + safeProvider, + defaultAbi, + safeVersion, + customContractAddress, + customContractAbi, + runner + ) + + this.safeVersion = safeVersion + } + + /** + * Allows to retrieve the creation code used for the Proxy deployment. With this it is easily possible to calculate predicted address. + * @returns Array[creationCode] + */ + proxyCreationCode: SafeProxyFactoryContract_v1_0_0_Function<'proxyCreationCode'> = async () => { + return [await this.contract.proxyCreationCode()] + } + + /** + * Allows to retrieve the runtime code of a deployed Proxy. This can be used to check that the expected Proxy was deployed. + * @returns Array[runtimeCode] + */ + proxyRuntimeCode: SafeProxyFactoryContract_v1_0_0_Function<'proxyRuntimeCode'> = async () => { + return [await this.contract.proxyRuntimeCode()] + } + + /** + * Allows to create new proxy contact and execute a message call to the new proxy within one transaction. + * @param args - Array[masterCopy, data] + * @returns Array[proxyAddress] + */ + createProxy: SafeProxyFactoryContract_v1_0_0_Function<'createProxy'> = async (args) => { + return [await this.contract.createProxy(...args)] + } + + /** + * Allows to create new proxy contract and execute a message call to the new proxy within one transaction. + * @param args - Array[masterCopy, initializer, saltNonce] + * @returns Array[proxyAddress] + */ + createProxyWithNonce: SafeProxyFactoryContract_v1_0_0_Function<'createProxyWithNonce'> = async ( + args + ) => { + return [await this.contract.createProxyWithNonce(...args)] + } + + /** + * Allows to create new proxy contract and execute a message call to the new proxy within one transaction. + * @param {CreateProxyProps} props - Properties for the new proxy contract. + * @returns The address of the new proxy contract. + */ + async createProxyWithOptions({ + safeSingletonAddress, + initializer, + saltNonce, + options, + callback + }: CreateProxyProps): Promise { + const saltNonceBigInt = BigInt(saltNonce) + + if (saltNonceBigInt < 0) throw new Error('saltNonce must be greater than or equal to 0') + + if (options && !options.gasLimit) { + options.gasLimit = ( + await this.estimateGas( + 'createProxyWithNonce', + [safeSingletonAddress, initializer, saltNonceBigInt], + { ...options } + ) + ).toString() + } + + const proxyAddress = this.contract + .createProxyWithNonce(safeSingletonAddress, initializer, saltNonce, { ...options }) + .then(async (txResponse) => { + if (callback) { + callback(txResponse.hash) + } + const txReceipt = await txResponse.wait() + const events = txReceipt?.logs as EventLog[] + const proxyCreationEvent = events.find((event) => event?.eventName === 'ProxyCreation') + if (!proxyCreationEvent || !proxyCreationEvent.args) { + throw new Error('SafeProxy was not deployed correctly') + } + const proxyAddress: string = proxyCreationEvent.args[0] + return proxyAddress + }) + return proxyAddress + } +} + +export default SafeProxyFactoryContract_v1_0_0 diff --git a/packages/protocol-kit/src/contracts/SafeProxyFactory/v1.1.1/SafeProxyFactoryContract_v1_1_1.ts b/packages/protocol-kit/src/contracts/SafeProxyFactory/v1.1.1/SafeProxyFactoryContract_v1_1_1.ts new file mode 100644 index 000000000..8cd499342 --- /dev/null +++ b/packages/protocol-kit/src/contracts/SafeProxyFactory/v1.1.1/SafeProxyFactoryContract_v1_1_1.ts @@ -0,0 +1,160 @@ +import { ContractRunner, EventLog } from 'ethers' +import SafeProxyFactoryBaseContract, { + CreateProxyProps +} from '@safe-global/protocol-kit/contracts/SafeProxyFactory/SafeProxyFactoryBaseContract' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' +import { + SafeVersion, + SafeProxyFactoryContract_v1_1_1_Abi, + SafeProxyFactoryContract_v1_1_1_Contract, + SafeProxyFactoryContract_v1_1_1_Function, + safeProxyFactory_1_1_1_ContractArtifacts +} from '@safe-global/safe-core-sdk-types' + +/** + * SafeProxyFactoryContract_v1_1_1 is the implementation specific to the Safe Proxy Factory contract version 1.1.1. + * + * This class specializes in handling interactions with the Safe Proxy Factory contract version 1.1.1 using Ethers.js v6. + * + * @extends SafeProxyFactoryBaseContract - Inherits from SafeProxyFactoryBaseContract with ABI specific to Safe Proxy Factory contract version 1.1.1. + * @implements SafeProxyFactoryContract_v1_1_1_Contract - Implements the interface specific to Safe Proxy Factory contract version 1.1.1. + */ +class SafeProxyFactoryContract_v1_1_1 + extends SafeProxyFactoryBaseContract + implements SafeProxyFactoryContract_v1_1_1_Contract +{ + safeVersion: SafeVersion + + /** + * Constructs an instance of SafeProxyFactoryContract_v1_1_1 + * + * @param chainId - The chain ID where the contract resides. + * @param safeProvider - An instance of SafeProvider. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the Safe deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the default ABI for version 1.1.1 is used. + */ + constructor( + chainId: bigint, + safeProvider: SafeProvider, + customContractAddress?: string, + customContractAbi?: SafeProxyFactoryContract_v1_1_1_Abi, + runner?: ContractRunner | null + ) { + const safeVersion = '1.1.1' + const defaultAbi = safeProxyFactory_1_1_1_ContractArtifacts.abi + + super( + chainId, + safeProvider, + defaultAbi, + safeVersion, + customContractAddress, + customContractAbi, + runner + ) + + this.safeVersion = safeVersion + } + + /** + * Allows to retrieve the creation code used for the Proxy deployment. With this it is easily possible to calculate predicted address. + * @returns Array[creationCode] + */ + proxyCreationCode: SafeProxyFactoryContract_v1_1_1_Function<'proxyCreationCode'> = async () => { + return [await this.contract.proxyCreationCode()] + } + + /** + * Allows to retrieve the runtime code of a deployed Proxy. This can be used to check that the expected Proxy was deployed. + * @returns Array[runtimeCode] + */ + proxyRuntimeCode: SafeProxyFactoryContract_v1_1_1_Function<'proxyRuntimeCode'> = async () => { + return [await this.contract.proxyRuntimeCode()] + } + + /** + * Allows to get the address for a new proxy contact created via `createProxyWithNonce`. + * @param args - Array[masterCopy, initializer, saltNonce] + * @returns Array[proxyAddress] + */ + calculateCreateProxyWithNonceAddress: SafeProxyFactoryContract_v1_1_1_Function<'calculateCreateProxyWithNonceAddress'> = + async (args) => { + return [await this.contract.calculateCreateProxyWithNonceAddress(...args)] + } + + /** + * Allows to create new proxy contact and execute a message call to the new proxy within one transaction. + * @param args - Array[masterCopy, data] + * @returns Array[proxyAddress] + */ + createProxy: SafeProxyFactoryContract_v1_1_1_Function<'createProxy'> = async (args) => { + return [await this.contract.createProxy(...args)] + } + + /** + * Allows to create new proxy contract, execute a message call to the new proxy and call a specified callback within one transaction. + * @param args - Array[masterCopy, initializer, saltNonce, callback] + * @returns Array[proxyAddress] + */ + createProxyWithCallback: SafeProxyFactoryContract_v1_1_1_Function<'createProxyWithCallback'> = + async (args) => { + return [await this.contract.createProxyWithCallback(...args)] + } + + /** + * Allows to create new proxy contract and execute a message call to the new proxy within one transaction. + * @param args - Array[masterCopy, initializer, saltNonce] + * @returns Array[proxyAddress] + */ + createProxyWithNonce: SafeProxyFactoryContract_v1_1_1_Function<'createProxyWithNonce'> = async ( + args + ) => { + return [await this.contract.createProxyWithNonce(...args)] + } + + /** + * Allows to create new proxy contract and execute a message call to the new proxy within one transaction. + * @param {CreateProxyProps} props - Properties for the new proxy contract. + * @returns The address of the new proxy contract. + */ + async createProxyWithOptions({ + safeSingletonAddress, + initializer, + saltNonce, + options, + callback + }: CreateProxyProps): Promise { + const saltNonceBigInt = BigInt(saltNonce) + + if (saltNonceBigInt < 0) throw new Error('saltNonce must be greater than or equal to 0') + + if (options && !options.gasLimit) { + options.gasLimit = ( + await this.estimateGas( + 'createProxyWithNonce', + [safeSingletonAddress, initializer, saltNonceBigInt], + { ...options } + ) + ).toString() + } + + const proxyAddress = this.contract + .createProxyWithNonce(safeSingletonAddress, initializer, saltNonce, { ...options }) + .then(async (txResponse) => { + if (callback) { + callback(txResponse.hash) + } + const txReceipt = await txResponse.wait() + const events = txReceipt?.logs as EventLog[] + const proxyCreationEvent = events.find((event) => event?.eventName === 'ProxyCreation') + if (!proxyCreationEvent || !proxyCreationEvent.args) { + throw new Error('SafeProxy was not deployed correctly') + } + const proxyAddress: string = proxyCreationEvent.args[0] + return proxyAddress + }) + return proxyAddress + } +} + +export default SafeProxyFactoryContract_v1_1_1 diff --git a/packages/protocol-kit/src/contracts/SafeProxyFactory/v1.3.0/SafeProxyFactoryContract_v1_3_0.ts b/packages/protocol-kit/src/contracts/SafeProxyFactory/v1.3.0/SafeProxyFactoryContract_v1_3_0.ts new file mode 100644 index 000000000..66ca7aabb --- /dev/null +++ b/packages/protocol-kit/src/contracts/SafeProxyFactory/v1.3.0/SafeProxyFactoryContract_v1_3_0.ts @@ -0,0 +1,160 @@ +import { ContractRunner, EventLog } from 'ethers' +import SafeProxyFactoryBaseContract, { + CreateProxyProps +} from '@safe-global/protocol-kit/contracts/SafeProxyFactory/SafeProxyFactoryBaseContract' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' +import { + SafeVersion, + SafeProxyFactoryContract_v1_3_0_Abi, + SafeProxyFactoryContract_v1_3_0_Contract, + SafeProxyFactoryContract_v1_3_0_Function, + safeProxyFactory_1_3_0_ContractArtifacts +} from '@safe-global/safe-core-sdk-types' + +/** + * SafeProxyFactoryContract_v1_3_0 is the implementation specific to the Safe Proxy Factory contract version 1.3.0. + * + * This class specializes in handling interactions with the Safe Proxy Factory contract version 1.3.0 using Ethers.js v6. + * + * @extends SafeProxyFactoryBaseContract - Inherits from SafeProxyFactoryBaseContract with ABI specific to Safe Proxy Factory contract version 1.3.0. + * @implements SafeProxyFactoryContract_v1_3_0_Contract - Implements the interface specific to Safe Proxy Factory contract version 1.3.0. + */ +class SafeProxyFactoryContract_v1_3_0 + extends SafeProxyFactoryBaseContract + implements SafeProxyFactoryContract_v1_3_0_Contract +{ + safeVersion: SafeVersion + + /** + * Constructs an instance of SafeProxyFactoryContract_v1_3_0 + * + * @param chainId - The chain ID where the contract resides. + * @param safeProvider - An instance of SafeProvider. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the Safe deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the default ABI for version 1.3.0 is used. + */ + constructor( + chainId: bigint, + safeProvider: SafeProvider, + customContractAddress?: string, + customContractAbi?: SafeProxyFactoryContract_v1_3_0_Abi, + runner?: ContractRunner | null + ) { + const safeVersion = '1.3.0' + const defaultAbi = safeProxyFactory_1_3_0_ContractArtifacts.abi + + super( + chainId, + safeProvider, + defaultAbi, + safeVersion, + customContractAddress, + customContractAbi, + runner + ) + + this.safeVersion = safeVersion + } + + /** + * Allows to retrieve the creation code used for the Proxy deployment. With this it is easily possible to calculate predicted address. + * @returns Array[creationCode] + */ + proxyCreationCode: SafeProxyFactoryContract_v1_3_0_Function<'proxyCreationCode'> = async () => { + return [await this.contract.proxyCreationCode()] + } + + /** + * Allows to retrieve the runtime code of a deployed Proxy. This can be used to check that the expected Proxy was deployed. + * @returns Array[runtimeCode] + */ + proxyRuntimeCode: SafeProxyFactoryContract_v1_3_0_Function<'proxyRuntimeCode'> = async () => { + return [await this.contract.proxyRuntimeCode()] + } + + /** + * Allows to get the address for a new proxy contact created via `createProxyWithNonce`. + * @param args - Array[singleton, initializer, saltNonce] + * @returns Array[proxyAddress] + */ + calculateCreateProxyWithNonceAddress: SafeProxyFactoryContract_v1_3_0_Function<'calculateCreateProxyWithNonceAddress'> = + async (args) => { + return [await this.contract.calculateCreateProxyWithNonceAddress(...args)] + } + + /** + * Allows to create new proxy contact and execute a message call to the new proxy within one transaction. + * @param args - Array[singleton, data] + * @returns Array[proxyAddress] + */ + createProxy: SafeProxyFactoryContract_v1_3_0_Function<'createProxy'> = async (args) => { + return [await this.contract.createProxy(...args)] + } + + /** + * Allows to create new proxy contract, execute a message call to the new proxy and call a specified callback within one transaction. + * @param args - Array[singleton, initializer, saltNonce, callback] + * @returns Array[proxyAddress] + */ + createProxyWithCallback: SafeProxyFactoryContract_v1_3_0_Function<'createProxyWithCallback'> = + async (args) => { + return [await this.contract.createProxyWithCallback(...args)] + } + + /** + * Allows to create new proxy contract and execute a message call to the new proxy within one transaction. + * @param args - Array[singleton, initializer, saltNonce] + * @returns Array[proxyAddress] + */ + createProxyWithNonce: SafeProxyFactoryContract_v1_3_0_Function<'createProxyWithNonce'> = async ( + args + ) => { + return [await this.contract.createProxyWithNonce(...args)] + } + + /** + * Allows to create new proxy contract and execute a message call to the new proxy within one transaction. + * @param {CreateProxyProps} props - Properties for the new proxy contract. + * @returns The address of the new proxy contract. + */ + async createProxyWithOptions({ + safeSingletonAddress, + initializer, + saltNonce, + options, + callback + }: CreateProxyProps): Promise { + const saltNonceBigInt = BigInt(saltNonce) + + if (saltNonceBigInt < 0) throw new Error('saltNonce must be greater than or equal to 0') + + if (options && !options.gasLimit) { + options.gasLimit = ( + await this.estimateGas( + 'createProxyWithNonce', + [safeSingletonAddress, initializer, saltNonceBigInt], + { ...options } + ) + ).toString() + } + + const proxyAddress = this.contract + .createProxyWithNonce(safeSingletonAddress, initializer, saltNonce, { ...options }) + .then(async (txResponse) => { + if (callback) { + callback(txResponse.hash) + } + const txReceipt = await txResponse.wait() + const events = txReceipt?.logs as EventLog[] + const proxyCreationEvent = events.find((event) => event?.eventName === 'ProxyCreation') + if (!proxyCreationEvent || !proxyCreationEvent.args) { + throw new Error('SafeProxy was not deployed correctly') + } + const proxyAddress: string = proxyCreationEvent.args[0] + return proxyAddress + }) + return proxyAddress + } +} + +export default SafeProxyFactoryContract_v1_3_0 diff --git a/packages/protocol-kit/src/contracts/SafeProxyFactory/v1.4.1/SafeProxyFactoryContract_v1_4_1.ts b/packages/protocol-kit/src/contracts/SafeProxyFactory/v1.4.1/SafeProxyFactoryContract_v1_4_1.ts new file mode 100644 index 000000000..425a11e26 --- /dev/null +++ b/packages/protocol-kit/src/contracts/SafeProxyFactory/v1.4.1/SafeProxyFactoryContract_v1_4_1.ts @@ -0,0 +1,152 @@ +import { ContractRunner, EventLog } from 'ethers' +import SafeProxyFactoryBaseContract, { + CreateProxyProps +} from '@safe-global/protocol-kit/contracts/SafeProxyFactory/SafeProxyFactoryBaseContract' +import { + SafeVersion, + SafeProxyFactoryContract_v1_4_1_Abi, + SafeProxyFactoryContract_v1_4_1_Contract, + SafeProxyFactoryContract_v1_4_1_Function, + safeProxyFactory_1_4_1_ContractArtifacts +} from '@safe-global/safe-core-sdk-types' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' + +/** + * SafeProxyFactoryContract_v1_4_1 is the implementation specific to the Safe Proxy Factory contract version 1.4.1. + * + * This class specializes in handling interactions with the Safe Proxy Factory contract version 1.4.1 using Ethers.js v6. + * + * @extends SafeProxyFactoryBaseContract - Inherits from SafeProxyFactoryBaseContract with ABI specific to Safe Proxy Factory contract version 1.4.1. + * @implements SafeProxyFactoryContract_v1_4_1_Contract - Implements the interface specific to Safe Proxy Factory contract version 1.4.1. + */ +class SafeProxyFactoryContract_v1_4_1 + extends SafeProxyFactoryBaseContract + implements SafeProxyFactoryContract_v1_4_1_Contract +{ + safeVersion: SafeVersion + + /** + * Constructs an instance of SafeProxyFactoryContract_v1_4_1 + * + * @param chainId - The chain ID where the contract resides. + * @param safeProvider - An instance of SafeProvider. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the Safe deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the default ABI for version 1.4.1 is used. + */ + constructor( + chainId: bigint, + safeProvider: SafeProvider, + customContractAddress?: string, + customContractAbi?: SafeProxyFactoryContract_v1_4_1_Abi, + runner?: ContractRunner | null + ) { + const safeVersion = '1.4.1' + const defaultAbi = safeProxyFactory_1_4_1_ContractArtifacts.abi + + super( + chainId, + safeProvider, + defaultAbi, + safeVersion, + customContractAddress, + customContractAbi, + runner + ) + + this.safeVersion = safeVersion + } + + /** + * Returns the ID of the chain the contract is currently deployed on. + * @returns Array[chainId] + */ + getChainId: SafeProxyFactoryContract_v1_4_1_Function<'getChainId'> = async () => { + return [await this.contract.getChainId()] + } + + /** + * Allows to retrieve the creation code used for the Proxy deployment. With this it is easily possible to calculate predicted address. + * @returns Array[creationCode] + */ + proxyCreationCode: SafeProxyFactoryContract_v1_4_1_Function<'proxyCreationCode'> = async () => { + return [await this.contract.proxyCreationCode()] + } + + /** + * Deploys a new chain-specific proxy with singleton and salt. Optionally executes an initializer call to a new proxy. + * @param args - Array[singleton, initializer, saltNonce] + * @returns Array[proxy] + */ + createChainSpecificProxyWithNonce: SafeProxyFactoryContract_v1_4_1_Function<'createChainSpecificProxyWithNonce'> = + async (args) => { + return [await this.contract.createChainSpecificProxyWithNonce(...args)] + } + + /** + * Deploy a new proxy with singleton and salt. + * Optionally executes an initializer call to a new proxy and calls a specified callback address. + * @param args - Array[singleton, initializer, saltNonce, callback] + * @returns Array[proxy] + */ + createProxyWithCallback: SafeProxyFactoryContract_v1_4_1_Function<'createProxyWithCallback'> = + async (args) => { + return [await this.contract.createProxyWithCallback(...args)] + } + + /** + * Deploys a new proxy with singleton and salt. Optionally executes an initializer call to a new proxy. + * @param args - Array[singleton, initializer, saltNonce] + * @returns Array[proxy] + */ + createProxyWithNonce: SafeProxyFactoryContract_v1_4_1_Function<'createProxyWithNonce'> = async ( + args + ) => { + return [await this.contract.createProxyWithNonce(...args)] + } + + /** + * Allows to create new proxy contract and execute a message call to the new proxy within one transaction. + * @param {CreateProxyProps} props - Properties for the new proxy contract. + * @returns The address of the new proxy contract. + */ + async createProxyWithOptions({ + safeSingletonAddress, + initializer, + saltNonce, + options, + callback + }: CreateProxyProps): Promise { + const saltNonceBigInt = BigInt(saltNonce) + + if (saltNonceBigInt < 0) throw new Error('saltNonce must be greater than or equal to 0') + + if (options && !options.gasLimit) { + options.gasLimit = ( + await this.estimateGas( + 'createProxyWithNonce', + [safeSingletonAddress, initializer, saltNonceBigInt], + { ...options } + ) + ).toString() + } + + const proxyAddress = this.contract + .createProxyWithNonce(safeSingletonAddress, initializer, saltNonce, { ...options }) + .then(async (txResponse) => { + if (callback) { + callback(txResponse.hash) + } + const txReceipt = await txResponse.wait() + const events = txReceipt?.logs as EventLog[] + const proxyCreationEvent = events.find((event) => event?.eventName === 'ProxyCreation') + if (!proxyCreationEvent || !proxyCreationEvent.args) { + throw new Error('SafeProxy was not deployed correctly') + } + const proxyAddress: string = proxyCreationEvent.args[0] + return proxyAddress + }) + return proxyAddress + } +} + +export default SafeProxyFactoryContract_v1_4_1 diff --git a/packages/protocol-kit/src/contracts/SignMessageLib/SignMessageLibBaseContract.ts b/packages/protocol-kit/src/contracts/SignMessageLib/SignMessageLibBaseContract.ts new file mode 100644 index 000000000..264019128 --- /dev/null +++ b/packages/protocol-kit/src/contracts/SignMessageLib/SignMessageLibBaseContract.ts @@ -0,0 +1,62 @@ +import { Abi } from 'abitype' +import { InterfaceAbi } from 'ethers' + +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' +import { SafeVersion } from '@safe-global/safe-core-sdk-types' +import BaseContract from '@safe-global/protocol-kit/contracts/BaseContract' +import { contractName } from '@safe-global/protocol-kit/contracts/config' + +/** + * Abstract class SignMessageLibBaseContract extends BaseContract to specifically integrate with the SignMessageLib contract. + * It is designed to be instantiated for different versions of the SignMessageLib contract. + * + * Subclasses of SignMessageLibBaseContract are expected to represent specific versions of the SignMessageLib contract. + * + * @template SignMessageLibContractAbiType - The ABI type specific to the version of the SignMessageLib contract, extending InterfaceAbi from Ethers. + * @extends BaseContract - Extends the generic BaseContract. + * + * Example subclasses: + * - SignMessageLibContract_v1_4_1 extends SignMessageLibBaseContract + * - SignMessageLibContract_v1_3_0 extends SignMessageLibBaseContract + */ +abstract class SignMessageLibBaseContract< + SignMessageLibContractAbiType extends InterfaceAbi & Abi +> extends BaseContract { + contractName: contractName + + /** + * @constructor + * Constructs an instance of SignMessageLibBaseContract. + * + * @param chainId - The chain ID of the contract. + * @param safeProvider - An instance of SafeProvider. + * @param defaultAbi - The default ABI for the SignMessageLib contract. It should be compatible with the specific version of the SignMessageLib contract. + * @param safeVersion - The version of the SignMessageLib contract. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the SignMessageLib deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the ABI is derived from the SignMessageLib deployments or the defaultAbi is used. + */ + constructor( + chainId: bigint, + safeProvider: SafeProvider, + defaultAbi: SignMessageLibContractAbiType, + safeVersion: SafeVersion, + customContractAddress?: string, + customContractAbi?: SignMessageLibContractAbiType + ) { + const contractName = 'signMessageLibVersion' + + super( + contractName, + chainId, + safeProvider, + defaultAbi, + safeVersion, + customContractAddress, + customContractAbi + ) + + this.contractName = contractName + } +} + +export default SignMessageLibBaseContract diff --git a/packages/protocol-kit/src/contracts/SignMessageLib/v1.3.0/SignMessageLibContract_v1_3_0.ts b/packages/protocol-kit/src/contracts/SignMessageLib/v1.3.0/SignMessageLibContract_v1_3_0.ts new file mode 100644 index 000000000..f506a61de --- /dev/null +++ b/packages/protocol-kit/src/contracts/SignMessageLib/v1.3.0/SignMessageLibContract_v1_3_0.ts @@ -0,0 +1,72 @@ +import { toTxResult } from '@safe-global/protocol-kit/contracts/utils' +import SignMessageLibBaseContract from '@safe-global/protocol-kit/contracts/SignMessageLib/SignMessageLibBaseContract' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' +import { + SafeVersion, + SafeContractFunction, + SignMessageLibContract_v1_3_0_Abi, + SignMessageLibContract_v1_3_0_Contract, + SignMessageLibContract_v1_3_0_Function, + signMessageLib_1_3_0_ContractArtifacts +} from '@safe-global/safe-core-sdk-types' + +/** + * SignMessageLibContract_v1_3_0 is the implementation specific to the SignMessageLib contract version 1.3.0. + * + * This class specializes in handling interactions with the SignMessageLib contract version 1.3.0 using Ethers.js v6. + * + * @extends SignMessageLibBaseContract - Inherits from SignMessageLibBaseContract with ABI specific to SignMessageLib contract version 1.3.0. + * @implements SignMessageLibContract_v1_3_0_Contract - Implements the interface specific to SignMessageLib contract version 1.3.0. + */ +class SignMessageLibContract_v1_3_0 + extends SignMessageLibBaseContract + implements SignMessageLibContract_v1_3_0_Contract +{ + safeVersion: SafeVersion + + /** + * Constructs an instance of SignMessageLibContract_v1_3_0 + * + * @param chainId - The chain ID where the contract resides. + * @param safeProvider - An instance of SafeProvider. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the SignMessageLib deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the default ABI for version 1.3.0 is used. + */ + constructor( + chainId: bigint, + safeProvider: SafeProvider, + customContractAddress?: string, + customContractAbi?: SignMessageLibContract_v1_3_0_Abi + ) { + const safeVersion = '1.3.0' + const defaultAbi = signMessageLib_1_3_0_ContractArtifacts.abi + + super(chainId, safeProvider, defaultAbi, safeVersion, customContractAddress, customContractAbi) + + this.safeVersion = safeVersion + } + /** + * @param args - Array[message] + */ + getMessageHash: SignMessageLibContract_v1_3_0_Function<'getMessageHash'> = async (args) => { + return [await this.contract.getMessageHash(...args)] + } + + /** + * @param args - Array[data] + */ + signMessage: SafeContractFunction = async ( + data, + options + ) => { + if (options && !options.gasLimit) { + options.gasLimit = Number(await this.estimateGas('signMessage', data, { ...options })) + } + + const txResponse = await this.contract.signMessage(data, { ...options }) + + return toTxResult(txResponse, options) + } +} + +export default SignMessageLibContract_v1_3_0 diff --git a/packages/protocol-kit/src/contracts/SignMessageLib/v1.4.1/SignMessageLibContract_v1_4_1.ts b/packages/protocol-kit/src/contracts/SignMessageLib/v1.4.1/SignMessageLibContract_v1_4_1.ts new file mode 100644 index 000000000..e00dc2183 --- /dev/null +++ b/packages/protocol-kit/src/contracts/SignMessageLib/v1.4.1/SignMessageLibContract_v1_4_1.ts @@ -0,0 +1,73 @@ +import { toTxResult } from '@safe-global/protocol-kit/contracts/utils' +import SignMessageLibBaseContract from '@safe-global/protocol-kit/contracts/SignMessageLib/SignMessageLibBaseContract' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' +import { + SafeVersion, + SafeContractFunction, + SignMessageLibContract_v1_4_1_Abi, + SignMessageLibContract_v1_4_1_Contract, + SignMessageLibContract_v1_4_1_Function, + signMessageLib_1_4_1_ContractArtifacts +} from '@safe-global/safe-core-sdk-types' + +/** + * SignMessageLibContract_v1_4_1 is the implementation specific to the SignMessageLib contract version 1.4.1. + * + * This class specializes in handling interactions with the SignMessageLib contract version 1.4.1 using Ethers.js v6. + * + * @extends SignMessageLibBaseContract - Inherits from SignMessageLibBaseContract with ABI specific to SignMessageLib contract version 1.4.1. + * @implements SignMessageLibContract_v1_4_1_Contract - Implements the interface specific to SignMessageLib contract version 1.4.1. + */ +class SignMessageLibContract_v1_4_1 + extends SignMessageLibBaseContract + implements SignMessageLibContract_v1_4_1_Contract +{ + safeVersion: SafeVersion + + /** + * Constructs an instance of SignMessageLibContract_v1_4_1 + * + * @param chainId - The chain ID where the contract resides. + * @param safeProvider - An instance of SafeProvider. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the SignMessageLib deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the default ABI for version 1.4.1 is used. + */ + constructor( + chainId: bigint, + safeProvider: SafeProvider, + customContractAddress?: string, + customContractAbi?: SignMessageLibContract_v1_4_1_Abi + ) { + const safeVersion = '1.4.1' + const defaultAbi = signMessageLib_1_4_1_ContractArtifacts.abi + + super(chainId, safeProvider, defaultAbi, safeVersion, customContractAddress, customContractAbi) + + this.safeVersion = safeVersion + } + + /** + * @param args - Array[message] + */ + getMessageHash: SignMessageLibContract_v1_4_1_Function<'getMessageHash'> = async (args) => { + return [await this.contract.getMessageHash(...args)] + } + + /** + * @param args - Array[data] + */ + signMessage: SafeContractFunction = async ( + data, + options + ) => { + if (options && !options.gasLimit) { + options.gasLimit = Number(await this.estimateGas('signMessage', data, { ...options })) + } + + const txResponse = await this.contract.signMessage(data, { ...options }) + + return toTxResult(txResponse, options) + } +} + +export default SignMessageLibContract_v1_4_1 diff --git a/packages/protocol-kit/src/contracts/SimulateTxAccessor/SimulateTxAccessorBaseContract.ts b/packages/protocol-kit/src/contracts/SimulateTxAccessor/SimulateTxAccessorBaseContract.ts new file mode 100644 index 000000000..1fda7217b --- /dev/null +++ b/packages/protocol-kit/src/contracts/SimulateTxAccessor/SimulateTxAccessorBaseContract.ts @@ -0,0 +1,64 @@ +import { Abi } from 'abitype' +import { ContractRunner, InterfaceAbi } from 'ethers' + +import BaseContract from '@safe-global/protocol-kit/contracts/BaseContract' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' +import { SafeVersion } from '@safe-global/safe-core-sdk-types' +import { contractName } from '@safe-global/protocol-kit/contracts/config' + +/** + * Abstract class SimulateTxAccessorBaseContract extends BaseContract to specifically integrate with the SimulateTxAccessor contract. + * It is designed to be instantiated for different versions of the Safe contract. + * + * Subclasses of SimulateTxAccessorBaseContract are expected to represent specific versions of the contract. + * + * @template SimulateTxAccessorContractAbiType - The ABI type specific to the version of the SimulateTxAccessor contract, extending InterfaceAbi from Ethers. + * @extends BaseContract - Extends the generic BaseContract. + * + * Example subclasses: + * - SimulateTxAccessorContract_v1_4_1 extends SimulateTxAccessorBaseContract + * - SimulateTxAccessorContract_v1_3_0 extends SimulateTxAccessorBaseContract + */ +abstract class SimulateTxAccessorBaseContract< + SimulateTxAccessorContractAbiType extends InterfaceAbi & Abi +> extends BaseContract { + contractName: contractName + + /** + * @constructor + * Constructs an instance of SimulateTxAccessorBaseContract. + * + * @param chainId - The chain ID of the contract. + * @param safeProvider - An instance of SafeProvider. + * @param defaultAbi - The default ABI for the SimulateTxAccessor contract. It should be compatible with the specific version of the contract. + * @param safeVersion - The version of the Safe contract. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the Safe deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the ABI is derived from the Safe deployments or the defaultAbi is used. + */ + constructor( + chainId: bigint, + safeProvider: SafeProvider, + defaultAbi: SimulateTxAccessorContractAbiType, + safeVersion: SafeVersion, + customContractAddress?: string, + customContractAbi?: SimulateTxAccessorContractAbiType, + runner?: ContractRunner | null + ) { + const contractName = 'simulateTxAccessorVersion' + + super( + contractName, + chainId, + safeProvider, + defaultAbi, + safeVersion, + customContractAddress, + customContractAbi, + runner + ) + + this.contractName = contractName + } +} + +export default SimulateTxAccessorBaseContract diff --git a/packages/protocol-kit/src/contracts/SimulateTxAccessor/v1.3.0/SimulateTxAccessorContract_v1_3_0.ts b/packages/protocol-kit/src/contracts/SimulateTxAccessor/v1.3.0/SimulateTxAccessorContract_v1_3_0.ts new file mode 100644 index 000000000..97d04b92a --- /dev/null +++ b/packages/protocol-kit/src/contracts/SimulateTxAccessor/v1.3.0/SimulateTxAccessorContract_v1_3_0.ts @@ -0,0 +1,56 @@ +import SimulateTxAccessorBaseContract from '@safe-global/protocol-kit/contracts/SimulateTxAccessor/SimulateTxAccessorBaseContract' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' +import { + SafeVersion, + simulateTxAccessor_1_3_0_ContractArtifacts, + SimulateTxAccessorContract_v1_3_0_Abi, + SimulateTxAccessorContract_v1_3_0_Contract, + SimulateTxAccessorContract_v1_3_0_Function +} from '@safe-global/safe-core-sdk-types' + +/** + * SimulateTxAccessorContract_v1_3_0 is the implementation specific to the SimulateTxAccessor contract version 1.3.0. + * + * This class specializes in handling interactions with the SimulateTxAccessor contract version 1.3.0 using Ethers.js v6. + * + * @extends SimulateTxAccessorBaseContract - Inherits from SimulateTxAccessorBaseContract with ABI specific to SimulateTxAccessor contract version 1.3.0. + * @implements SimulateTxAccessorContract_v1_3_0_Contract - Implements the interface specific to SimulateTxAccessor contract version 1.3.0. + */ +class SimulateTxAccessorContract_v1_3_0 + extends SimulateTxAccessorBaseContract + implements SimulateTxAccessorContract_v1_3_0_Contract +{ + safeVersion: SafeVersion + + /** + * Constructs an instance of SimulateTxAccessorContract_v1_3_0 + * + * @param chainId - The chain ID where the contract resides. + * @param safeProvider - An instance of SafeProvider. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the SimulateTxAccessor deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the default ABI for version 1.3.0 is used. + */ + constructor( + chainId: bigint, + safeProvider: SafeProvider, + customContractAddress?: string, + customContractAbi?: SimulateTxAccessorContract_v1_3_0_Abi + ) { + const safeVersion = '1.3.0' + const defaultAbi = simulateTxAccessor_1_3_0_ContractArtifacts.abi + + super(chainId, safeProvider, defaultAbi, safeVersion, customContractAddress, customContractAbi) + + this.safeVersion = safeVersion + } + + /** + * @param args - Array[to, value, data, operation] + * @returns Array[estimate, success, returnData] + */ + simulate: SimulateTxAccessorContract_v1_3_0_Function<'simulate'> = (args) => { + return this.contract.simulate(...args) + } +} + +export default SimulateTxAccessorContract_v1_3_0 diff --git a/packages/protocol-kit/src/contracts/SimulateTxAccessor/v1.4.1/SimulateTxAccessorContract_v1_4_1.ts b/packages/protocol-kit/src/contracts/SimulateTxAccessor/v1.4.1/SimulateTxAccessorContract_v1_4_1.ts new file mode 100644 index 000000000..294562199 --- /dev/null +++ b/packages/protocol-kit/src/contracts/SimulateTxAccessor/v1.4.1/SimulateTxAccessorContract_v1_4_1.ts @@ -0,0 +1,55 @@ +import SimulateTxAccessorBaseContract from '@safe-global/protocol-kit/contracts/SimulateTxAccessor/SimulateTxAccessorBaseContract' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' +import { + SafeVersion, + simulateTxAccessor_1_4_1_ContractArtifacts, + SimulateTxAccessorContract_v1_4_1_Abi, + SimulateTxAccessorContract_v1_4_1_Contract, + SimulateTxAccessorContract_v1_4_1_Function +} from '@safe-global/safe-core-sdk-types' +/** + * SimulateTxAccessorContract_v1_4_1 is the implementation specific to the SimulateTxAccessor contract version 1.4.1. + * + * This class specializes in handling interactions with the SimulateTxAccessor contract version 1.4.1 using Ethers.js v6. + * + * @extends SimulateTxAccessorBaseContract - Inherits from SimulateTxAccessorBaseContract with ABI specific to SimulateTxAccessor contract version 1.4.1. + * @implements SimulateTxAccessorContract_v1_4_1_Contract - Implements the interface specific to SimulateTxAccessor contract version 1.4.1. + */ +class SimulateTxAccessorContract_v1_4_1 + extends SimulateTxAccessorBaseContract + implements SimulateTxAccessorContract_v1_4_1_Contract +{ + safeVersion: SafeVersion + + /** + * Constructs an instance of SimulateTxAccessorContract_v1_4_1 + * + * @param chainId - The chain ID where the contract resides. + * @param safeProvider - An instance of SafeProvider. + * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the SimulateTxAccessor deployments based on the chainId and safeVersion. + * @param customContractAbi - Optional custom ABI for the contract. If not provided, the default ABI for version 1.4.1 is used. + */ + constructor( + chainId: bigint, + safeProvider: SafeProvider, + customContractAddress?: string, + customContractAbi?: SimulateTxAccessorContract_v1_4_1_Abi + ) { + const safeVersion = '1.4.1' + const defaultAbi = simulateTxAccessor_1_4_1_ContractArtifacts.abi + + super(chainId, safeProvider, defaultAbi, safeVersion, customContractAddress, customContractAbi) + + this.safeVersion = safeVersion + } + + /** + * @param args - Array[to, value, data, operation] + * @returns Array[estimate, success, returnData] + */ + simulate: SimulateTxAccessorContract_v1_4_1_Function<'simulate'> = (args) => { + return this.contract.simulate(...args) + } +} + +export default SimulateTxAccessorContract_v1_4_1 diff --git a/packages/protocol-kit/src/contracts/config.ts b/packages/protocol-kit/src/contracts/config.ts index c6e75ea02..585b62151 100644 --- a/packages/protocol-kit/src/contracts/config.ts +++ b/packages/protocol-kit/src/contracts/config.ts @@ -1,21 +1,37 @@ +import { + DeploymentFilter, + SingletonDeployment, + getCompatibilityFallbackHandlerDeployment, + getCreateCallDeployment, + getMultiSendCallOnlyDeployment, + getMultiSendDeployment, + getProxyFactoryDeployment, + getSafeL2SingletonDeployment, + getSafeSingletonDeployment, + getSignMessageLibDeployment, + getSimulateTxAccessorDeployment +} from '@safe-global/safe-deployments' import { SafeVersion } from '@safe-global/safe-core-sdk-types' export const DEFAULT_SAFE_VERSION: SafeVersion = '1.3.0' export const SAFE_BASE_VERSION: SafeVersion = '1.0.0' -type SafeDeploymentsVersions = { - [version: string]: { - safeSingletonVersion: string - safeSingletonL2Version?: string - safeProxyFactoryVersion: string - compatibilityFallbackHandler: string - multiSendVersion: string - multiSendCallOnlyVersion?: string - signMessageLibVersion?: string - createCallVersion?: string - } +type contractNames = { + safeSingletonVersion: string + safeSingletonL2Version?: string + safeProxyFactoryVersion: string + compatibilityFallbackHandler: string + multiSendVersion: string + multiSendCallOnlyVersion?: string + signMessageLibVersion?: string + createCallVersion?: string + simulateTxAccessorVersion?: string } +type SafeDeploymentsVersions = Record + +export type contractName = keyof contractNames + export const safeDeploymentsVersions: SafeDeploymentsVersions = { '1.4.1': { safeSingletonVersion: '1.4.1', @@ -25,7 +41,8 @@ export const safeDeploymentsVersions: SafeDeploymentsVersions = { multiSendVersion: '1.4.1', multiSendCallOnlyVersion: '1.4.1', signMessageLibVersion: '1.4.1', - createCallVersion: '1.4.1' + createCallVersion: '1.4.1', + simulateTxAccessorVersion: '1.4.1' }, '1.3.0': { safeSingletonVersion: '1.3.0', @@ -35,7 +52,8 @@ export const safeDeploymentsVersions: SafeDeploymentsVersions = { multiSendVersion: '1.3.0', multiSendCallOnlyVersion: '1.3.0', signMessageLibVersion: '1.3.0', - createCallVersion: '1.3.0' + createCallVersion: '1.3.0', + simulateTxAccessorVersion: '1.3.0' }, '1.2.0': { safeSingletonVersion: '1.2.0', @@ -72,3 +90,36 @@ export const safeDeploymentsVersions: SafeDeploymentsVersions = { export const safeDeploymentsL1ChainIds = [ 1n // Ethereum Mainnet ] + +const contractFunctions: Record< + contractName, + (filter?: DeploymentFilter) => SingletonDeployment | undefined +> = { + safeSingletonVersion: getSafeSingletonDeployment, + safeSingletonL2Version: getSafeL2SingletonDeployment, + safeProxyFactoryVersion: getProxyFactoryDeployment, + compatibilityFallbackHandler: getCompatibilityFallbackHandlerDeployment, + multiSendVersion: getMultiSendDeployment, + multiSendCallOnlyVersion: getMultiSendCallOnlyDeployment, + signMessageLibVersion: getSignMessageLibDeployment, + createCallVersion: getCreateCallDeployment, + simulateTxAccessorVersion: getSimulateTxAccessorDeployment +} + +export function getContractDeployment( + safeVersion: SafeVersion, + chainId: bigint, + contractName: contractName +) { + const contractVersion = safeDeploymentsVersions[safeVersion][contractName] + + const filters: DeploymentFilter = { + version: contractVersion, + network: chainId.toString(), + released: true + } + + const deployment = contractFunctions[contractName](filters) + + return deployment +} diff --git a/packages/protocol-kit/src/adapters/ethers/utils/constants.ts b/packages/protocol-kit/src/contracts/constants.ts similarity index 100% rename from packages/protocol-kit/src/adapters/ethers/utils/constants.ts rename to packages/protocol-kit/src/contracts/constants.ts diff --git a/packages/protocol-kit/src/contracts/contractInstances.ts b/packages/protocol-kit/src/contracts/contractInstances.ts new file mode 100644 index 000000000..4021c9bfb --- /dev/null +++ b/packages/protocol-kit/src/contracts/contractInstances.ts @@ -0,0 +1,413 @@ +import { JsonFragment, AbstractSigner, Provider } from 'ethers' +import { + SafeVersion, + SafeContract_v1_3_0_Abi, + SafeContract_v1_4_1_Abi, + SafeContract_v1_2_0_Abi, + SafeContract_v1_1_1_Abi, + SafeContract_v1_0_0_Abi, + CompatibilityFallbackHandlerContract_v1_4_1_Abi, + CompatibilityFallbackHandlerContract_v1_3_0_Abi, + MultiSendContract_v1_4_1_Abi, + MultiSendContract_v1_3_0_Abi, + MultiSendContract_v1_1_1_Abi, + MultiSendCallOnlyContract_v1_4_1_Abi, + MultiSendCallOnlyContract_v1_3_0_Abi, + SafeProxyFactoryContract_v1_4_1_Abi, + SafeProxyFactoryContract_v1_3_0_Abi, + SafeProxyFactoryContract_v1_1_1_Abi, + SafeProxyFactoryContract_v1_0_0_Abi, + SignMessageLibContract_v1_4_1_Abi, + SignMessageLibContract_v1_3_0_Abi, + CreateCallContract_v1_4_1_Abi, + CreateCallContract_v1_3_0_Abi, + SimulateTxAccessorContract_v1_4_1_Abi, + SimulateTxAccessorContract_v1_3_0_Abi +} from '@safe-global/safe-core-sdk-types' +import CreateCallContract_v1_3_0 from './CreateCall/v1.3.0/CreateCallContract_v1_3_0' +import CreateCallContract_v1_4_1 from './CreateCall/v1.4.1/CreateCallContract_v1_4_1' +import MultiSendContract_v1_1_1 from './MultiSend/v1.1.1/MultiSendContract_v1_1_1' +import MultiSendContract_v1_3_0 from './MultiSend/v1.3.0/MultiSendContract_v1_3_0' +import MultiSendContract_v1_4_1 from './MultiSend/v1.4.1/MultiSendContract_v1_4_1' +import MultiSendCallOnlyContract_v1_3_0 from './MultiSend/v1.3.0/MultiSendCallOnlyContract_v1_3_0' +import MultiSendCallOnlyContract_v1_4_1 from './MultiSend/v1.4.1/MultiSendCallOnlyContract_v1_4_1' +import SignMessageLibContract_v1_3_0 from './SignMessageLib/v1.3.0/SignMessageLibContract_v1_3_0' +import SignMessageLibContract_v1_4_1 from './SignMessageLib/v1.4.1/SignMessageLibContract_v1_4_1' +import SafeContract_v1_0_0 from './Safe/v1.0.0/SafeContract_v1_0_0' +import SafeContract_v1_1_1 from './Safe/v1.1.1/SafeContract_v1_1_1' +import SafeContract_v1_2_0 from './Safe/v1.2.0/SafeContract_v1_2_0' +import SafeContract_v1_3_0 from './Safe/v1.3.0/SafeContract_v1_3_0' +import SafeContract_v1_4_1 from './Safe/v1.4.1/SafeContract_v1_4_1' +import SafeProxyFactoryContract_v1_0_0 from './SafeProxyFactory/v1.0.0/SafeProxyFactoryContract_v1_0_0' +import SafeProxyFactoryContract_v1_1_1 from './SafeProxyFactory/v1.1.1/SafeProxyFactoryContract_v1_1_1' +import SafeProxyFactoryContract_v1_3_0 from './SafeProxyFactory/v1.3.0/SafeProxyFactoryContract_v1_3_0' +import SafeProxyFactoryContract_v1_4_1 from './SafeProxyFactory/v1.4.1/SafeProxyFactoryContract_v1_4_1' +import SimulateTxAccessorContract_v1_3_0 from './SimulateTxAccessor/v1.3.0/SimulateTxAccessorContract_v1_3_0' +import SimulateTxAccessorContract_v1_4_1 from './SimulateTxAccessor/v1.4.1/SimulateTxAccessorContract_v1_4_1' +import CompatibilityFallbackHandlerContract_v1_3_0 from './CompatibilityFallbackHandler/v1.3.0/CompatibilityFallbackHandlerContract_v1_3_0' +import CompatibilityFallbackHandlerContract_v1_4_1 from './CompatibilityFallbackHandler/v1.4.1/CompatibilityFallbackHandlerContract_v1_4_1' +import SafeProvider from '../SafeProvider' + +export async function getSafeContractInstance( + safeVersion: SafeVersion, + safeProvider: SafeProvider, + contractAddress?: string, + customContractAbi?: JsonFragment | JsonFragment[] | undefined, + isL1SafeSingleton?: boolean +): Promise< + | SafeContract_v1_4_1 + | SafeContract_v1_3_0 + | SafeContract_v1_2_0 + | SafeContract_v1_1_1 + | SafeContract_v1_0_0 +> { + const chainId = await safeProvider.getChainId() + let safeContractInstance + + switch (safeVersion) { + case '1.4.1': + safeContractInstance = new SafeContract_v1_4_1( + chainId, + safeProvider, + isL1SafeSingleton, + contractAddress, + customContractAbi as SafeContract_v1_4_1_Abi + ) + break + case '1.3.0': + safeContractInstance = new SafeContract_v1_3_0( + chainId, + safeProvider, + isL1SafeSingleton, + contractAddress, + customContractAbi as SafeContract_v1_3_0_Abi + ) + break + case '1.2.0': + safeContractInstance = new SafeContract_v1_2_0( + chainId, + safeProvider, + isL1SafeSingleton, + contractAddress, + customContractAbi as SafeContract_v1_2_0_Abi + ) + break + case '1.1.1': + safeContractInstance = new SafeContract_v1_1_1( + chainId, + safeProvider, + isL1SafeSingleton, + contractAddress, + customContractAbi as SafeContract_v1_1_1_Abi + ) + break + case '1.0.0': + safeContractInstance = new SafeContract_v1_0_0( + chainId, + safeProvider, + isL1SafeSingleton, + contractAddress, + customContractAbi as SafeContract_v1_0_0_Abi + ) + break + default: + throw new Error('Invalid Safe version') + } + + await safeContractInstance.init() + + return safeContractInstance +} + +export async function getCompatibilityFallbackHandlerContractInstance( + safeVersion: SafeVersion, + safeProvider: SafeProvider, + contractAddress?: string, + customContractAbi?: JsonFragment | JsonFragment[] | undefined +): Promise< + CompatibilityFallbackHandlerContract_v1_4_1 | CompatibilityFallbackHandlerContract_v1_3_0 +> { + const chainId = await safeProvider.getChainId() + let compatibilityFallbackHandlerInstance + + switch (safeVersion) { + case '1.4.1': + compatibilityFallbackHandlerInstance = new CompatibilityFallbackHandlerContract_v1_4_1( + chainId, + safeProvider, + contractAddress, + customContractAbi as CompatibilityFallbackHandlerContract_v1_4_1_Abi + ) + break + case '1.3.0': + case '1.2.0': + case '1.1.1': + compatibilityFallbackHandlerInstance = new CompatibilityFallbackHandlerContract_v1_3_0( + chainId, + safeProvider, + contractAddress, + customContractAbi as CompatibilityFallbackHandlerContract_v1_3_0_Abi + ) + break + default: + throw new Error('Invalid Safe version') + } + + await compatibilityFallbackHandlerInstance.init() + + return compatibilityFallbackHandlerInstance +} + +export async function getMultiSendContractInstance( + safeVersion: SafeVersion, + safeProvider: SafeProvider, + contractAddress?: string, + customContractAbi?: JsonFragment | JsonFragment[] | undefined +): Promise { + const chainId = await safeProvider.getChainId() + let multiSendContractInstance + + switch (safeVersion) { + case '1.4.1': + multiSendContractInstance = new MultiSendContract_v1_4_1( + chainId, + safeProvider, + contractAddress, + customContractAbi as MultiSendContract_v1_4_1_Abi + ) + break + case '1.3.0': + multiSendContractInstance = new MultiSendContract_v1_3_0( + chainId, + safeProvider, + contractAddress, + customContractAbi as MultiSendContract_v1_3_0_Abi + ) + break + case '1.2.0': + case '1.1.1': + case '1.0.0': + multiSendContractInstance = new MultiSendContract_v1_1_1( + chainId, + safeProvider, + contractAddress, + customContractAbi as MultiSendContract_v1_1_1_Abi + ) + break + default: + throw new Error('Invalid Safe version') + } + + await multiSendContractInstance.init() + + return multiSendContractInstance +} + +export async function getMultiSendCallOnlyContractInstance( + safeVersion: SafeVersion, + safeProvider: SafeProvider, + contractAddress?: string, + customContractAbi?: JsonFragment | JsonFragment[] | undefined +): Promise { + const chainId = await safeProvider.getChainId() + let multiSendCallOnlyContractInstance + + switch (safeVersion) { + case '1.4.1': + multiSendCallOnlyContractInstance = new MultiSendCallOnlyContract_v1_4_1( + chainId, + safeProvider, + contractAddress, + customContractAbi as MultiSendCallOnlyContract_v1_4_1_Abi + ) + break + case '1.3.0': + case '1.2.0': + case '1.1.1': + case '1.0.0': + multiSendCallOnlyContractInstance = new MultiSendCallOnlyContract_v1_3_0( + chainId, + safeProvider, + contractAddress, + customContractAbi as MultiSendCallOnlyContract_v1_3_0_Abi + ) + break + default: + throw new Error('Invalid Safe version') + } + + await multiSendCallOnlyContractInstance.init() + + return multiSendCallOnlyContractInstance +} + +export async function getSafeProxyFactoryContractInstance( + safeVersion: SafeVersion, + safeProvider: SafeProvider, + // TODO: remove this ?? + signerOrProvider: AbstractSigner | Provider, + contractAddress?: string, + customContractAbi?: JsonFragment | JsonFragment[] | undefined +): Promise< + | SafeProxyFactoryContract_v1_4_1 + | SafeProxyFactoryContract_v1_3_0 + | SafeProxyFactoryContract_v1_1_1 + | SafeProxyFactoryContract_v1_0_0 +> { + const chainId = await safeProvider.getChainId() + let safeProxyFactoryContractInstance + + switch (safeVersion) { + case '1.4.1': + safeProxyFactoryContractInstance = new SafeProxyFactoryContract_v1_4_1( + chainId, + safeProvider, + contractAddress, + customContractAbi as SafeProxyFactoryContract_v1_4_1_Abi, + signerOrProvider + ) + break + case '1.3.0': + safeProxyFactoryContractInstance = new SafeProxyFactoryContract_v1_3_0( + chainId, + safeProvider, + contractAddress, + customContractAbi as SafeProxyFactoryContract_v1_3_0_Abi, + signerOrProvider + ) + break + case '1.2.0': + case '1.1.1': + safeProxyFactoryContractInstance = new SafeProxyFactoryContract_v1_1_1( + chainId, + safeProvider, + contractAddress, + customContractAbi as SafeProxyFactoryContract_v1_1_1_Abi, + signerOrProvider + ) + break + case '1.0.0': + safeProxyFactoryContractInstance = new SafeProxyFactoryContract_v1_0_0( + chainId, + safeProvider, + contractAddress, + customContractAbi as SafeProxyFactoryContract_v1_0_0_Abi, + signerOrProvider + ) + break + default: + throw new Error('Invalid Safe version') + } + + await safeProxyFactoryContractInstance.init() + + return safeProxyFactoryContractInstance +} + +export async function getSignMessageLibContractInstance( + safeVersion: SafeVersion, + safeProvider: SafeProvider, + contractAddress?: string, + customContractAbi?: JsonFragment | JsonFragment[] | undefined +): Promise { + const chainId = await safeProvider.getChainId() + let signMessageLibContractInstance + + switch (safeVersion) { + case '1.4.1': + signMessageLibContractInstance = new SignMessageLibContract_v1_4_1( + chainId, + safeProvider, + contractAddress, + customContractAbi as SignMessageLibContract_v1_4_1_Abi + ) + break + case '1.3.0': + signMessageLibContractInstance = new SignMessageLibContract_v1_3_0( + chainId, + safeProvider, + contractAddress, + customContractAbi as SignMessageLibContract_v1_3_0_Abi + ) + break + default: + throw new Error('Invalid Safe version') + } + + await signMessageLibContractInstance.init() + + return signMessageLibContractInstance +} + +export async function getCreateCallContractInstance( + safeVersion: SafeVersion, + safeProvider: SafeProvider, + contractAddress?: string, + customContractAbi?: JsonFragment | JsonFragment[] | undefined +): Promise { + const chainId = await safeProvider.getChainId() + let createCallContractInstance + + switch (safeVersion) { + case '1.4.1': + createCallContractInstance = new CreateCallContract_v1_4_1( + chainId, + safeProvider, + contractAddress, + customContractAbi as CreateCallContract_v1_4_1_Abi + ) + break + case '1.3.0': + case '1.2.0': + case '1.1.1': + case '1.0.0': + createCallContractInstance = new CreateCallContract_v1_3_0( + chainId, + safeProvider, + contractAddress, + customContractAbi as CreateCallContract_v1_3_0_Abi + ) + break + default: + throw new Error('Invalid Safe version') + } + + await createCallContractInstance.init() + + return createCallContractInstance +} + +export async function getSimulateTxAccessorContractInstance( + safeVersion: SafeVersion, + safeProvider: SafeProvider, + contractAddress?: string, + customContractAbi?: JsonFragment | JsonFragment[] | undefined +): Promise { + const chainId = await safeProvider.getChainId() + let simulateTxAccessorContractInstance + + switch (safeVersion) { + case '1.4.1': + simulateTxAccessorContractInstance = new SimulateTxAccessorContract_v1_4_1( + chainId, + safeProvider, + contractAddress, + customContractAbi as SimulateTxAccessorContract_v1_4_1_Abi + ) + break + case '1.3.0': + simulateTxAccessorContractInstance = new SimulateTxAccessorContract_v1_3_0( + chainId, + safeProvider, + contractAddress, + customContractAbi as SimulateTxAccessorContract_v1_3_0_Abi + ) + break + default: + throw new Error('Invalid Safe version') + } + + await simulateTxAccessorContractInstance.init() + + return simulateTxAccessorContractInstance +} diff --git a/packages/protocol-kit/src/contracts/index.ts b/packages/protocol-kit/src/contracts/index.ts new file mode 100644 index 000000000..009c4b5a3 --- /dev/null +++ b/packages/protocol-kit/src/contracts/index.ts @@ -0,0 +1,15 @@ +import CreateCallBaseContract from './CreateCall/CreateCallBaseContract' +import MultiSendBaseContract from './MultiSend/MultiSendBaseContract' +import MultiSendCallOnlyBaseContract from './MultiSend/MultiSendCallOnlyBaseContract' +import SafeBaseContract from './Safe/SafeBaseContract' +import SafeProxyFactoryBaseContract from './SafeProxyFactory/SafeProxyFactoryBaseContract' +import SignMessageLibBaseContract from './SignMessageLib/SignMessageLibBaseContract' + +export { + CreateCallBaseContract, + MultiSendCallOnlyBaseContract, + MultiSendBaseContract, + SafeBaseContract, + SafeProxyFactoryBaseContract, + SignMessageLibBaseContract +} diff --git a/packages/protocol-kit/src/contracts/safeDeploymentContracts.ts b/packages/protocol-kit/src/contracts/safeDeploymentContracts.ts index 4e4e9ae24..cff605dca 100644 --- a/packages/protocol-kit/src/contracts/safeDeploymentContracts.ts +++ b/packages/protocol-kit/src/contracts/safeDeploymentContracts.ts @@ -1,33 +1,19 @@ -import { ContractNetworkConfig } from '@safe-global/protocol-kit/types' +import SafeProvider from '../SafeProvider' import { - CompatibilityFallbackHandlerContract, - CreateCallContract, - EthAdapter, - MultiSendCallOnlyContract, - MultiSendContract, - SafeContract, - SafeProxyFactoryContract, - SafeVersion, - SignMessageLibContract, - SimulateTxAccessorContract -} from '@safe-global/safe-core-sdk-types' -import { - DeploymentFilter, - SingletonDeployment, - getCompatibilityFallbackHandlerDeployment, - getCreateCallDeployment, - getMultiSendCallOnlyDeployment, - getMultiSendDeployment, - getProxyFactoryDeployment, - getSafeL2SingletonDeployment, - getSafeSingletonDeployment, - getSignMessageLibDeployment, - getSimulateTxAccessorDeployment -} from '@safe-global/safe-deployments' -import { safeDeploymentsL1ChainIds, safeDeploymentsVersions } from './config' + CompatibilityFallbackHandlerContractImplementationType, + ContractNetworkConfig, + CreateCallContractImplementationType, + MultiSendCallOnlyContractImplementationType, + MultiSendContractImplementationType, + SafeContractImplementationType, + SafeProxyFactoryContractImplementationType, + SignMessageLibContractImplementationType, + SimulateTxAccessorContractImplementationType +} from '@safe-global/protocol-kit/types' +import { SafeVersion } from '@safe-global/safe-core-sdk-types' export interface GetContractInstanceProps { - ethAdapter: EthAdapter + safeProvider: SafeProvider safeVersion: SafeVersion customContracts?: ContractNetworkConfig } @@ -37,95 +23,20 @@ export interface GetSafeContractInstanceProps extends GetContractInstanceProps { customSafeAddress?: string } -export function getSafeContractDeployment( - safeVersion: SafeVersion, - chainId: bigint, - isL1SafeSingleton = false -): SingletonDeployment | undefined { - const version = safeDeploymentsVersions[safeVersion].safeSingletonVersion - const filters: DeploymentFilter = { version, network: chainId.toString(), released: true } - if (safeDeploymentsL1ChainIds.includes(chainId) || isL1SafeSingleton) { - return getSafeSingletonDeployment(filters) - } - return getSafeL2SingletonDeployment(filters) -} - -export function getCompatibilityFallbackHandlerContractDeployment( - safeVersion: SafeVersion, - chainId: bigint -): SingletonDeployment | undefined { - const version = safeDeploymentsVersions[safeVersion].compatibilityFallbackHandler - return getCompatibilityFallbackHandlerDeployment({ - version, - network: chainId.toString(), - released: true - }) -} - -export function getMultiSendCallOnlyContractDeployment( - safeVersion: SafeVersion, - chainId: bigint -): SingletonDeployment | undefined { - const version = safeDeploymentsVersions[safeVersion].multiSendCallOnlyVersion - return getMultiSendCallOnlyDeployment({ version, network: chainId.toString(), released: true }) -} - -export function getMultiSendContractDeployment( - safeVersion: SafeVersion, - chainId: bigint -): SingletonDeployment | undefined { - const version = safeDeploymentsVersions[safeVersion].multiSendVersion - return getMultiSendDeployment({ version, network: chainId.toString(), released: true }) -} - -export function getSafeProxyFactoryContractDeployment( - safeVersion: SafeVersion, - chainId: bigint -): SingletonDeployment | undefined { - const version = safeDeploymentsVersions[safeVersion].safeProxyFactoryVersion - return getProxyFactoryDeployment({ version, network: chainId.toString(), released: true }) -} - -export function getSignMessageLibContractDeployment( - safeVersion: SafeVersion, - chainId: bigint -): SingletonDeployment | undefined { - const version = safeDeploymentsVersions[safeVersion].signMessageLibVersion - return getSignMessageLibDeployment({ version, network: chainId.toString(), released: true }) -} - -export function getCreateCallContractDeployment( - safeVersion: SafeVersion, - chainId: bigint -): SingletonDeployment | undefined { - const version = safeDeploymentsVersions[safeVersion].createCallVersion - return getCreateCallDeployment({ version, network: chainId.toString(), released: true }) -} - -export function getSimulateTxAccessorContractDeployment( - safeVersion: SafeVersion, - chainId: bigint -): SingletonDeployment | undefined { - const version = safeDeploymentsVersions[safeVersion].createCallVersion - return getSimulateTxAccessorDeployment({ version, network: chainId.toString(), released: true }) -} - export async function getSafeContract({ - ethAdapter, + safeProvider, safeVersion, customSafeAddress, isL1SafeSingleton, customContracts -}: GetSafeContractInstanceProps): Promise { - const chainId = await ethAdapter.getChainId() - const singletonDeployment = getSafeContractDeployment(safeVersion, chainId, isL1SafeSingleton) - const safeContract = await ethAdapter.getSafeContract({ +}: GetSafeContractInstanceProps): Promise { + const safeContract = await safeProvider.getSafeContract({ safeVersion, - singletonDeployment, customContractAddress: customSafeAddress ?? customContracts?.safeSingletonAddress, - customContractAbi: customContracts?.safeSingletonAbi + customContractAbi: customContracts?.safeSingletonAbi, + isL1SafeSingleton }) - const isContractDeployed = await ethAdapter.isContractDeployed(await safeContract.getAddress()) + const isContractDeployed = await safeProvider.isContractDeployed(await safeContract.getAddress()) if (!isContractDeployed) { throw new Error('SafeProxy contract is not deployed on the current network') } @@ -133,19 +44,16 @@ export async function getSafeContract({ } export async function getProxyFactoryContract({ - ethAdapter, + safeProvider, safeVersion, customContracts -}: GetContractInstanceProps): Promise { - const chainId = await ethAdapter.getChainId() - const proxyFactoryDeployment = getSafeProxyFactoryContractDeployment(safeVersion, chainId) - const safeProxyFactoryContract = await ethAdapter.getSafeProxyFactoryContract({ +}: GetContractInstanceProps): Promise { + const safeProxyFactoryContract = await safeProvider.getSafeProxyFactoryContract({ safeVersion, - singletonDeployment: proxyFactoryDeployment, customContractAddress: customContracts?.safeProxyFactoryAddress, customContractAbi: customContracts?.safeProxyFactoryAbi }) - const isContractDeployed = await ethAdapter.isContractDeployed( + const isContractDeployed = await safeProvider.isContractDeployed( await safeProxyFactoryContract.getAddress() ) if (!isContractDeployed) { @@ -155,22 +63,16 @@ export async function getProxyFactoryContract({ } export async function getCompatibilityFallbackHandlerContract({ - ethAdapter, + safeProvider, safeVersion, customContracts -}: GetContractInstanceProps): Promise { - const chainId = await ethAdapter.getChainId() - const fallbackHandlerDeployment = getCompatibilityFallbackHandlerContractDeployment( - safeVersion, - chainId - ) - const fallbackHandlerContract = await ethAdapter.getCompatibilityFallbackHandlerContract({ +}: GetContractInstanceProps): Promise { + const fallbackHandlerContract = await safeProvider.getCompatibilityFallbackHandlerContract({ safeVersion, - singletonDeployment: fallbackHandlerDeployment, customContractAddress: customContracts?.fallbackHandlerAddress, customContractAbi: customContracts?.fallbackHandlerAbi }) - const isContractDeployed = await ethAdapter.isContractDeployed( + const isContractDeployed = await safeProvider.isContractDeployed( await fallbackHandlerContract.getAddress() ) if (!isContractDeployed) { @@ -180,19 +82,16 @@ export async function getCompatibilityFallbackHandlerContract({ } export async function getMultiSendContract({ - ethAdapter, + safeProvider, safeVersion, customContracts -}: GetContractInstanceProps): Promise { - const chainId = await ethAdapter.getChainId() - const multiSendDeployment = getMultiSendContractDeployment(safeVersion, chainId) - const multiSendContract = await ethAdapter.getMultiSendContract({ +}: GetContractInstanceProps): Promise { + const multiSendContract = await safeProvider.getMultiSendContract({ safeVersion, - singletonDeployment: multiSendDeployment, customContractAddress: customContracts?.multiSendAddress, customContractAbi: customContracts?.multiSendAbi }) - const isContractDeployed = await ethAdapter.isContractDeployed( + const isContractDeployed = await safeProvider.isContractDeployed( await multiSendContract.getAddress() ) if (!isContractDeployed) { @@ -202,19 +101,16 @@ export async function getMultiSendContract({ } export async function getMultiSendCallOnlyContract({ - ethAdapter, + safeProvider, safeVersion, customContracts -}: GetContractInstanceProps): Promise { - const chainId = await ethAdapter.getChainId() - const multiSendCallOnlyDeployment = getMultiSendCallOnlyContractDeployment(safeVersion, chainId) - const multiSendCallOnlyContract = await ethAdapter.getMultiSendCallOnlyContract({ +}: GetContractInstanceProps): Promise { + const multiSendCallOnlyContract = await safeProvider.getMultiSendCallOnlyContract({ safeVersion, - singletonDeployment: multiSendCallOnlyDeployment, customContractAddress: customContracts?.multiSendCallOnlyAddress, customContractAbi: customContracts?.multiSendCallOnlyAbi }) - const isContractDeployed = await ethAdapter.isContractDeployed( + const isContractDeployed = await safeProvider.isContractDeployed( await multiSendCallOnlyContract.getAddress() ) if (!isContractDeployed) { @@ -224,19 +120,16 @@ export async function getMultiSendCallOnlyContract({ } export async function getSignMessageLibContract({ - ethAdapter, + safeProvider, safeVersion, customContracts -}: GetContractInstanceProps): Promise { - const chainId = await ethAdapter.getChainId() - const signMessageLibDeployment = getSignMessageLibContractDeployment(safeVersion, chainId) - const signMessageLibContract = await ethAdapter.getSignMessageLibContract({ +}: GetContractInstanceProps): Promise { + const signMessageLibContract = await safeProvider.getSignMessageLibContract({ safeVersion, - singletonDeployment: signMessageLibDeployment, customContractAddress: customContracts?.signMessageLibAddress, customContractAbi: customContracts?.signMessageLibAbi }) - const isContractDeployed = await ethAdapter.isContractDeployed( + const isContractDeployed = await safeProvider.isContractDeployed( await signMessageLibContract.getAddress() ) if (!isContractDeployed) { @@ -246,19 +139,16 @@ export async function getSignMessageLibContract({ } export async function getCreateCallContract({ - ethAdapter, + safeProvider, safeVersion, customContracts -}: GetContractInstanceProps): Promise { - const chainId = await ethAdapter.getChainId() - const createCallDeployment = getCreateCallContractDeployment(safeVersion, chainId) - const createCallContract = await ethAdapter.getCreateCallContract({ +}: GetContractInstanceProps): Promise { + const createCallContract = await safeProvider.getCreateCallContract({ safeVersion, - singletonDeployment: createCallDeployment, customContractAddress: customContracts?.createCallAddress, customContractAbi: customContracts?.createCallAbi }) - const isContractDeployed = await ethAdapter.isContractDeployed( + const isContractDeployed = await safeProvider.isContractDeployed( await createCallContract.getAddress() ) if (!isContractDeployed) { @@ -268,19 +158,16 @@ export async function getCreateCallContract({ } export async function getSimulateTxAccessorContract({ - ethAdapter, + safeProvider, safeVersion, customContracts -}: GetContractInstanceProps): Promise { - const chainId = await ethAdapter.getChainId() - const simulateTxAccessorDeployment = getSimulateTxAccessorContractDeployment(safeVersion, chainId) - const simulateTxAccessorContract = await ethAdapter.getSimulateTxAccessorContract({ +}: GetContractInstanceProps): Promise { + const simulateTxAccessorContract = await safeProvider.getSimulateTxAccessorContract({ safeVersion, - singletonDeployment: simulateTxAccessorDeployment, customContractAddress: customContracts?.simulateTxAccessorAddress, customContractAbi: customContracts?.simulateTxAccessorAbi }) - const isContractDeployed = await ethAdapter.isContractDeployed( + const isContractDeployed = await safeProvider.isContractDeployed( await simulateTxAccessorContract.getAddress() ) if (!isContractDeployed) { diff --git a/packages/protocol-kit/src/contracts/utils.ts b/packages/protocol-kit/src/contracts/utils.ts index 1b6dded64..55bccc402 100644 --- a/packages/protocol-kit/src/contracts/utils.ts +++ b/packages/protocol-kit/src/contracts/utils.ts @@ -1,13 +1,19 @@ -import { isAddress, zeroPadValue } from 'ethers' +import { + ContractTransactionResponse, + Provider, + AbstractSigner, + isAddress, + zeroPadValue +} from 'ethers' import { keccak_256 } from '@noble/hashes/sha3' import { DEFAULT_SAFE_VERSION } from '@safe-global/protocol-kit/contracts/config' import { EMPTY_DATA, ZERO_ADDRESS } from '@safe-global/protocol-kit/utils/constants' import { createMemoizedFunction } from '@safe-global/protocol-kit/utils/memoized' import { - EthAdapter, - SafeContract, - SafeProxyFactoryContract, - SafeVersion + SafeProxyFactoryContractType, + SafeVersion, + TransactionOptions, + TransactionResult } from '@safe-global/safe-core-sdk-types' import { generateAddress2, keccak256, toBuffer } from 'ethereumjs-util' import semverSatisfies from 'semver/functions/satisfies' @@ -19,7 +25,13 @@ import { getProxyFactoryContract, getSafeContract } from '../contracts/safeDeploymentContracts' -import { ContractNetworkConfig, SafeAccountConfig, SafeDeploymentConfig } from '../types' +import { + ContractNetworkConfig, + SafeAccountConfig, + SafeContractImplementationType, + SafeDeploymentConfig +} from '../types' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' // keccak256(toUtf8Bytes('Safe Account Abstraction')) export const PREDETERMINED_SALT_NONCE = @@ -47,7 +59,7 @@ const ZKSYNC_SAFE_PROXY_DEPLOYED_BYTECODE: { const ZKSYNC_CREATE2_PREFIX = '0x2020dba91b30cc0006188af794c2fb30dd8520db7e2c088b7fc7c103c00ca494' export interface PredictSafeAddressProps { - ethAdapter: EthAdapter + safeProvider: SafeProvider chainId: bigint // required for performance safeAccountConfig: SafeAccountConfig safeDeploymentConfig?: SafeDeploymentConfig @@ -56,15 +68,15 @@ export interface PredictSafeAddressProps { } export interface encodeSetupCallDataProps { - ethAdapter: EthAdapter + safeProvider: SafeProvider safeAccountConfig: SafeAccountConfig - safeContract: SafeContract + safeContract: SafeContractImplementationType customContracts?: ContractNetworkConfig customSafeVersion?: SafeVersion } export function encodeCreateProxyWithNonce( - safeProxyFactoryContract: SafeProxyFactoryContract, + safeProxyFactoryContract: SafeProxyFactoryContractType, safeSingletonAddress: string, initializer: string, salt?: string @@ -72,7 +84,7 @@ export function encodeCreateProxyWithNonce( return safeProxyFactoryContract.encode('createProxyWithNonce', [ safeSingletonAddress, initializer, - salt || PREDETERMINED_SALT_NONCE + BigInt(salt || PREDETERMINED_SALT_NONCE) ]) } @@ -81,7 +93,7 @@ const memoizedGetCompatibilityFallbackHandlerContract = createMemoizedFunction( ) export async function encodeSetupCallData({ - ethAdapter, + safeProvider, safeAccountConfig, safeContract, customContracts, @@ -116,7 +128,7 @@ export async function encodeSetupCallData({ const isValidAddress = fallbackHandlerAddress !== undefined && isAddress(fallbackHandlerAddress) if (!isValidAddress) { const fallbackHandlerContract = await memoizedGetCompatibilityFallbackHandlerContract({ - ethAdapter, + safeProvider, safeVersion, customContracts }) @@ -141,19 +153,19 @@ type MemoizedGetProxyFactoryContractProps = GetContractInstanceProps & { chainId type MemoizedGetSafeContractInstanceProps = GetSafeContractInstanceProps & { chainId: string } const memoizedGetProxyFactoryContract = createMemoizedFunction( - ({ ethAdapter, safeVersion, customContracts }: MemoizedGetProxyFactoryContractProps) => - getProxyFactoryContract({ ethAdapter, safeVersion, customContracts }) + ({ safeProvider, safeVersion, customContracts }: MemoizedGetProxyFactoryContractProps) => + getProxyFactoryContract({ safeProvider, safeVersion, customContracts }) ) const memoizedGetProxyCreationCode = createMemoizedFunction( async ({ - ethAdapter, + safeProvider, safeVersion, customContracts, chainId }: MemoizedGetProxyFactoryContractProps) => { const safeProxyFactoryContract = await memoizedGetProxyFactoryContract({ - ethAdapter, + safeProvider, safeVersion, customContracts, chainId @@ -165,12 +177,12 @@ const memoizedGetProxyCreationCode = createMemoizedFunction( const memoizedGetSafeContract = createMemoizedFunction( ({ - ethAdapter, + safeProvider, safeVersion, isL1SafeSingleton, customContracts }: MemoizedGetSafeContractInstanceProps) => - getSafeContract({ ethAdapter, safeVersion, isL1SafeSingleton, customContracts }) + getSafeContract({ safeProvider, safeVersion, isL1SafeSingleton, customContracts }) ) /** @@ -185,7 +197,7 @@ export function getChainSpecificDefaultSaltNonce(chainId: bigint): string { } export async function getPredictedSafeAddressInitCode({ - ethAdapter, + safeProvider, chainId, safeAccountConfig, safeDeploymentConfig = {}, @@ -201,14 +213,14 @@ export async function getPredictedSafeAddressInitCode({ } = safeDeploymentConfig const safeProxyFactoryContract = await memoizedGetProxyFactoryContract({ - ethAdapter, + safeProvider, safeVersion, customContracts, chainId: chainId.toString() }) const safeContract = await memoizedGetSafeContract({ - ethAdapter, + safeProvider, safeVersion, isL1SafeSingleton, customContracts, @@ -216,14 +228,14 @@ export async function getPredictedSafeAddressInitCode({ }) const initializer = await encodeSetupCallData({ - ethAdapter, + safeProvider, safeAccountConfig, safeContract, customContracts, customSafeVersion: safeVersion // it is more efficient if we provide the safeVersion manually }) - const encodedNonce = toBuffer(ethAdapter.encodeParameters(['uint256'], [saltNonce])).toString( + const encodedNonce = toBuffer(safeProvider.encodeParameters(['uint256'], [saltNonce])).toString( 'hex' ) const safeSingletonAddress = await safeContract.getAddress() @@ -243,7 +255,7 @@ export async function getPredictedSafeAddressInitCode({ } export async function predictSafeAddress({ - ethAdapter, + safeProvider, chainId, safeAccountConfig, safeDeploymentConfig = {}, @@ -259,21 +271,21 @@ export async function predictSafeAddress({ } = safeDeploymentConfig const safeProxyFactoryContract = await memoizedGetProxyFactoryContract({ - ethAdapter, + safeProvider, safeVersion, customContracts, chainId: chainId.toString() }) const proxyCreationCode = await memoizedGetProxyCreationCode({ - ethAdapter, + safeProvider, safeVersion, customContracts, chainId: chainId.toString() }) const safeContract = await memoizedGetSafeContract({ - ethAdapter, + safeProvider, safeVersion, isL1SafeSingleton, customContracts, @@ -281,20 +293,22 @@ export async function predictSafeAddress({ }) const initializer = await encodeSetupCallData({ - ethAdapter, + safeProvider, safeAccountConfig, safeContract, customContracts, customSafeVersion: safeVersion // it is more efficient if we provide the safeVersion manually }) - const encodedNonce = toBuffer(ethAdapter.encodeParameters(['uint256'], [saltNonce])).toString( + const encodedNonce = toBuffer(safeProvider.encodeParameters(['uint256'], [saltNonce])).toString( 'hex' ) const salt = keccak256( toBuffer('0x' + keccak256(toBuffer(initializer)).toString('hex') + encodedNonce) ) - const input = ethAdapter.encodeParameters(['address'], [await safeContract.getAddress()]) + + const input = safeProvider.encodeParameters(['address'], [await safeContract.getAddress()]) + const from = await safeProxyFactoryContract.getAddress() // On the zkSync Era chain, the counterfactual deployment address is calculated differently @@ -302,16 +316,15 @@ export async function predictSafeAddress({ if (isZkSyncEraChain) { const proxyAddress = zkSyncEraCreate2Address(from, safeVersion, salt, input) - return ethAdapter.getChecksummedAddress(proxyAddress) + return safeProvider.getChecksummedAddress(proxyAddress) } const constructorData = toBuffer(input).toString('hex') const initCode = proxyCreationCode + constructorData const proxyAddress = '0x' + generateAddress2(toBuffer(from), toBuffer(salt), toBuffer(initCode)).toString('hex') - const predictedAddress = ethAdapter.getChecksummedAddress(proxyAddress) - return predictedAddress + return safeProvider.getChecksummedAddress(proxyAddress) } export const validateSafeAccountConfig = ({ owners, threshold }: SafeAccountConfig): void => { @@ -360,3 +373,33 @@ export function zkSyncEraCreate2Address( return addressBytes } + +export function toTxResult( + transactionResponse: ContractTransactionResponse, + options?: TransactionOptions +): TransactionResult { + return { + hash: transactionResponse.hash, + options, + transactionResponse + } +} + +export function isTypedDataSigner(signer: any): signer is AbstractSigner { + return (signer as unknown as AbstractSigner).signTypedData !== undefined +} + +/** + * Check if the signerOrProvider is compatible with `Signer` + * @param signerOrProvider - Signer or provider + * @returns true if the parameter is compatible with `Signer` + */ +export function isSignerCompatible(signerOrProvider: AbstractSigner | Provider): boolean { + const candidate = signerOrProvider as AbstractSigner + + const isSigntransactionCompatible = typeof candidate.signTransaction === 'function' + const isSignMessageCompatible = typeof candidate.signMessage === 'function' + const isGetAddressCompatible = typeof candidate.getAddress === 'function' + + return isSigntransactionCompatible && isSignMessageCompatible && isGetAddressCompatible +} diff --git a/packages/protocol-kit/src/index.ts b/packages/protocol-kit/src/index.ts index dbd7fe4a9..55f076393 100644 --- a/packages/protocol-kit/src/index.ts +++ b/packages/protocol-kit/src/index.ts @@ -1,30 +1,13 @@ import Safe from './Safe' +import SafeProvider from './SafeProvider' import { - CreateCallEthersContract, - CreateProxyProps as CreateEthersProxyProps, - EthersAdapter, - EthersAdapterConfig, - EthersTransactionOptions, - EthersTransactionResult, - MultiSendCallOnlyEthersContract, - MultiSendEthersContract, - SafeContractEthers, - SafeProxyFactoryEthersContract, - SignMessageLibEthersContract -} from './adapters/ethers' -import { - CreateCallWeb3Contract, - CreateProxyProps as CreateWeb3ProxyProps, - MultiSendCallOnlyWeb3Contract, - MultiSendWeb3Contract, - SafeContractWeb3, - SafeProxyFactoryWeb3Contract, - SignMessageLibWeb3Contract, - Web3Adapter, - Web3AdapterConfig, - Web3TransactionOptions, - Web3TransactionResult -} from './adapters/web3' + CreateCallBaseContract, + MultiSendBaseContract, + MultiSendCallOnlyBaseContract, + SafeBaseContract, + SafeProxyFactoryBaseContract, + SignMessageLibBaseContract +} from './contracts' import { DEFAULT_SAFE_VERSION } from './contracts/config' import { getCompatibilityFallbackHandlerContract, @@ -43,25 +26,7 @@ import { getPredictedSafeAddressInitCode } from './contracts/utils' import ContractManager from './managers/contractManager' -import SafeFactory, { DeploySafeProps, SafeFactoryConfig } from './safeFactory' -import { - AddOwnerTxParams, - ConnectSafeConfig, - ConnectSafeConfigWithPredictedSafe, - ConnectSafeConfigWithSafeAddress, - ContractNetworksConfig, - CreateTransactionProps, - PredictedSafeProps, - RemoveOwnerTxParams, - SafeAccountConfig, - SafeConfig, - SafeConfigWithPredictedSafe, - SafeConfigWithSafeAddress, - SafeDeploymentConfig, - StandardizeSafeTransactionDataProps, - SwapOwnerTxParams, - SigningMethod -} from './types' +import SafeFactory from './SafeFactory' import { EthSafeSignature, estimateTxBaseGas, @@ -96,57 +61,23 @@ import { } from './utils/eip-712' export { - AddOwnerTxParams, estimateTxBaseGas, estimateTxGas, estimateSafeTxGas, estimateSafeDeploymentGas, - ConnectSafeConfig, - ConnectSafeConfigWithPredictedSafe, - ConnectSafeConfigWithSafeAddress, ContractManager, - ContractNetworksConfig, - CreateCallEthersContract, - CreateCallWeb3Contract, + CreateCallBaseContract, createERC20TokenTransferTransaction, - CreateEthersProxyProps, - CreateTransactionProps, - CreateWeb3ProxyProps, DEFAULT_SAFE_VERSION, - DeploySafeProps, EthSafeSignature, - EthersAdapter, - EthersAdapterConfig, - EthersTransactionOptions, - EthersTransactionResult, - MultiSendCallOnlyEthersContract, - MultiSendCallOnlyWeb3Contract, - MultiSendEthersContract, - MultiSendWeb3Contract, + MultiSendCallOnlyBaseContract, + MultiSendBaseContract, PREDETERMINED_SALT_NONCE, - PredictedSafeProps, - RemoveOwnerTxParams, - SafeAccountConfig, - SafeConfig, - SafeConfigWithPredictedSafe, - SafeConfigWithSafeAddress, - SafeContractEthers, - SafeContractWeb3, - SafeDeploymentConfig, + SafeBaseContract, SafeFactory, - SafeFactoryConfig, - SafeProxyFactoryEthersContract, - SafeProxyFactoryWeb3Contract, + SafeProxyFactoryBaseContract, SafeTransactionOptionalProps, - SignMessageLibEthersContract, - SignMessageLibWeb3Contract, - StandardizeSafeTransactionDataProps, - SwapOwnerTxParams, - SigningMethod, - Web3Adapter, - Web3AdapterConfig, - Web3TransactionOptions, - Web3TransactionResult, + SignMessageLibBaseContract, encodeCreateProxyWithNonce, encodeMultiSendData, encodeSetupCallData, @@ -173,7 +104,10 @@ export { getEip712TxTypes, getEip712MessageTypes, hashSafeMessage, - generateTypedData + generateTypedData, + SafeProvider } +export * from './types' + export default Safe diff --git a/packages/protocol-kit/src/managers/contractManager.ts b/packages/protocol-kit/src/managers/contractManager.ts index a5959e000..3493333e6 100644 --- a/packages/protocol-kit/src/managers/contractManager.ts +++ b/packages/protocol-kit/src/managers/contractManager.ts @@ -4,32 +4,34 @@ import { getMultiSendContract, getSafeContract } from '@safe-global/protocol-kit/contracts/safeDeploymentContracts' -import { ContractNetworksConfig, SafeConfig } from '@safe-global/protocol-kit/types' import { - MultiSendCallOnlyContract, - MultiSendContract, - SafeContract -} from '@safe-global/safe-core-sdk-types' -import { SafeVersion } from 'packages/safe-core-sdk-types/dist/src/types' + ContractNetworksConfig, + MultiSendCallOnlyContractImplementationType, + MultiSendContractImplementationType, + SafeConfig, + SafeContractImplementationType +} from '@safe-global/protocol-kit/types' +import { SafeVersion } from '@safe-global/safe-core-sdk-types' import { isSafeConfigWithPredictedSafe } from '../utils/types' +import SafeProvider from '../SafeProvider' class ContractManager { #contractNetworks?: ContractNetworksConfig #isL1SafeSingleton?: boolean - #safeContract?: SafeContract - #multiSendContract!: MultiSendContract - #multiSendCallOnlyContract!: MultiSendCallOnlyContract + #safeContract?: SafeContractImplementationType + #multiSendContract!: MultiSendContractImplementationType + #multiSendCallOnlyContract!: MultiSendCallOnlyContractImplementationType - static async create(config: SafeConfig): Promise { + static async init(config: SafeConfig, safeProvider: SafeProvider): Promise { const contractManager = new ContractManager() - await contractManager.init(config) + await contractManager.#initializeContractManager(config, safeProvider) return contractManager } - async init(config: SafeConfig): Promise { - const { ethAdapter, isL1SafeSingleton, contractNetworks, predictedSafe, safeAddress } = config + async #initializeContractManager(config: SafeConfig, safeProvider: SafeProvider) { + const { isL1SafeSingleton, contractNetworks, predictedSafe, safeAddress } = config - const chainId = await ethAdapter.getChainId() + const chainId = await safeProvider.getChainId() const customContracts = contractNetworks?.[chainId.toString()] this.#contractNetworks = contractNetworks this.#isL1SafeSingleton = isL1SafeSingleton @@ -41,7 +43,7 @@ class ContractManager { } else { // We use the default version of the Safe contract to get the correct version of this Safe const defaultSafeContractInstance = await getSafeContract({ - ethAdapter, + safeProvider, safeVersion: DEFAULT_SAFE_VERSION, isL1SafeSingleton, customSafeAddress: safeAddress, @@ -57,7 +59,7 @@ class ContractManager { this.#safeContract = isTheDefaultSafeVersion ? defaultSafeContractInstance : await getSafeContract({ - ethAdapter, + safeProvider, safeVersion, isL1SafeSingleton, customSafeAddress: safeAddress, @@ -66,13 +68,13 @@ class ContractManager { } this.#multiSendContract = await getMultiSendContract({ - ethAdapter, + safeProvider, safeVersion, customContracts }) this.#multiSendCallOnlyContract = await getMultiSendCallOnlyContract({ - ethAdapter, + safeProvider, safeVersion, customContracts }) @@ -86,15 +88,15 @@ class ContractManager { return this.#isL1SafeSingleton } - get safeContract(): SafeContract | undefined { + get safeContract(): SafeContractImplementationType | undefined { return this.#safeContract } - get multiSendContract(): MultiSendContract { + get multiSendContract(): MultiSendContractImplementationType { return this.#multiSendContract } - get multiSendCallOnlyContract(): MultiSendCallOnlyContract { + get multiSendCallOnlyContract(): MultiSendCallOnlyContractImplementationType { return this.#multiSendCallOnlyContract } } diff --git a/packages/protocol-kit/src/managers/fallbackHandlerManager.ts b/packages/protocol-kit/src/managers/fallbackHandlerManager.ts index 6e0b8f39a..088581747 100644 --- a/packages/protocol-kit/src/managers/fallbackHandlerManager.ts +++ b/packages/protocol-kit/src/managers/fallbackHandlerManager.ts @@ -2,24 +2,26 @@ import { hasSafeFeature, isZeroAddress, SAFE_FEATURES, + SafeContractCompatibleWithFallbackHandler, sameString } from '@safe-global/protocol-kit/utils' import { ZERO_ADDRESS } from '@safe-global/protocol-kit/utils/constants' -import { EthAdapter, SafeContract } from '@safe-global/safe-core-sdk-types' +import { SafeContractImplementationType } from '@safe-global/protocol-kit/types' +import SafeProvider from '../SafeProvider' class FallbackHandlerManager { - #ethAdapter: EthAdapter - #safeContract?: SafeContract + #safeProvider: SafeProvider + #safeContract?: SafeContractImplementationType // keccak256("fallback_manager.handler.address") #slot = '0x6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d5' - constructor(ethAdapter: EthAdapter, safeContract?: SafeContract) { - this.#ethAdapter = ethAdapter + constructor(safeProvider: SafeProvider, safeContract?: SafeContractImplementationType) { + this.#safeProvider = safeProvider this.#safeContract = safeContract } private validateFallbackHandlerAddress(fallbackHandlerAddress: string): void { - const isValidAddress = this.#ethAdapter.isAddress(fallbackHandlerAddress) + const isValidAddress = this.#safeProvider.isAddress(fallbackHandlerAddress) if (!isValidAddress || isZeroAddress(fallbackHandlerAddress)) { throw new Error('Invalid fallback handler address provided') } @@ -40,37 +42,43 @@ class FallbackHandlerManager { } } - async getFallbackHandler(): Promise { + private async isFallbackHandlerCompatible(): Promise { if (!this.#safeContract) { throw new Error('Safe is not deployed') } const safeVersion = await this.#safeContract.getVersion() - if (hasSafeFeature(SAFE_FEATURES.SAFE_FALLBACK_HANDLER, safeVersion)) { - return this.#ethAdapter.getStorageAt(await this.#safeContract.getAddress(), this.#slot) - } else { + if (!hasSafeFeature(SAFE_FEATURES.SAFE_FALLBACK_HANDLER, safeVersion)) { throw new Error( 'Current version of the Safe does not support the fallback handler functionality' ) } + + return this.#safeContract as SafeContractCompatibleWithFallbackHandler + } + + async getFallbackHandler(): Promise { + const safeContract = await this.isFallbackHandlerCompatible() + + return this.#safeProvider.getStorageAt(await safeContract.getAddress(), this.#slot) } async encodeEnableFallbackHandlerData(fallbackHandlerAddress: string): Promise { - if (!this.#safeContract) { - throw new Error('Safe is not deployed') - } + const safeContract = await this.isFallbackHandlerCompatible() + this.validateFallbackHandlerAddress(fallbackHandlerAddress) const currentFallbackHandler = await this.getFallbackHandler() this.validateFallbackHandlerIsNotEnabled(currentFallbackHandler, fallbackHandlerAddress) - return this.#safeContract.encode('setFallbackHandler', [fallbackHandlerAddress]) + + return safeContract.encode('setFallbackHandler', [fallbackHandlerAddress]) } async encodeDisableFallbackHandlerData(): Promise { - if (!this.#safeContract) { - throw new Error('Safe is not deployed') - } + const safeContract = await this.isFallbackHandlerCompatible() + const currentFallbackHandler = await this.getFallbackHandler() this.validateFallbackHandlerIsEnabled(currentFallbackHandler) - return this.#safeContract.encode('setFallbackHandler', [ZERO_ADDRESS]) + + return safeContract.encode('setFallbackHandler', [ZERO_ADDRESS]) } } diff --git a/packages/protocol-kit/src/managers/guardManager.ts b/packages/protocol-kit/src/managers/guardManager.ts index 24ac4c07f..9f82e96ac 100644 --- a/packages/protocol-kit/src/managers/guardManager.ts +++ b/packages/protocol-kit/src/managers/guardManager.ts @@ -2,24 +2,26 @@ import { hasSafeFeature, isZeroAddress, SAFE_FEATURES, + SafeContractCompatibleWithGuardManager, sameString } from '@safe-global/protocol-kit/utils' import { ZERO_ADDRESS } from '@safe-global/protocol-kit/utils/constants' -import { EthAdapter, SafeContract } from '@safe-global/safe-core-sdk-types' +import { SafeContractImplementationType } from '@safe-global/protocol-kit/types' +import SafeProvider from '../SafeProvider' class GuardManager { - #ethAdapter: EthAdapter - #safeContract?: SafeContract + #safeProvider: SafeProvider + #safeContract?: SafeContractImplementationType // keccak256("guard_manager.guard.address") #slot = '0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8' - constructor(ethAdapter: EthAdapter, safeContract?: SafeContract) { - this.#ethAdapter = ethAdapter + constructor(safeProvider: SafeProvider, safeContract?: SafeContractImplementationType) { + this.#safeProvider = safeProvider this.#safeContract = safeContract } private validateGuardAddress(guardAddress: string): void { - const isValidAddress = this.#ethAdapter.isAddress(guardAddress) + const isValidAddress = this.#safeProvider.isAddress(guardAddress) if (!isValidAddress || isZeroAddress(guardAddress)) { throw new Error('Invalid guard address provided') } @@ -37,37 +39,41 @@ class GuardManager { } } - async getGuard(): Promise { + private async isGuardCompatible(): Promise { if (!this.#safeContract) { throw new Error('Safe is not deployed') } const safeVersion = await this.#safeContract.getVersion() - if (hasSafeFeature(SAFE_FEATURES.SAFE_TX_GUARDS, safeVersion)) { - return this.#ethAdapter.getStorageAt(await this.#safeContract.getAddress(), this.#slot) - } else { + if (!hasSafeFeature(SAFE_FEATURES.SAFE_TX_GUARDS, safeVersion)) { throw new Error( 'Current version of the Safe does not support Safe transaction guards functionality' ) } + + return this.#safeContract as SafeContractCompatibleWithGuardManager + } + + async getGuard(): Promise { + const safeContract = await this.isGuardCompatible() + + return this.#safeProvider.getStorageAt(await safeContract.getAddress(), this.#slot) } async encodeEnableGuardData(guardAddress: string): Promise { - if (!this.#safeContract) { - throw new Error('Safe is not deployed') - } + const safeContract = await this.isGuardCompatible() + this.validateGuardAddress(guardAddress) const currentGuard = await this.getGuard() this.validateGuardIsNotEnabled(currentGuard, guardAddress) - return this.#safeContract.encode('setGuard', [guardAddress]) + return safeContract.encode('setGuard', [guardAddress]) } async encodeDisableGuardData(): Promise { - if (!this.#safeContract) { - throw new Error('Safe is not deployed') - } + const safeContract = await this.isGuardCompatible() + const currentGuard = await this.getGuard() this.validateGuardIsEnabled(currentGuard) - return this.#safeContract.encode('setGuard', [ZERO_ADDRESS]) + return safeContract.encode('setGuard', [ZERO_ADDRESS]) } } diff --git a/packages/protocol-kit/src/managers/moduleManager.ts b/packages/protocol-kit/src/managers/moduleManager.ts index 65c9b9529..f90d626fc 100644 --- a/packages/protocol-kit/src/managers/moduleManager.ts +++ b/packages/protocol-kit/src/managers/moduleManager.ts @@ -1,18 +1,22 @@ -import { isRestrictedAddress, sameString } from '@safe-global/protocol-kit/utils/address' +import { isRestrictedAddress, sameString } from '@safe-global/protocol-kit/utils' import { SENTINEL_ADDRESS } from '@safe-global/protocol-kit/utils/constants' -import { EthAdapter, SafeContract } from '@safe-global/safe-core-sdk-types' +import { + SafeContractImplementationType, + SafeModulesPaginated +} from '@safe-global/protocol-kit/types' +import SafeProvider from '../SafeProvider' class ModuleManager { - #ethAdapter: EthAdapter - #safeContract?: SafeContract + #safeProvider: SafeProvider + #safeContract?: SafeContractImplementationType - constructor(ethAdapter: EthAdapter, safeContract?: SafeContract) { - this.#ethAdapter = ethAdapter + constructor(safeProvider: SafeProvider, safeContract?: SafeContractImplementationType) { + this.#safeProvider = safeProvider this.#safeContract = safeContract } private validateModuleAddress(moduleAddress: string): void { - const isValidAddress = this.#ethAdapter.isAddress(moduleAddress) + const isValidAddress = this.#safeProvider.isAddress(moduleAddress) if (!isValidAddress || isRestrictedAddress(moduleAddress)) { throw new Error('Invalid module address provided') } @@ -39,21 +43,29 @@ class ModuleManager { if (!this.#safeContract) { throw new Error('Safe is not deployed') } - return this.#safeContract.getModules() + + const [modules] = await this.#safeContract.getModules() + + return [...modules] } - async getModulesPaginated(start: string, pageSize: number): Promise { + async getModulesPaginated(start: string, pageSize: number): Promise { if (!this.#safeContract) { throw new Error('Safe is not deployed') } - return this.#safeContract.getModulesPaginated(start, pageSize) + + const [modules, next] = await this.#safeContract.getModulesPaginated([start, BigInt(pageSize)]) + return { modules: modules as string[], next } } async isModuleEnabled(moduleAddress: string): Promise { if (!this.#safeContract) { throw new Error('Safe is not deployed') } - return this.#safeContract.isModuleEnabled(moduleAddress) + + const [isModuleEnabled] = await this.#safeContract.isModuleEnabled([moduleAddress]) + + return isModuleEnabled } async encodeEnableModuleData(moduleAddress: string): Promise { diff --git a/packages/protocol-kit/src/managers/ownerManager.ts b/packages/protocol-kit/src/managers/ownerManager.ts index d3927cf6d..6ede3460b 100644 --- a/packages/protocol-kit/src/managers/ownerManager.ts +++ b/packages/protocol-kit/src/managers/ownerManager.ts @@ -1,18 +1,19 @@ -import { isRestrictedAddress, sameString } from '@safe-global/protocol-kit/utils/address' +import { isRestrictedAddress, sameString } from '@safe-global/protocol-kit/utils' import { SENTINEL_ADDRESS } from '@safe-global/protocol-kit/utils/constants' -import { EthAdapter, SafeContract } from '@safe-global/safe-core-sdk-types' +import { SafeContractImplementationType } from '../types' +import SafeProvider from '../SafeProvider' class OwnerManager { - #ethAdapter: EthAdapter - #safeContract?: SafeContract + #safeProvider: SafeProvider + #safeContract?: SafeContractImplementationType - constructor(ethAdapter: EthAdapter, safeContract?: SafeContract) { - this.#ethAdapter = ethAdapter + constructor(safeProvider: SafeProvider, safeContract?: SafeContractImplementationType) { + this.#safeProvider = safeProvider this.#safeContract = safeContract } private validateOwnerAddress(ownerAddress: string, errorMessage?: string): void { - const isValidAddress = this.#ethAdapter.isAddress(ownerAddress) + const isValidAddress = this.#safeProvider.isAddress(ownerAddress) if (!isValidAddress || isRestrictedAddress(ownerAddress)) { throw new Error(errorMessage || 'Invalid owner address provided') } @@ -56,7 +57,7 @@ class OwnerManager { if (!this.#safeContract) { throw new Error('Safe is not deployed') } - const owners = await this.#safeContract.getOwners() + const [owners] = await this.#safeContract.getOwners() return [...owners] } @@ -64,14 +65,19 @@ class OwnerManager { if (!this.#safeContract) { throw new Error('Safe is not deployed') } - return this.#safeContract.getThreshold() + + const [threshold] = await this.#safeContract.getThreshold() + + return Number(threshold) } async isOwner(ownerAddress: string): Promise { if (!this.#safeContract) { throw new Error('Safe is not deployed') } - return this.#safeContract.isOwner(ownerAddress) + + const [isOwner] = await this.#safeContract.isOwner([ownerAddress]) + return isOwner } async encodeAddOwnerWithThresholdData(ownerAddress: string, threshold?: number): Promise { diff --git a/packages/protocol-kit/src/types/contracts.ts b/packages/protocol-kit/src/types/contracts.ts new file mode 100644 index 000000000..612f3fd28 --- /dev/null +++ b/packages/protocol-kit/src/types/contracts.ts @@ -0,0 +1,118 @@ +import { JsonFragment } from 'ethers' +import { SafeVersion } from '@safe-global/safe-core-sdk-types' + +import SafeContract_v1_0_0 from '@safe-global/protocol-kit/contracts/Safe/v1.0.0/SafeContract_v1_0_0' +import SafeContract_v1_1_1 from '@safe-global/protocol-kit/contracts/Safe/v1.1.1/SafeContract_v1_1_1' +import SafeContract_v1_2_0 from '@safe-global/protocol-kit/contracts/Safe/v1.2.0/SafeContract_v1_2_0' +import SafeContract_v1_3_0 from '@safe-global/protocol-kit/contracts/Safe/v1.3.0/SafeContract_v1_3_0' +import SafeContract_v1_4_1 from '@safe-global/protocol-kit/contracts/Safe/v1.4.1/SafeContract_v1_4_1' +import MultiSendContract_v1_1_1 from '@safe-global/protocol-kit/contracts/MultiSend/v1.1.1/MultiSendContract_v1_1_1' +import MultiSendContract_v1_3_0 from '@safe-global/protocol-kit/contracts/MultiSend/v1.3.0/MultiSendContract_v1_3_0' +import MultiSendContract_v1_4_1 from '@safe-global/protocol-kit/contracts/MultiSend/v1.4.1/MultiSendContract_v1_4_1' +import MultiSendCallOnlyContract_v1_4_1 from '@safe-global/protocol-kit/contracts/MultiSend/v1.4.1/MultiSendCallOnlyContract_v1_4_1' +import MultiSendCallOnlyContract_v1_3_0 from '@safe-global/protocol-kit/contracts/MultiSend/v1.3.0/MultiSendCallOnlyContract_v1_3_0' +import CompatibilityFallbackHandlerContract_v1_3_0 from '@safe-global/protocol-kit/contracts/CompatibilityFallbackHandler/v1.3.0/CompatibilityFallbackHandlerContract_v1_3_0' +import CompatibilityFallbackHandlerContract_v1_4_1 from '@safe-global/protocol-kit/contracts/CompatibilityFallbackHandler/v1.4.1/CompatibilityFallbackHandlerContract_v1_4_1' +import SafeProxyFactoryContract_v1_0_0 from '@safe-global/protocol-kit/contracts/SafeProxyFactory/v1.0.0/SafeProxyFactoryContract_v1_0_0' +import SafeProxyFactoryContract_v1_1_1 from '@safe-global/protocol-kit/contracts/SafeProxyFactory/v1.1.1/SafeProxyFactoryContract_v1_1_1' +import SafeProxyFactoryContract_v1_3_0 from '@safe-global/protocol-kit/contracts/SafeProxyFactory/v1.3.0/SafeProxyFactoryContract_v1_3_0' +import SafeProxyFactoryContract_v1_4_1 from '@safe-global/protocol-kit/contracts/SafeProxyFactory/v1.4.1/SafeProxyFactoryContract_v1_4_1' +import SignMessageLibContract_v1_3_0 from '@safe-global/protocol-kit/contracts/SignMessageLib/v1.3.0/SignMessageLibContract_v1_3_0' +import SignMessageLibContract_v1_4_1 from '@safe-global/protocol-kit/contracts/SignMessageLib/v1.4.1/SignMessageLibContract_v1_4_1' +import SimulateTxAccessorContract_v1_3_0 from '@safe-global/protocol-kit/contracts/SimulateTxAccessor/v1.3.0/SimulateTxAccessorContract_v1_3_0' +import SimulateTxAccessorContract_v1_4_1 from '@safe-global/protocol-kit/contracts/SimulateTxAccessor/v1.4.1/SimulateTxAccessorContract_v1_4_1' +import CreateCallContract_v1_3_0 from '@safe-global/protocol-kit/contracts/CreateCall/v1.3.0/CreateCallContract_v1_3_0' +import CreateCallContract_v1_4_1 from '@safe-global/protocol-kit/contracts/CreateCall/v1.4.1/CreateCallContract_v1_4_1' + +// Safe contract implementation types +export type SafeContractImplementationType = + | SafeContract_v1_0_0 + | SafeContract_v1_1_1 + | SafeContract_v1_2_0 + | SafeContract_v1_3_0 + | SafeContract_v1_4_1 + +// MultiSend contract implementation types +export type MultiSendContractImplementationType = + | MultiSendContract_v1_1_1 + | MultiSendContract_v1_3_0 + | MultiSendContract_v1_4_1 + +// MultiSendCallOnly contract implementation types +export type MultiSendCallOnlyContractImplementationType = + | MultiSendCallOnlyContract_v1_3_0 + | MultiSendCallOnlyContract_v1_4_1 + +// CompatibilityFallbackHandler contract implementation types +export type CompatibilityFallbackHandlerContractImplementationType = + | CompatibilityFallbackHandlerContract_v1_3_0 + | CompatibilityFallbackHandlerContract_v1_4_1 + +// SafeProxyFactory contract implementation types +export type SafeProxyFactoryContractImplementationType = + | SafeProxyFactoryContract_v1_0_0 + | SafeProxyFactoryContract_v1_1_1 + | SafeProxyFactoryContract_v1_3_0 + | SafeProxyFactoryContract_v1_4_1 + +// SignMessageLib contract implementation types +export type SignMessageLibContractImplementationType = + | SignMessageLibContract_v1_3_0 + | SignMessageLibContract_v1_4_1 + +// SimulateTxAccessor contract implementation types +export type SimulateTxAccessorContractImplementationType = + | SimulateTxAccessorContract_v1_3_0 + | SimulateTxAccessorContract_v1_4_1 + +// CreateCall contract implementation types +export type CreateCallContractImplementationType = + | CreateCallContract_v1_3_0 + | CreateCallContract_v1_4_1 + +export type GetContractProps = { + safeVersion: SafeVersion + customContractAddress?: string + customContractAbi?: JsonFragment | JsonFragment[] + isL1SafeSingleton?: boolean +} + +export type ContractNetworkConfig = { + /** safeSingletonAddress - Address of the Safe Singleton contract deployed on a specific network */ + safeSingletonAddress: string + /** safeSingletonAbi - Abi of the Safe Singleton contract deployed on a specific network */ + safeSingletonAbi?: JsonFragment | JsonFragment[] + /** safeProxyFactoryAddress - Address of the SafeProxyFactory contract deployed on a specific network */ + safeProxyFactoryAddress: string + /** safeProxyFactoryAbi - Abi of the SafeProxyFactory contract deployed on a specific network */ + safeProxyFactoryAbi?: JsonFragment | JsonFragment[] + /** multiSendAddress - Address of the MultiSend contract deployed on a specific network */ + multiSendAddress: string + /** multiSendAbi - Abi of the MultiSend contract deployed on a specific network */ + multiSendAbi?: JsonFragment | JsonFragment[] + /** multiSendCallOnlyAddress - Address of the MultiSendCallOnly contract deployed on a specific network */ + multiSendCallOnlyAddress: string + /** multiSendCallOnlyAbi - Abi of the MultiSendCallOnly contract deployed on a specific network */ + multiSendCallOnlyAbi?: JsonFragment | JsonFragment[] + /** fallbackHandlerAddress - Address of the Fallback Handler contract deployed on a specific network */ + fallbackHandlerAddress: string + /** fallbackHandlerAbi - Abi of the Fallback Handler contract deployed on a specific network */ + fallbackHandlerAbi?: JsonFragment | JsonFragment[] + /** signMessageLibAddress - Address of the SignMessageLib contract deployed on a specific network */ + signMessageLibAddress: string + /** signMessageLibAbi - Abi of the SignMessageLib contract deployed on a specific network */ + signMessageLibAbi?: JsonFragment | JsonFragment[] + /** createCallAddress - Address of the CreateCall contract deployed on a specific network */ + createCallAddress: string + /** createCallAbi - Abi of the CreateCall contract deployed on a specific network */ + createCallAbi?: JsonFragment | JsonFragment[] + /** simulateTxAccessorAddress - Address of the SimulateTxAccessor contract deployed on a specific network */ + simulateTxAccessorAddress: string + /** simulateTxAccessorAbi - Abi of the SimulateTxAccessor contract deployed on a specific network */ + simulateTxAccessorAbi?: JsonFragment | JsonFragment[] +} + +export type ContractNetworksConfig = { + /** id - Network id */ + [id: string]: ContractNetworkConfig +} diff --git a/packages/protocol-kit/src/types/index.ts b/packages/protocol-kit/src/types/index.ts index 6c785cf19..6fd85f361 100644 --- a/packages/protocol-kit/src/types/index.ts +++ b/packages/protocol-kit/src/types/index.ts @@ -1,199 +1,6 @@ -import { SafeTransactionOptionalProps } from '@safe-global/protocol-kit/utils/transactions' -import { - EthAdapter, - MetaTransactionData, - SafeContract, - SafeTransactionDataPartial, - SafeVersion -} from '@safe-global/safe-core-sdk-types' -import { AbiItem } from 'web3-utils' - -export interface SafeAccountConfig { - owners: string[] - threshold: number - to?: string - data?: string - fallbackHandler?: string - paymentToken?: string - payment?: number - paymentReceiver?: string -} - -export interface SafeDeploymentConfig { - saltNonce?: string - safeVersion?: SafeVersion -} - -export interface PredictedSafeProps { - safeAccountConfig: SafeAccountConfig - safeDeploymentConfig?: SafeDeploymentConfig -} - -export interface ContractNetworkConfig { - /** safeSingletonAddress - Address of the Safe Singleton contract deployed on a specific network */ - safeSingletonAddress: string - /** safeSingletonAbi - Abi of the Safe Singleton contract deployed on a specific network */ - safeSingletonAbi?: AbiItem | AbiItem[] - /** safeProxyFactoryAddress - Address of the SafeProxyFactory contract deployed on a specific network */ - safeProxyFactoryAddress: string - /** safeProxyFactoryAbi - Abi of the SafeProxyFactory contract deployed on a specific network */ - safeProxyFactoryAbi?: AbiItem | AbiItem[] - /** multiSendAddress - Address of the MultiSend contract deployed on a specific network */ - multiSendAddress: string - /** multiSendAbi - Abi of the MultiSend contract deployed on a specific network */ - multiSendAbi?: AbiItem | AbiItem[] - /** multiSendCallOnlyAddress - Address of the MultiSendCallOnly contract deployed on a specific network */ - multiSendCallOnlyAddress: string - /** multiSendCallOnlyAbi - Abi of the MultiSendCallOnly contract deployed on a specific network */ - multiSendCallOnlyAbi?: AbiItem | AbiItem[] - /** fallbackHandlerAddress - Address of the Fallback Handler contract deployed on a specific network */ - fallbackHandlerAddress: string - /** fallbackHandlerAbi - Abi of the Fallback Handler contract deployed on a specific network */ - fallbackHandlerAbi?: AbiItem | AbiItem[] - /** signMessageLibAddress - Address of the SignMessageLib contract deployed on a specific network */ - signMessageLibAddress: string - /** signMessageLibAbi - Abi of the SignMessageLib contract deployed on a specific network */ - signMessageLibAbi?: AbiItem | AbiItem[] - /** createCallAddress - Address of the CreateCall contract deployed on a specific network */ - createCallAddress: string - /** createCallAbi - Abi of the CreateCall contract deployed on a specific network */ - createCallAbi?: AbiItem | AbiItem[] - /** simulateTxAccessorAddress - Address of the SimulateTxAccessor contract deployed on a specific network */ - simulateTxAccessorAddress: string - /** simulateTxAccessorAbi - Abi of the SimulateTxAccessor contract deployed on a specific network */ - simulateTxAccessorAbi?: AbiItem | AbiItem[] -} - -export interface ContractNetworksConfig { - /** id - Network id */ - [id: string]: ContractNetworkConfig -} - -type SafeConfigWithSafeAddressProps = { - /** safeAddress - The address of the Safe account to use */ - safeAddress: string - /** predictedSafe - The configuration of the Safe that is not yet deployed */ - predictedSafe?: never -} - -type SafeConfigWithPredictedSafeProps = { - /** safeAddress - The address of the Safe account to use */ - safeAddress?: never - /** predictedSafe - The configuration of the Safe that is not yet deployed */ - predictedSafe: PredictedSafeProps -} - -export type SafeConfigProps = { - /** ethAdapter - Ethereum adapter */ - ethAdapter: EthAdapter - /** isL1SafeSingleton - Forces to use the Safe L1 version of the contract instead of the L2 version */ - isL1SafeSingleton?: boolean - /** contractNetworks - Contract network configuration */ - contractNetworks?: ContractNetworksConfig -} - -export type SafeConfigWithSafeAddress = SafeConfigProps & SafeConfigWithSafeAddressProps -export type SafeConfigWithPredictedSafe = SafeConfigProps & SafeConfigWithPredictedSafeProps -export type SafeConfig = SafeConfigWithSafeAddress | SafeConfigWithPredictedSafe - -type ConnectSafeConfigWithSafeAddressProps = { - /** safeAddress - The address of the Safe account to use */ - safeAddress?: string - /** predictedSafe - The configuration of the Safe that is not yet deployed */ - predictedSafe?: never -} - -type ConnectSafeConfigWithPredictedSafeProps = { - /** safeAddress - The address of the Safe account to use */ - safeAddress?: never - /** predictedSafe - The configuration of the Safe that is not yet deployed */ - predictedSafe?: PredictedSafeProps -} - -type ConnectSafeConfigProps = { - /** ethAdapter - Ethereum adapter */ - ethAdapter?: EthAdapter - /** isL1SafeSingleton - Forces to use the Safe L1 version of the contract instead of the L2 version */ - isL1SafeSingleton?: boolean - /** contractNetworks - Contract network configuration */ - contractNetworks?: ContractNetworksConfig -} - -export type ConnectSafeConfigWithSafeAddress = ConnectSafeConfigProps & - ConnectSafeConfigWithSafeAddressProps -export type ConnectSafeConfigWithPredictedSafe = ConnectSafeConfigProps & - ConnectSafeConfigWithPredictedSafeProps -export type ConnectSafeConfig = - | ConnectSafeConfigWithSafeAddress - | ConnectSafeConfigWithPredictedSafe - -export interface CreateTransactionProps { - /** transactions - The transaction array to process */ - transactions: MetaTransactionData[] - /** options - The transaction array optional properties */ - options?: SafeTransactionOptionalProps - /** onlyCalls - Forces the execution of the transaction array with MultiSendCallOnly contract */ - onlyCalls?: boolean -} - -export interface AddOwnerTxParams { - /** ownerAddress - The address of the new owner */ - ownerAddress: string - /** threshold - The new threshold */ - threshold?: number -} - -export interface RemoveOwnerTxParams { - /** ownerAddress - The address of the owner that will be removed */ - ownerAddress: string - /** threshold - The new threshold */ - threshold?: number -} - -export interface SwapOwnerTxParams { - /** oldOwnerAddress - The old owner address */ - oldOwnerAddress: string - /** newOwnerAddress - The new owner address */ - newOwnerAddress: string -} - -type StandardizeSafeTxDataWithSafeContractProps = { - /** safeContract - The Safe contract to use */ - safeContract: SafeContract - /** predictedSafe - The configuration of the Safe that is not yet deployed */ - predictedSafe?: never -} - -type StandardizeSafeTxDataWithPredictedSafeProps = { - /** safeContract - The Safe contract to use */ - safeContract?: never - /** predictedSafe - The configuration of the Safe that is not yet deployed */ - predictedSafe: PredictedSafeProps -} - -interface StandardizeSafeTransactionData { - /** ethAdapter - Ethereum adapter */ - ethAdapter: EthAdapter - /** tx - Safe transaction */ - tx: SafeTransactionDataPartial - /** contractNetworks - Contract network configuration */ - contractNetworks?: ContractNetworksConfig -} - -export type StandardizeSafeTxDataWithSafeContract = StandardizeSafeTransactionData & - StandardizeSafeTxDataWithSafeContractProps -export type StandardizeSafeTxDataWithPredictedSafe = StandardizeSafeTransactionData & - StandardizeSafeTxDataWithPredictedSafeProps -export type StandardizeSafeTransactionDataProps = - | StandardizeSafeTxDataWithSafeContract - | StandardizeSafeTxDataWithPredictedSafe - -export enum SigningMethod { - ETH_SIGN = 'eth_sign', - ETH_SIGN_TYPED_DATA = 'eth_signTypedData', - ETH_SIGN_TYPED_DATA_V3 = 'eth_signTypedData_v3', - ETH_SIGN_TYPED_DATA_V4 = 'eth_signTypedData_v4', - SAFE_SIGNATURE = 'safe_sign' -} - -export type SigningMethodType = SigningMethod | string +export * from './contracts' +export * from './safeConfig' +export * from './safeFactory' +export * from './safeProvider' +export * from './signing' +export * from './transactions' diff --git a/packages/protocol-kit/src/types/safeConfig.ts b/packages/protocol-kit/src/types/safeConfig.ts new file mode 100644 index 000000000..5e9f9b9ab --- /dev/null +++ b/packages/protocol-kit/src/types/safeConfig.ts @@ -0,0 +1,83 @@ +import { SafeVersion } from '@safe-global/safe-core-sdk-types' + +import { SafeProviderConfig } from './safeProvider' +import { ContractNetworksConfig } from './contracts' + +export type SafeAccountConfig = { + owners: string[] + threshold: number + to?: string + data?: string + fallbackHandler?: string + paymentToken?: string + payment?: number + paymentReceiver?: string +} + +export type SafeDeploymentConfig = { + saltNonce?: string + safeVersion?: SafeVersion +} + +export type PredictedSafeProps = { + safeAccountConfig: SafeAccountConfig + safeDeploymentConfig?: SafeDeploymentConfig +} + +type SafeConfigWithSafeAddressProps = { + /** safeAddress - The address of the Safe account to use */ + safeAddress: string + /** predictedSafe - The configuration of the Safe that is not yet deployed */ + predictedSafe?: never +} + +type SafeConfigWithPredictedSafeProps = { + /** safeAddress - The address of the Safe account to use */ + safeAddress?: never + /** predictedSafe - The configuration of the Safe that is not yet deployed */ + predictedSafe: PredictedSafeProps +} + +export type SafeConfigProps = { + provider: SafeProviderConfig['provider'] + signer?: SafeProviderConfig['signer'] + /** isL1SafeSingleton - Forces to use the Safe L1 version of the contract instead of the L2 version */ + isL1SafeSingleton?: boolean + /** contractNetworks - Contract network configuration */ + contractNetworks?: ContractNetworksConfig +} + +export type SafeConfigWithSafeAddress = SafeConfigProps & SafeConfigWithSafeAddressProps +export type SafeConfigWithPredictedSafe = SafeConfigProps & SafeConfigWithPredictedSafeProps +export type SafeConfig = SafeConfigWithSafeAddress | SafeConfigWithPredictedSafe + +type ConnectSafeConfigWithSafeAddressProps = { + /** safeAddress - The address of the Safe account to use */ + safeAddress?: string + /** predictedSafe - The configuration of the Safe that is not yet deployed */ + predictedSafe?: never +} + +type ConnectSafeConfigWithPredictedSafeProps = { + /** safeAddress - The address of the Safe account to use */ + safeAddress?: never + /** predictedSafe - The configuration of the Safe that is not yet deployed */ + predictedSafe?: PredictedSafeProps +} + +type ConnectSafeConfigProps = { + provider?: SafeProviderConfig['provider'] + signer?: SafeProviderConfig['signer'] + /** isL1SafeSingleton - Forces to use the Safe L1 version of the contract instead of the L2 version */ + isL1SafeSingleton?: boolean + /** contractNetworks - Contract network configuration */ + contractNetworks?: ContractNetworksConfig +} + +export type ConnectSafeConfigWithSafeAddress = ConnectSafeConfigProps & + ConnectSafeConfigWithSafeAddressProps +export type ConnectSafeConfigWithPredictedSafe = ConnectSafeConfigProps & + ConnectSafeConfigWithPredictedSafeProps +export type ConnectSafeConfig = + | ConnectSafeConfigWithSafeAddress + | ConnectSafeConfigWithPredictedSafe diff --git a/packages/protocol-kit/src/types/safeFactory.ts b/packages/protocol-kit/src/types/safeFactory.ts new file mode 100644 index 000000000..f31d36df8 --- /dev/null +++ b/packages/protocol-kit/src/types/safeFactory.ts @@ -0,0 +1,35 @@ +import { SafeVersion, TransactionOptions } from '@safe-global/safe-core-sdk-types' + +import { SafeProviderConfig } from './safeProvider' +import { SafeAccountConfig } from './safeConfig' +import { ContractNetworksConfig } from './contracts' + +export type DeploySafeProps = { + safeAccountConfig: SafeAccountConfig + saltNonce?: string + options?: TransactionOptions + callback?: (txHash: string) => void +} + +export type SafeFactoryConfig = { + provider: SafeProviderConfig['provider'] + signer?: SafeProviderConfig['signer'] + /** safeVersion - Versions of the Safe deployed by this Factory contract */ + safeVersion?: SafeVersion + /** isL1SafeSingleton - Forces to use the Safe L1 version of the contract instead of the L2 version */ + isL1SafeSingleton?: boolean + /** contractNetworks - Contract network configuration */ + contractNetworks?: ContractNetworksConfig +} + +export type SafeFactoryInitConfig = { + provider: SafeProviderConfig['provider'] + signer?: SafeProviderConfig['signer'] + privateKeyOrMnemonic?: string + /** safeVersion - Versions of the Safe deployed by this Factory contract */ + safeVersion: SafeVersion + /** isL1SafeSingleton - Forces to use the Safe L1 version of the contract instead of the L2 version */ + isL1SafeSingleton?: boolean + /** contractNetworks - Contract network configuration */ + contractNetworks?: ContractNetworksConfig +} diff --git a/packages/protocol-kit/src/types/safeProvider.ts b/packages/protocol-kit/src/types/safeProvider.ts new file mode 100644 index 000000000..af47b84bb --- /dev/null +++ b/packages/protocol-kit/src/types/safeProvider.ts @@ -0,0 +1,36 @@ +export type RequestArguments = { + readonly method: string + readonly params?: readonly unknown[] | object +} + +export type Eip1193Provider = { + request: (args: RequestArguments) => Promise +} + +export type HexAddress = string +export type PrivateKey = string +export type HttpTransport = string +export type SocketTransport = string +export type SafeSigner = HexAddress | PrivateKey + +export type SafeProviderConfig = { + /** signerOrProvider - Ethers signer or provider */ + provider: Eip1193Provider | HttpTransport | SocketTransport + signer?: HexAddress | PrivateKey +} + +export type SafeProviderTransaction = { + to: string + from: string + data: string + value?: string + gasPrice?: number | string + gasLimit?: number | string + maxFeePerGas?: number | string + maxPriorityFeePerGas?: number | string +} + +export type SafeModulesPaginated = { + modules: string[] + next: string +} diff --git a/packages/protocol-kit/src/types/signing.ts b/packages/protocol-kit/src/types/signing.ts new file mode 100644 index 000000000..3cb5f5792 --- /dev/null +++ b/packages/protocol-kit/src/types/signing.ts @@ -0,0 +1,9 @@ +export enum SigningMethod { + ETH_SIGN = 'eth_sign', + ETH_SIGN_TYPED_DATA = 'eth_signTypedData', + ETH_SIGN_TYPED_DATA_V3 = 'eth_signTypedData_v3', + ETH_SIGN_TYPED_DATA_V4 = 'eth_signTypedData_v4', + SAFE_SIGNATURE = 'safe_sign' +} + +export type SigningMethodType = SigningMethod | string diff --git a/packages/protocol-kit/src/types/transactions.ts b/packages/protocol-kit/src/types/transactions.ts new file mode 100644 index 000000000..15582c2fa --- /dev/null +++ b/packages/protocol-kit/src/types/transactions.ts @@ -0,0 +1,68 @@ +import { MetaTransactionData, SafeTransactionDataPartial } from '@safe-global/safe-core-sdk-types' +import { SafeTransactionOptionalProps } from '@safe-global/protocol-kit/utils/transactions' + +import { SafeProviderConfig } from './safeProvider' +import { SafeContractImplementationType } from './contracts' +import { ContractNetworksConfig } from './contracts' +import { PredictedSafeProps } from './safeConfig' + +export type CreateTransactionProps = { + /** transactions - The transaction array to process */ + transactions: MetaTransactionData[] + /** options - The transaction array optional properties */ + options?: SafeTransactionOptionalProps + /** onlyCalls - Forces the execution of the transaction array with MultiSendCallOnly contract */ + onlyCalls?: boolean +} + +type StandardizeSafeTxDataWithSafeContractProps = { + /** safeContract - The Safe contract to use */ + safeContract: SafeContractImplementationType + /** predictedSafe - The configuration of the Safe that is not yet deployed */ + predictedSafe?: never +} + +type StandardizeSafeTxDataWithPredictedSafeProps = { + /** safeContract - The Safe contract to use */ + safeContract?: never + /** predictedSafe - The configuration of the Safe that is not yet deployed */ + predictedSafe: PredictedSafeProps +} + +type StandardizeSafeTransactionData = { + provider: SafeProviderConfig['provider'] + signer?: SafeProviderConfig['signer'] + /** tx - Safe transaction */ + tx: SafeTransactionDataPartial + /** contractNetworks - Contract network configuration */ + contractNetworks?: ContractNetworksConfig +} + +export type StandardizeSafeTxDataWithSafeContract = StandardizeSafeTransactionData & + StandardizeSafeTxDataWithSafeContractProps +export type StandardizeSafeTxDataWithPredictedSafe = StandardizeSafeTransactionData & + StandardizeSafeTxDataWithPredictedSafeProps +export type StandardizeSafeTransactionDataProps = + | StandardizeSafeTxDataWithSafeContract + | StandardizeSafeTxDataWithPredictedSafe + +export type AddOwnerTxParams = { + /** ownerAddress - The address of the new owner */ + ownerAddress: string + /** threshold - The new threshold */ + threshold?: number +} + +export type RemoveOwnerTxParams = { + /** ownerAddress - The address of the owner that will be removed */ + ownerAddress: string + /** threshold - The new threshold */ + threshold?: number +} + +export type SwapOwnerTxParams = { + /** oldOwnerAddress - The old owner address */ + oldOwnerAddress: string + /** newOwnerAddress - The new owner address */ + newOwnerAddress: string +} diff --git a/packages/protocol-kit/src/utils/address.ts b/packages/protocol-kit/src/utils/address.ts index 5906f3c8b..472011460 100644 --- a/packages/protocol-kit/src/utils/address.ts +++ b/packages/protocol-kit/src/utils/address.ts @@ -8,7 +8,7 @@ export function isZeroAddress(address: string): boolean { return sameString(address, ZERO_ADDRESS) } -function isSentinelAddress(address: string): boolean { +export function isSentinelAddress(address: string): boolean { return sameString(address, SENTINEL_ADDRESS) } diff --git a/packages/protocol-kit/src/utils/eip-3770/config.ts b/packages/protocol-kit/src/utils/eip-3770/config.ts index ab90bbc40..81ed14586 100644 --- a/packages/protocol-kit/src/utils/eip-3770/config.ts +++ b/packages/protocol-kit/src/utils/eip-3770/config.ts @@ -238,6 +238,4 @@ export const networks: NetworkShortName[] = [ if (process.env.TEST_NETWORK === 'hardhat') { networks.push({ shortName: 'local', chainId: 31337n }) -} else if (process.env.TEST_NETWORK === 'ganache') { - networks.push({ shortName: 'local', chainId: 1337n }) } diff --git a/packages/protocol-kit/src/utils/eip-3770/index.ts b/packages/protocol-kit/src/utils/eip-3770/index.ts index 835a72a5b..ff2319cc4 100644 --- a/packages/protocol-kit/src/utils/eip-3770/index.ts +++ b/packages/protocol-kit/src/utils/eip-3770/index.ts @@ -1,5 +1,5 @@ +import { ethers } from 'ethers' import { Eip3770Address } from '@safe-global/safe-core-sdk-types' -import { isAddress, isHexStrict } from 'web3-utils' import { networks } from './config' export function parseEip3770Address(fullAddress: string): Eip3770Address { @@ -29,7 +29,7 @@ export function validateEip3770NetworkPrefix(prefix: string, currentChainId: big } export function validateEthereumAddress(address: string): void { - const isValidAddress = isHexStrict(address) && isAddress(address) + const isValidAddress = ethers.isHexString(address) && ethers.isAddress(address) if (!isValidAddress) { throw new Error(`Invalid Ethereum address ${address}`) } diff --git a/packages/protocol-kit/src/utils/erc-20/index.ts b/packages/protocol-kit/src/utils/erc-20/index.ts index b1b1ea72c..57273e4c9 100644 --- a/packages/protocol-kit/src/utils/erc-20/index.ts +++ b/packages/protocol-kit/src/utils/erc-20/index.ts @@ -19,7 +19,7 @@ const ERC20_ABI = [ * @throws "Invalid ERC-20 decimals" */ export async function getERC20Decimals(tokenAddress: string, safe: Safe): Promise { - const ethAdapter = safe.getEthAdapter() + const safeProvider = safe.getSafeProvider() const erc20Interface = new Interface(ERC20_ABI) const getTokenDecimalsTransaction = { @@ -29,7 +29,7 @@ export async function getERC20Decimals(tokenAddress: string, safe: Safe): Promis data: erc20Interface.encodeFunctionData('decimals') } - const response = await ethAdapter.call(getTokenDecimalsTransaction) + const response = await safeProvider.call(getTokenDecimalsTransaction) const decimals = Number(response) diff --git a/packages/protocol-kit/src/utils/memoized.ts b/packages/protocol-kit/src/utils/memoized.ts index 757707cd9..703d018a7 100644 --- a/packages/protocol-kit/src/utils/memoized.ts +++ b/packages/protocol-kit/src/utils/memoized.ts @@ -1,12 +1,43 @@ +import SafeProvider from '../SafeProvider' + export function createMemoizedFunction) => ReturnType>( callback: T, cache: Record> = {} ) { + const replacer = createSafeContractSerializerReplacer() return (...args: Parameters): ReturnType => { - const key = JSON.stringify(args) + const key = JSON.stringify(args, replacer) cache[key] = cache[key] || callback(...args) return cache[key] } } + +// EIP1193 providers from web3.currentProvider and hre.network.provider fail to serialize BigInts +function createSafeContractSerializerReplacer() { + const seen = new Set() + + return (_: string, value: unknown) => { + // Serialize Bigints as strings + if (typeof value === 'bigint') { + return value.toString() + } + + // Avoid circular references + if (value instanceof SafeProvider && value !== null) { + if (seen.has(value)) { + return undefined + } + seen.add(value) + return { + $safeProvider: { + provider: typeof value.provider === 'object' ? 'EIP1193Provider' : value.provider, + signer: value.signer + } + } + } + + return value + } +} diff --git a/packages/protocol-kit/src/utils/safeVersions.ts b/packages/protocol-kit/src/utils/safeVersions.ts index 13a152699..76f052adb 100644 --- a/packages/protocol-kit/src/utils/safeVersions.ts +++ b/packages/protocol-kit/src/utils/safeVersions.ts @@ -1,11 +1,19 @@ import semverSatisfies from 'semver/functions/satisfies' +import { SafeContractImplementationType } from '@safe-global/protocol-kit/types' +import SafeContract_v1_0_0 from '@safe-global/protocol-kit/contracts/Safe/v1.0.0/SafeContract_v1_0_0' +import SafeContract_v1_1_1 from '@safe-global/protocol-kit/contracts/Safe/v1.1.1/SafeContract_v1_1_1' +import SafeContract_v1_2_0 from '@safe-global/protocol-kit/contracts/Safe/v1.2.0/SafeContract_v1_2_0' +import SafeContract_v1_3_0 from '@safe-global/protocol-kit/contracts/Safe/v1.3.0/SafeContract_v1_3_0' +import SafeContract_v1_4_1 from '@safe-global/protocol-kit/contracts/Safe/v1.4.1/SafeContract_v1_4_1' export enum SAFE_FEATURES { SAFE_TX_GAS_OPTIONAL = 'SAFE_TX_GAS_OPTIONAL', SAFE_TX_GUARDS = 'SAFE_TX_GUARDS', SAFE_FALLBACK_HANDLER = 'SAFE_FALLBACK_HANDLER', ETH_SIGN = 'ETH_SIGN', - ACCOUNT_ABSTRACTION = 'ACCOUNT_ABSTRACTION' + ACCOUNT_ABSTRACTION = 'ACCOUNT_ABSTRACTION', + REQUIRED_TXGAS = 'REQUIRED_TXGAS', + SIMULATE_AND_REVERT = 'SIMULATE_AND_REVERT' } const SAFE_FEATURES_BY_VERSION: Record = { @@ -13,7 +21,9 @@ const SAFE_FEATURES_BY_VERSION: Record = { [SAFE_FEATURES.SAFE_TX_GUARDS]: '>=1.3.0', [SAFE_FEATURES.SAFE_FALLBACK_HANDLER]: '>=1.1.1', [SAFE_FEATURES.ETH_SIGN]: '>=1.1.0', - [SAFE_FEATURES.ACCOUNT_ABSTRACTION]: '>=1.3.0' + [SAFE_FEATURES.ACCOUNT_ABSTRACTION]: '>=1.3.0', + [SAFE_FEATURES.REQUIRED_TXGAS]: '<=1.2.0', + [SAFE_FEATURES.SIMULATE_AND_REVERT]: '>=1.3.0' } export const hasSafeFeature = (feature: SAFE_FEATURES, version: string): boolean => { @@ -23,3 +33,46 @@ export const hasSafeFeature = (feature: SAFE_FEATURES, version: string): boolean return semverSatisfies(version, SAFE_FEATURES_BY_VERSION[feature]) } + +export type SafeContractCompatibleWithFallbackHandler = + | SafeContract_v1_1_1 + | SafeContract_v1_2_0 + | SafeContract_v1_3_0 + | SafeContract_v1_4_1 + +export type SafeContractCompatibleWithGuardManager = SafeContract_v1_3_0 | SafeContract_v1_4_1 + +export type SafeContractCompatibleWithModuleManager = SafeContract_v1_3_0 | SafeContract_v1_4_1 + +export type SafeContractCompatibleWithRequiredTxGas = + | SafeContract_v1_0_0 + | SafeContract_v1_1_1 + | SafeContract_v1_2_0 + +export type SafeContractCompatibleWithSimulateAndRevert = SafeContract_v1_3_0 | SafeContract_v1_4_1 + +export async function isSafeContractCompatibleWithRequiredTxGas( + safeContract: SafeContractImplementationType +): Promise { + const safeVersion = await safeContract.getVersion() + + if (!hasSafeFeature(SAFE_FEATURES.REQUIRED_TXGAS, safeVersion)) { + throw new Error('Current version of the Safe does not support the requiredTxGas functionality') + } + + return safeContract as SafeContractCompatibleWithRequiredTxGas +} + +export async function isSafeContractCompatibleWithSimulateAndRevert( + safeContract: SafeContractImplementationType +): Promise { + const safeVersion = await safeContract.getVersion() + + if (!hasSafeFeature(SAFE_FEATURES.SIMULATE_AND_REVERT, safeVersion)) { + throw new Error( + 'Current version of the Safe does not support the simulateAndRevert functionality' + ) + } + + return safeContract as SafeContractCompatibleWithSimulateAndRevert +} diff --git a/packages/protocol-kit/src/utils/signatures/utils.ts b/packages/protocol-kit/src/utils/signatures/utils.ts index 7dfda1198..dcc26c477 100644 --- a/packages/protocol-kit/src/utils/signatures/utils.ts +++ b/packages/protocol-kit/src/utils/signatures/utils.ts @@ -1,6 +1,6 @@ import { ethers } from 'ethers' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' import { - EthAdapter, SafeSignature, SafeEIP712Args, SafeTransactionData @@ -106,31 +106,32 @@ export const adjustVInSignature: AdjustVOverload = ( } export async function generateSignature( - ethAdapter: EthAdapter, + safeProvider: SafeProvider, hash: string ): Promise { - const signerAddress = await ethAdapter.getSignerAddress() + const signerAddress = await safeProvider.getSignerAddress() if (!signerAddress) { - throw new Error('EthAdapter must be initialized with a signer to use this method') + throw new Error('SafeProvider must be initialized with a signer to use this method') } - let signature = await ethAdapter.signMessage(hash) + let signature = await safeProvider.signMessage(hash) signature = adjustVInSignature(SigningMethod.ETH_SIGN, signature, hash, signerAddress) return new EthSafeSignature(signerAddress, signature) } export async function generateEIP712Signature( - ethAdapter: EthAdapter, + safeProvider: SafeProvider, safeEIP712Args: SafeEIP712Args, methodVersion?: 'v3' | 'v4' ): Promise { - const signerAddress = await ethAdapter.getSignerAddress() + const signerAddress = await safeProvider.getSignerAddress() if (!signerAddress) { - throw new Error('EthAdapter must be initialized with a signer to use this method') + throw new Error('SafeProvider must be initialized with a signer to use this method') } - let signature = await ethAdapter.signTypedData(safeEIP712Args, methodVersion) + //@ts-expect-error: Evaluate removal of methodVersion and use v4 + let signature = await safeProvider.signTypedData(safeEIP712Args, methodVersion) signature = adjustVInSignature(SigningMethod.ETH_SIGN_TYPED_DATA, signature) return new EthSafeSignature(signerAddress, signature) diff --git a/packages/protocol-kit/src/utils/transactions/gas.ts b/packages/protocol-kit/src/utils/transactions/gas.ts index c69180834..dff83c07b 100644 --- a/packages/protocol-kit/src/utils/transactions/gas.ts +++ b/packages/protocol-kit/src/utils/transactions/gas.ts @@ -1,18 +1,20 @@ -import { - EthAdapter, - SafeContract, - OperationType, - SafeVersion, - SafeTransaction -} from '@safe-global/safe-core-sdk-types' +import { OperationType, SafeVersion, SafeTransaction } from '@safe-global/safe-core-sdk-types' import semverSatisfies from 'semver/functions/satisfies' import Safe from '@safe-global/protocol-kit/Safe' -import { ContractNetworksConfig } from '@safe-global/protocol-kit/types' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' +import { + ContractNetworksConfig, + SafeContractImplementationType +} from '@safe-global/protocol-kit/types' import { ZERO_ADDRESS } from '../constants' import { getSafeContract, getSimulateTxAccessorContract } from '../../contracts/safeDeploymentContracts' +import { + isSafeContractCompatibleWithRequiredTxGas, + isSafeContractCompatibleWithSimulateAndRevert +} from '../safeVersions' // Every byte == 00 -> 4 Gas cost const CALL_DATA_ZERO_BYTE_GAS_COST = 4 @@ -60,31 +62,35 @@ function estimateDataGasCosts(data: string): number { export async function estimateGas( safeVersion: SafeVersion, - safeContract: SafeContract, - ethAdapter: EthAdapter, + safeContract: SafeContractImplementationType, + safeProvider: SafeProvider, to: string, valueInWei: string, data: string, operation: OperationType, customContracts?: ContractNetworksConfig ) { - const chainId = await ethAdapter.getChainId() + const chainId = await safeProvider.getChainId() const simulateTxAccessorContract = await getSimulateTxAccessorContract({ - ethAdapter, + safeProvider, safeVersion, customContracts: customContracts?.[chainId.toString()] }) const transactionDataToEstimate = simulateTxAccessorContract.encode('simulate', [ to, - valueInWei, + BigInt(valueInWei), data, operation ]) - const safeFunctionToEstimate = safeContract.encode('simulateAndRevert', [ - await simulateTxAccessorContract.getAddress(), - transactionDataToEstimate - ]) + + const safeContractContractCompatibleWithSimulateAndRevert = + await isSafeContractCompatibleWithSimulateAndRevert(safeContract) + + const safeFunctionToEstimate = safeContractContractCompatibleWithSimulateAndRevert.encode( + 'simulateAndRevert', + [await simulateTxAccessorContract.getAddress(), transactionDataToEstimate] + ) const safeAddress = await safeContract.getAddress() const transactionToEstimateGas = { to: safeAddress, @@ -94,7 +100,7 @@ export async function estimateGas( } try { - const encodedResponse = await ethAdapter.call(transactionToEstimateGas) + const encodedResponse = await safeProvider.call(transactionToEstimateGas) return decodeSafeTxGas(encodedResponse) } catch (error: any) { @@ -103,8 +109,8 @@ export async function estimateGas( } export async function estimateTxGas( - safeContract: SafeContract, - ethAdapter: EthAdapter, + safeContract: SafeContractImplementationType, + safeProvider: SafeProvider, to: string, valueInWei: string, data: string, @@ -113,14 +119,18 @@ export async function estimateTxGas( let txGasEstimation = 0 const safeAddress = await safeContract.getAddress() - const estimateData: string = safeContract.encode('requiredTxGas', [ + const safeContractCompatibleWithRequiredTxGas = + await isSafeContractCompatibleWithRequiredTxGas(safeContract) + + const estimateData = safeContractCompatibleWithRequiredTxGas.encode('requiredTxGas', [ to, - valueInWei, + BigInt(valueInWei), data, operation ]) + try { - const estimateResponse = await ethAdapter.estimateGas({ + const estimateResponse = await safeProvider.estimateGas({ to: safeAddress, from: safeAddress, data: estimateData @@ -133,7 +143,7 @@ export async function estimateTxGas( let additionalGas = 10000 for (let i = 0; i < 10; i++) { try { - const estimateResponse = await ethAdapter.call({ + const estimateResponse = await safeProvider.call({ to: safeAddress, from: safeAddress, data: estimateData, @@ -151,7 +161,7 @@ export async function estimateTxGas( } try { - const estimateGas = await ethAdapter.estimateGas({ + const estimateGas = await safeProvider.estimateGas({ to, from: safeAddress, value: valueInWei, @@ -203,21 +213,23 @@ export async function estimateTxBaseGas( const signatures = '0x' const safeVersion = await safe.getContractVersion() - const ethAdapter = safe.getEthAdapter() + const safeProvider = safe.getSafeProvider() const isL1SafeSingleton = safe.getContractManager().isL1SafeSingleton const chainId = await safe.getChainId() const customContracts = safe.getContractManager().contractNetworks?.[chainId.toString()] const safeSingletonContract = await getSafeContract({ - ethAdapter, + safeProvider, safeVersion, isL1SafeSingleton, customContracts }) - const execTransactionData: string = safeSingletonContract.encode('execTransaction', [ + //@ts-expect-error: Type too complex to represent. + //TODO: We should explore contract versions and map to the correct types + const execTransactionData = safeSingletonContract.encode('execTransaction', [ to, - value, + BigInt(value), data, operation, encodeSafeTxGas, @@ -313,24 +325,30 @@ async function estimateSafeTxGasWithRequiredTxGas( const isSafeDeployed = await safe.isSafeDeployed() const safeAddress = await safe.getAddress() const safeVersion = await safe.getContractVersion() - const ethAdapter = safe.getEthAdapter() + const safeProvider = safe.getSafeProvider() const isL1SafeSingleton = safe.getContractManager().isL1SafeSingleton const chainId = await safe.getChainId() const customContracts = safe.getContractManager().contractNetworks?.[chainId.toString()] const safeSingletonContract = await getSafeContract({ - ethAdapter, + safeProvider, safeVersion, isL1SafeSingleton, customContracts }) - const transactionDataToEstimate: string = safeSingletonContract.encode('requiredTxGas', [ - safeTransaction.data.to, - safeTransaction.data.value, - safeTransaction.data.data, - safeTransaction.data.operation - ]) + const safeContractCompatibleWithRequiredTxGas = + await isSafeContractCompatibleWithRequiredTxGas(safeSingletonContract) + + const transactionDataToEstimate: string = safeContractCompatibleWithRequiredTxGas.encode( + 'requiredTxGas', + [ + safeTransaction.data.to, + BigInt(safeTransaction.data.value), + safeTransaction.data.data, + safeTransaction.data.operation + ] + ) const to = isSafeDeployed ? safeAddress : await safeSingletonContract.getAddress() @@ -341,7 +359,7 @@ async function estimateSafeTxGasWithRequiredTxGas( from: safeAddress } try { - const encodedResponse = await ethAdapter.call(transactionToEstimateGas) + const encodedResponse = await safeProvider.call(transactionToEstimateGas) const safeTxGas = '0x' + encodedResponse.slice(-32) @@ -367,11 +385,11 @@ async function estimateSafeTxGasWithRequiredTxGas( // TO-DO: Improve decoding /* - const simulateAndRevertResponse = ethAdapter.decodeParameters( + const simulateAndRevertResponse = safeProvider.decodeParameters( ['bool', 'bytes'], encodedResponse ) - const returnedData = ethAdapter.decodeParameters(['uint256', 'bool', 'bytes'], simulateAndRevertResponse[1]) + const returnedData = safeProvider.decodeParameters(['uint256', 'bool', 'bytes'], simulateAndRevertResponse[1]) */ function decodeSafeTxGas(encodedDataResponse: string): string { const [, encodedSafeTxGas] = encodedDataResponse.split('0x') @@ -382,7 +400,11 @@ function decodeSafeTxGas(encodedDataResponse: string): string { type GnosisChainEstimationError = { info: { error: { data: string | { data: string } } } } type EthersEstimationError = { data: string } -type EstimationError = Error & EthersEstimationError & GnosisChainEstimationError +type ViemEstimationError = { info: { error: { message: string } } } +type EstimationError = Error & + EthersEstimationError & + GnosisChainEstimationError & + ViemEstimationError /** * Parses the SafeTxGas estimation response from different providers. @@ -399,6 +421,12 @@ function parseSafeTxGasErrorResponse(error: EstimationError) { return decodeSafeTxGas(ethersData) } + // viem + const viemError = error?.info?.error?.message + if (viemError) { + return decodeSafeTxGas(viemError) + } + // gnosis-chain const gnosisChainProviderData = error?.info?.error?.data @@ -437,13 +465,13 @@ async function estimateSafeTxGasWithSimulate( const isSafeDeployed = await safe.isSafeDeployed() const safeAddress = await safe.getAddress() const safeVersion = await safe.getContractVersion() - const ethAdapter = safe.getEthAdapter() + const safeProvider = safe.getSafeProvider() const chainId = await safe.getChainId() const customContracts = safe.getContractManager().contractNetworks?.[chainId.toString()] const isL1SafeSingleton = safe.getContractManager().isL1SafeSingleton const safeSingletonContract = await getSafeContract({ - ethAdapter, + safeProvider, safeVersion, isL1SafeSingleton, customContracts @@ -451,14 +479,14 @@ async function estimateSafeTxGasWithSimulate( // new version of the estimation const simulateTxAccessorContract = await getSimulateTxAccessorContract({ - ethAdapter, + safeProvider, safeVersion, customContracts }) const transactionDataToEstimate: string = simulateTxAccessorContract.encode('simulate', [ safeTransaction.data.to, - safeTransaction.data.value, + BigInt(safeTransaction.data.value), safeTransaction.data.data, safeTransaction.data.operation ]) @@ -466,10 +494,13 @@ async function estimateSafeTxGasWithSimulate( // if the Safe is not deployed we can use the singleton address to simulate const to = isSafeDeployed ? safeAddress : await safeSingletonContract.getAddress() - const safeFunctionToEstimate: string = safeSingletonContract.encode('simulateAndRevert', [ - await simulateTxAccessorContract.getAddress(), - transactionDataToEstimate - ]) + const SafeContractCompatibleWithSimulateAndRevert = + await isSafeContractCompatibleWithSimulateAndRevert(safeSingletonContract) + + const safeFunctionToEstimate: string = SafeContractCompatibleWithSimulateAndRevert.encode( + 'simulateAndRevert', + [await simulateTxAccessorContract.getAddress(), transactionDataToEstimate] + ) const transactionToEstimateGas = { to, @@ -479,7 +510,7 @@ async function estimateSafeTxGasWithSimulate( } try { - const encodedResponse = await ethAdapter.call(transactionToEstimateGas) + const encodedResponse = await safeProvider.call(transactionToEstimateGas) const safeTxGas = decodeSafeTxGas(encodedResponse) @@ -489,8 +520,6 @@ async function estimateSafeTxGasWithSimulate( } catch (error: any) { return parseSafeTxGasErrorResponse(error) } - - return '0' } /** @@ -510,10 +539,10 @@ export async function estimateSafeDeploymentGas(safe: Safe): Promise { return '0' } - const ethAdapter = safe.getEthAdapter() + const safeProvider = safe.getSafeProvider() const safeDeploymentTransaction = await safe.createSafeDeploymentTransaction() - const estimation = await ethAdapter.estimateGas({ + const estimation = await safeProvider.estimateGas({ ...safeDeploymentTransaction, from: ZERO_ADDRESS // if we use the Safe address the estimation always fails due to CREATE2 }) diff --git a/packages/protocol-kit/src/utils/transactions/utils.ts b/packages/protocol-kit/src/utils/transactions/utils.ts index cc75401a8..583752527 100644 --- a/packages/protocol-kit/src/utils/transactions/utils.ts +++ b/packages/protocol-kit/src/utils/transactions/utils.ts @@ -1,4 +1,5 @@ -import { Interface, getBytes, solidityPacked as solidityPack } from 'ethers' +import { ethers, Interface, getBytes, solidityPacked as solidityPack } from 'ethers' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' import { DEFAULT_SAFE_VERSION } from '@safe-global/protocol-kit/contracts/config' import { StandardizeSafeTransactionDataProps } from '@safe-global/protocol-kit/types' import { hasSafeFeature, SAFE_FEATURES } from '@safe-global/protocol-kit/utils' @@ -13,7 +14,6 @@ import { SafeVersion } from '@safe-global/safe-core-sdk-types' import semverSatisfies from 'semver/functions/satisfies' -import { hexToNumber, hexToNumberString, toChecksumAddress } from 'web3-utils' import { estimateGas, estimateTxGas } from './gas' export function standardizeMetaTransactionData( @@ -29,7 +29,7 @@ export function standardizeMetaTransactionData( export async function standardizeSafeTransactionData({ safeContract, predictedSafe, - ethAdapter, + provider, tx, contractNetworks }: StandardizeSafeTransactionDataProps): Promise { @@ -42,7 +42,7 @@ export async function standardizeSafeTransactionData({ gasPrice: tx.gasPrice ?? '0', gasToken: tx.gasToken || ZERO_ADDRESS, refundReceiver: tx.refundReceiver || ZERO_ADDRESS, - nonce: tx.nonce ?? (safeContract ? await safeContract.getNonce() : 0) + nonce: tx.nonce ?? (safeContract ? Number(await safeContract.getNonce()) : 0) } if (typeof tx.safeTxGas !== 'undefined') { @@ -78,11 +78,13 @@ export async function standardizeSafeTransactionData({ } let safeTxGas + + const safeProvider = new SafeProvider({ provider }) if (semverSatisfies(safeVersion, '>=1.3.0')) { safeTxGas = await estimateGas( safeVersion, safeContract, - ethAdapter, + safeProvider, standardizedTxs.to, standardizedTxs.value, standardizedTxs.data, @@ -92,7 +94,7 @@ export async function standardizeSafeTransactionData({ } else { safeTxGas = await estimateTxGas( safeContract, - ethAdapter, + safeProvider, standardizedTxs.to, standardizedTxs.value, standardizedTxs.data, @@ -140,9 +142,9 @@ export function decodeMultiSendData(encodedData: string): MetaTransactionData[] const data = `0x${decodedData.slice(index, (index += dataLength))}` txs.push({ - operation: hexToNumber(operation) as OperationType, - to: toChecksumAddress(to), - value: hexToNumberString(value), + operation: Number(operation) as OperationType, + to: ethers.getAddress(to), + value: BigInt(value).toString(), data }) } diff --git a/packages/protocol-kit/tests/e2e/contractManager.test.ts b/packages/protocol-kit/tests/e2e/contractManager.test.ts index ec2cef1de..c96983d76 100644 --- a/packages/protocol-kit/tests/e2e/contractManager.test.ts +++ b/packages/protocol-kit/tests/e2e/contractManager.test.ts @@ -16,7 +16,7 @@ import { getSignMessageLib, getSimulateTxAccessor } from './utils/setupContracts' -import { getEthAdapter } from './utils/setupEthAdapter' +import { getEip1193Provider } from './utils/setupProvider' import { getAccounts } from './utils/setupTestNetwork' chai.use(chaiAsPromised) @@ -27,19 +27,19 @@ describe('Safe contracts manager', () => { const accounts = await getAccounts() const chainId = BigInt(await getChainId()) const contractNetworks = await getContractNetworks(chainId) + const provider = getEip1193Provider() return { safe: await getSafeWithOwners([accounts[0].address]), accounts, contractNetworks, - chainId + chainId, + provider } }) describe('create', async () => { it('should initialize the SDK with a Safe that is not deployed', async () => { - const { accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { accounts, contractNetworks, provider } = await setupTests() const predictedSafe: PredictedSafeProps = { safeAccountConfig: { owners: [accounts[0].address], @@ -49,9 +49,9 @@ describe('Safe contracts manager', () => { safeVersion: safeVersionDeployed } } - await chai.expect( - await Safe.create({ - ethAdapter, + chai.expect( + await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -59,32 +59,24 @@ describe('Safe contracts manager', () => { }) it('should fail if the current network is not a default network and no contractNetworks is provided', async () => { - const { safe, accounts } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, provider } = await setupTests() const safeAddress = await safe.getAddress() await chai .expect( - Safe.create({ - ethAdapter, + Safe.init({ + provider, safeAddress }) ) - .to.be.rejectedWith( - process.env.ETH_LIB === 'web3' - ? 'You must provide the json interface of the contract when instantiating a contract object' - : 'Invalid MultiSend contract address' - ) + .to.be.rejectedWith('Invalid multiSend contract address') }) it('should fail if SafeProxy contract is not deployed on the current network', async () => { - const { accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { contractNetworks, provider } = await setupTests() await chai .expect( - Safe.create({ - ethAdapter, + Safe.init({ + provider, safeAddress: ZERO_ADDRESS, contractNetworks }) @@ -93,7 +85,7 @@ describe('Safe contracts manager', () => { }) it('should fail if MultiSend contract is specified in contractNetworks but not deployed', async () => { - const { safe, accounts, chainId } = await setupTests() + const { safe, chainId, provider } = await setupTests() const customContractNetworks: ContractNetworksConfig = { [chainId.toString()]: { safeSingletonAddress: ZERO_ADDRESS, @@ -114,13 +106,12 @@ describe('Safe contracts manager', () => { simulateTxAccessorAbi: (await getSimulateTxAccessor()).abi } } - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const safeAddress = await safe.getAddress() await chai .expect( - Safe.create({ - ethAdapter, + Safe.init({ + provider, safeAddress, contractNetworks: customContractNetworks }) @@ -129,12 +120,10 @@ describe('Safe contracts manager', () => { }) it('should set the MultiSend contract available on the current network', async () => { - const { safe, accounts, chainId, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, chainId, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) diff --git a/packages/protocol-kit/tests/e2e/core.test.ts b/packages/protocol-kit/tests/e2e/core.test.ts index e097f7072..a61c6c81b 100644 --- a/packages/protocol-kit/tests/e2e/core.test.ts +++ b/packages/protocol-kit/tests/e2e/core.test.ts @@ -7,7 +7,7 @@ import { deployments } from 'hardhat' import { itif } from './utils/helpers' import { getContractNetworks } from './utils/setupContractNetworks' import { getSafeWithOwners } from './utils/setupContracts' -import { getEthAdapter } from './utils/setupEthAdapter' +import { getEip1193Provider } from './utils/setupProvider' import { getAccounts } from './utils/setupTestNetwork' import { waitSafeTxReceipt } from './utils/transactions' @@ -28,9 +28,11 @@ describe('Safe Info', () => { safeVersion: safeVersionDeployed } } + const provider = getEip1193Provider() return { chainId, safe: await getSafeWithOwners([accounts[0].address, accounts[1].address]), + provider, predictedSafe, accounts, contractNetworks @@ -41,12 +43,10 @@ describe('Safe Info', () => { itif(safeVersionDeployed < '1.3.0')( 'should fail to connect a Safe { - const { predictedSafe, safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { predictedSafe, safe, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -62,64 +62,62 @@ describe('Safe Info', () => { itif(safeVersionDeployed >= '1.3.0')( 'should connect a Safe >=v1.3.0 that is not deployed', async () => { - const { predictedSafe, safe, accounts, contractNetworks } = await setupTests() + const { predictedSafe, safe, accounts, contractNetworks, provider } = await setupTests() const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) const safeSdk2 = await safeSdk.connect({ predictedSafe }) chai - .expect(await safeSdk2.getEthAdapter().getSignerAddress()) + .expect(await safeSdk2.getSafeProvider().getSignerAddress()) .to.be.eq(await account1.signer.getAddress()) } ) it('should connect a deployed Safe', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1, account2] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, accounts, contractNetworks, provider } = await setupTests() + const [account1, account2, account3] = accounts const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) chai.expect(await safeSdk.getAddress()).to.be.eq(safeAddress) chai - .expect(await safeSdk.getEthAdapter().getSignerAddress()) + .expect(await safeSdk.getSafeProvider().getSignerAddress()) .to.be.eq(await account1.signer.getAddress()) - const ethAdapter2 = await getEthAdapter(account2.signer) const safeSdk2 = await safeSdk.connect({ - ethAdapter: ethAdapter2, + signer: account2.address, contractNetworks }) chai.expect(await safeSdk2.getAddress()).to.be.eq(safeAddress) chai - .expect(await safeSdk2.getEthAdapter().getSignerAddress()) + .expect(await safeSdk2.getSafeProvider().getSignerAddress()) .to.be.eq(await account2.signer.getAddress()) - const safe2 = await getSafeWithOwners([accounts[2].address]) + const safe2 = await getSafeWithOwners([account3.address]) const safe2Address = await safe2.getAddress() - const safeSdk3 = await safeSdk2.connect({ safeAddress: safe2Address }) + const safeSdk3 = await safeSdk2.connect({ + safeAddress: safe2Address, + signer: account3.address + }) chai.expect(await safeSdk3.getAddress()).to.be.eq(safe2Address) chai - .expect(await safeSdk3.getEthAdapter().getSignerAddress()) - .to.be.eq(await account2.signer.getAddress()) + .expect(await safeSdk3.getSafeProvider().getSignerAddress()) + .to.be.eq(await account3.signer.getAddress()) }) }) describe('getContractVersion', async () => { it('should return the contract version of a Safe that is not deployed with a custom version configuration', async () => { - const { predictedSafe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { predictedSafe, contractNetworks, provider } = await setupTests() + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -128,15 +126,13 @@ describe('Safe Info', () => { }) it('should return the contract version of a Safe that is not deployed with a default version configuration', async () => { - const { predictedSafe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { predictedSafe, contractNetworks, provider } = await setupTests() const safeConfig: PredictedSafeProps = { ...predictedSafe, safeDeploymentConfig: {} } - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, predictedSafe: safeConfig, contractNetworks }) @@ -145,12 +141,10 @@ describe('Safe Info', () => { }) it('should return the Safe contract version', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -163,11 +157,9 @@ describe('Safe Info', () => { itif(safeVersionDeployed < '1.3.0')( 'should fail to return the address of a Safe { - const { predictedSafe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { predictedSafe, contractNetworks, provider } = await setupTests() + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -183,18 +175,16 @@ describe('Safe Info', () => { itif(safeVersionDeployed >= '1.3.0')( 'should return the address of a Safe >=v1.3.0 that is not deployed', async () => { - const { predictedSafe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { predictedSafe, contractNetworks, provider } = await setupTests() + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) const safeAddress = await safeSdk.getAddress() - const safeFactory = await SafeFactory.create({ - ethAdapter, + const safeFactory = await SafeFactory.init({ + provider, safeVersion: safeVersionDeployed, contractNetworks }) @@ -206,12 +196,10 @@ describe('Safe Info', () => { ) it('should return the address of a deployed Safe', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -219,30 +207,27 @@ describe('Safe Info', () => { }) }) - describe('getEthAdapter', async () => { - it('should return the connected EthAdapter', async () => { - const { safe, accounts, contractNetworks } = await setupTests() + describe('getEip1193Provider', async () => { + it('should return the connected SafeProvider', async () => { + const { safe, accounts, contractNetworks, provider } = await setupTests() const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress: safeAddress, contractNetworks }) chai - .expect(await safeSdk.getEthAdapter().getSignerAddress()) + .expect(await safeSdk.getSafeProvider().getSignerAddress()) .to.be.eq(await account1.signer.getAddress()) }) }) describe('getNonce', async () => { it('should return the nonce of a Safe that is not deployed', async () => { - const { predictedSafe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { predictedSafe, contractNetworks, provider } = await setupTests() + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -250,13 +235,12 @@ describe('Safe Info', () => { }) it('should return the Safe nonce', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts - const ethAdapter = await getEthAdapter(account1.signer) const safe = await getSafeWithOwners([account1.address]) const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress: safeAddress, contractNetworks }) @@ -276,11 +260,9 @@ describe('Safe Info', () => { describe('getChainId', async () => { it('should return the chainId of a Safe that is not deployed', async () => { - const { predictedSafe, accounts, chainId, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { predictedSafe, chainId, contractNetworks, provider } = await setupTests() + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -288,12 +270,10 @@ describe('Safe Info', () => { }) it('should return the chainId of the current network', async () => { - const { safe, accounts, chainId, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, chainId, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress: safeAddress, contractNetworks }) @@ -305,11 +285,9 @@ describe('Safe Info', () => { itif(safeVersionDeployed < '1.3.0')( 'should fail to return the balance of a Safe { - const { predictedSafe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { predictedSafe, contractNetworks, provider } = await setupTests() + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -324,38 +302,49 @@ describe('Safe Info', () => { itif(safeVersionDeployed >= '1.3.0')( 'should return the balance of a Safe >=v1.3.0 that is not deployed', async () => { - const { predictedSafe, accounts, contractNetworks } = await setupTests() + const { predictedSafe, accounts, contractNetworks, provider } = await setupTests() const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) chai.expect(await safeSdk.getBalance()).to.be.eq(0n) - await account1.signer.sendTransaction({ + + const txResponse = await account1.signer.sendTransaction({ to: await safeSdk.getAddress(), value: BigInt(`${1e18}`) }) + await txResponse.wait(1) + + // TODO: Not working without this delay + await new Promise((resolve) => setTimeout(resolve, 500)) + chai.expect(await safeSdk.getBalance()).to.be.eq(BigInt(`${1e18}`)) } ) it('should return the balance of a deployed Safe', async () => { - const { safe, accounts, contractNetworks } = await setupTests() + const { safe, accounts, contractNetworks, provider } = await setupTests() const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, + signer: account1.address, safeAddress, contractNetworks }) chai.expect(await safeSdk.getBalance()).to.be.eq(0n) - await account1.signer.sendTransaction({ - to: await safeSdk.getAddress(), + + const txResponse = await account1.signer.sendTransaction({ + to: safeAddress, value: BigInt(`${1e18}`) }) + await txResponse.wait(1) + + // TODO: Not working without this delay + await new Promise((resolve) => setTimeout(resolve, 500)) + chai.expect(await safeSdk.getBalance()).to.be.eq(BigInt(`${1e18}`)) }) }) diff --git a/packages/protocol-kit/tests/e2e/createSafeDeploymentTransaction.test.ts b/packages/protocol-kit/tests/e2e/createSafeDeploymentTransaction.test.ts index 6e307d87c..3ccba4d55 100644 --- a/packages/protocol-kit/tests/e2e/createSafeDeploymentTransaction.test.ts +++ b/packages/protocol-kit/tests/e2e/createSafeDeploymentTransaction.test.ts @@ -6,11 +6,12 @@ import { safeVersionDeployed } from '@safe-global/protocol-kit/hardhat/deploy/de import Safe, { PREDETERMINED_SALT_NONCE, PredictedSafeProps, + SafeProvider, encodeSetupCallData } from '@safe-global/protocol-kit/index' import { getContractNetworks } from './utils/setupContractNetworks' import { getSafeWithOwners, getFactory } from './utils/setupContracts' -import { getEthAdapter } from './utils/setupEthAdapter' +import { getEip1193Provider } from './utils/setupProvider' import { getAccounts } from './utils/setupTestNetwork' import { itif } from './utils/helpers' @@ -22,7 +23,7 @@ describe('createSafeDeploymentTransaction', () => { const accounts = await getAccounts() const chainId = BigInt(await getChainId()) const contractNetworks = await getContractNetworks(chainId) - + const provider = getEip1193Provider() const predictedSafe: PredictedSafeProps = { safeAccountConfig: { owners: [accounts[0].address], @@ -37,18 +38,16 @@ describe('createSafeDeploymentTransaction', () => { accounts, contractNetworks, predictedSafe, - chainId + chainId, + provider } }) itif(safeVersionDeployed == '1.4.1')('should return a Safe deployment transactions', async () => { - const { accounts, contractNetworks, predictedSafe } = await setupTests() - const [account1] = accounts - - const ethAdapter = await getEthAdapter(account1.signer) + const { contractNetworks, predictedSafe, provider } = await setupTests() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -66,13 +65,10 @@ describe('createSafeDeploymentTransaction', () => { }) itif(safeVersionDeployed == '1.3.0')('should return a Safe deployment transactions', async () => { - const { accounts, contractNetworks, predictedSafe } = await setupTests() - const [account1] = accounts - - const ethAdapter = await getEthAdapter(account1.signer) + const { contractNetworks, predictedSafe, provider } = await setupTests() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -90,13 +86,10 @@ describe('createSafeDeploymentTransaction', () => { }) itif(safeVersionDeployed == '1.2.0')('should return a Safe deployment transactions', async () => { - const { accounts, contractNetworks, predictedSafe } = await setupTests() - const [account1] = accounts - - const ethAdapter = await getEthAdapter(account1.signer) + const { contractNetworks, predictedSafe, provider } = await setupTests() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -114,13 +107,10 @@ describe('createSafeDeploymentTransaction', () => { }) itif(safeVersionDeployed == '1.1.1')('should return a Safe deployment transactions', async () => { - const { accounts, contractNetworks, predictedSafe } = await setupTests() - const [account1] = accounts - - const ethAdapter = await getEthAdapter(account1.signer) + const { contractNetworks, predictedSafe, provider } = await setupTests() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -138,13 +128,10 @@ describe('createSafeDeploymentTransaction', () => { }) itif(safeVersionDeployed == '1.0.0')('should return a Safe deployment transactions', async () => { - const { accounts, contractNetworks, predictedSafe } = await setupTests() - const [account1] = accounts - - const ethAdapter = await getEthAdapter(account1.signer) + const { contractNetworks, predictedSafe, provider } = await setupTests() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -162,21 +149,18 @@ describe('createSafeDeploymentTransaction', () => { }) it('should contain the initializer setup call in the deployment data to sets the threshold & owners of the deployed Safe', async () => { - const { accounts, contractNetworks, predictedSafe, chainId } = await setupTests() - const [account1] = accounts - - const ethAdapter = await getEthAdapter(account1.signer) + const { contractNetworks, predictedSafe, chainId, provider } = await setupTests() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) - + const safeProvider = safeSdk.getSafeProvider() const deploymentTransaction = await safeSdk.createSafeDeploymentTransaction() const customContract = contractNetworks[chainId.toString()] - const safeContract = await ethAdapter.getSafeContract({ + const safeContract = await safeProvider.getSafeContract({ safeVersion: safeVersionDeployed, customContractAddress: customContract?.safeSingletonAddress, customContractAbi: customContract?.safeSingletonAbi @@ -184,7 +168,7 @@ describe('createSafeDeploymentTransaction', () => { // this is the call to the setup method that sets the threshold & owners of the new Safe const initializer = await encodeSetupCallData({ - ethAdapter, + safeProvider, safeContract, safeAccountConfig: predictedSafe.safeAccountConfig, customContracts: contractNetworks[chainId.toString()] @@ -196,18 +180,16 @@ describe('createSafeDeploymentTransaction', () => { describe('salt nonce', () => { it('should include the predetermined salt nonce in the Safe deployment data', async () => { - const { accounts, contractNetworks, predictedSafe, chainId } = await setupTests() - const [account1] = accounts - - const ethAdapter = await getEthAdapter(account1.signer) + const { contractNetworks, predictedSafe, chainId, provider } = await setupTests() - const safeSdk = await Safe.create({ - ethAdapter, + const safeProvider = new SafeProvider({ provider }) + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) - const predeterminedSaltNonceEncoded = ethAdapter.encodeParameters( + const predeterminedSaltNonceEncoded = safeProvider.encodeParameters( ['uint256'], [`0x${Buffer.from(keccak_256(PREDETERMINED_SALT_NONCE + chainId)).toString('hex')}`] ) @@ -221,20 +203,18 @@ describe('createSafeDeploymentTransaction', () => { }) it('should include the custom salt nonce in the Safe deployment data', async () => { - const { accounts, contractNetworks, predictedSafe } = await setupTests() - const [account1] = accounts + const { contractNetworks, predictedSafe, provider } = await setupTests() - const ethAdapter = await getEthAdapter(account1.signer) - - const safeSdk = await Safe.create({ - ethAdapter, + const safeProvider = new SafeProvider({ provider }) + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) const customSaltNonce = '123456789' - const customSaltNonceEncoded = ethAdapter.encodeParameters(['uint256'], [customSaltNonce]) + const customSaltNonceEncoded = safeProvider.encodeParameters(['uint256'], [customSaltNonce]) const deploymentTransaction = await safeSdk.createSafeDeploymentTransaction(customSaltNonce) @@ -243,15 +223,12 @@ describe('createSafeDeploymentTransaction', () => { }) it('should include the salt nonce included in the safeDeploymentConfig in the Safe deployment data', async () => { - const { accounts, contractNetworks, predictedSafe } = await setupTests() - const [account1] = accounts - - const ethAdapter = await getEthAdapter(account1.signer) + const { contractNetworks, predictedSafe, provider } = await setupTests() const customSaltNonce = '123456789' - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, predictedSafe: { ...predictedSafe, safeDeploymentConfig: { @@ -262,7 +239,9 @@ describe('createSafeDeploymentTransaction', () => { contractNetworks }) - const saltNonceEncoded = ethAdapter.encodeParameters(['uint256'], [customSaltNonce]) + const saltNonceEncoded = safeSdk + .getSafeProvider() + .encodeParameters(['uint256'], [customSaltNonce]) const deploymentTransaction = await safeSdk.createSafeDeploymentTransaction(customSaltNonce) @@ -272,15 +251,14 @@ describe('createSafeDeploymentTransaction', () => { }) it('should throw an error if predicted Safe is not present', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) diff --git a/packages/protocol-kit/tests/e2e/createTransaction.test.ts b/packages/protocol-kit/tests/e2e/createTransaction.test.ts index 4e5717862..bf70f6ed3 100644 --- a/packages/protocol-kit/tests/e2e/createTransaction.test.ts +++ b/packages/protocol-kit/tests/e2e/createTransaction.test.ts @@ -2,16 +2,17 @@ import { safeVersionDeployed } from '@safe-global/protocol-kit/hardhat/deploy/de import Safe, { PredictedSafeProps, SafeTransactionOptionalProps, - standardizeSafeTransactionData + standardizeSafeTransactionData, + SafeContractImplementationType as SafeContract } from '@safe-global/protocol-kit/index' -import { SafeContract, SafeTransactionDataPartial } from '@safe-global/safe-core-sdk-types' +import { SafeTransactionDataPartial } from '@safe-global/safe-core-sdk-types' import chai from 'chai' import chaiAsPromised from 'chai-as-promised' import { deployments } from 'hardhat' import { itif } from './utils/helpers' import { getContractNetworks } from './utils/setupContractNetworks' import { getERC20Mintable, getSafeWithOwners } from './utils/setupContracts' -import { getEthAdapter } from './utils/setupEthAdapter' +import { getEip1193Provider } from './utils/setupProvider' import { getAccounts } from './utils/setupTestNetwork' chai.use(chaiAsPromised) @@ -31,6 +32,7 @@ describe('Transactions creation', () => { const accounts = await getAccounts() const chainId = BigInt(await getChainId()) const contractNetworks = await getContractNetworks(chainId) + const provider = getEip1193Provider() const predictedSafe: PredictedSafeProps = { safeAccountConfig: { owners: [accounts[0].address], @@ -46,7 +48,8 @@ describe('Transactions creation', () => { accounts, chainId, contractNetworks, - predictedSafe + predictedSafe, + provider } }) @@ -54,13 +57,12 @@ describe('Transactions creation', () => { itif(safeVersionDeployed >= '1.3.0')( 'should return a transaction with safeTxGas=0 if safeVersion>=1.3.0 and gasPrice=0', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -71,7 +73,7 @@ describe('Transactions creation', () => { } const safeTxData = await standardizeSafeTransactionData({ safeContract: safeSdk.getContractManager().safeContract as SafeContract, - ethAdapter, + provider, tx: txDataPartial, contractNetworks }) @@ -82,13 +84,12 @@ describe('Transactions creation', () => { itif(safeVersionDeployed >= '1.3.0')( 'should return a transaction with estimated safeTxGas if safeVersion>=1.3.0 and gasPrice>0', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -100,7 +101,7 @@ describe('Transactions creation', () => { } const safeTxData = await standardizeSafeTransactionData({ safeContract: safeSdk.getContractManager().safeContract as SafeContract, - ethAdapter, + provider, tx: txDataPartial, contractNetworks }) @@ -111,13 +112,12 @@ describe('Transactions creation', () => { itif(safeVersionDeployed >= '1.3.0')( 'should return a transaction with defined safeTxGas if safeVersion>=1.3.0', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -130,7 +130,7 @@ describe('Transactions creation', () => { } const safeTxData = await standardizeSafeTransactionData({ safeContract: safeSdk.getContractManager().safeContract as SafeContract, - ethAdapter, + provider, tx: txDataPartial, contractNetworks }) @@ -141,13 +141,12 @@ describe('Transactions creation', () => { itif(safeVersionDeployed < '1.3.0')( 'should return a transaction with estimated safeTxGas if safeVersion<1.3.0', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -158,7 +157,7 @@ describe('Transactions creation', () => { } const safeTxData = await standardizeSafeTransactionData({ safeContract: safeSdk.getContractManager().safeContract as SafeContract, - ethAdapter, + provider, tx: txDataPartial, contractNetworks }) @@ -169,13 +168,12 @@ describe('Transactions creation', () => { itif(safeVersionDeployed < '1.3.0')( 'should return a transaction with defined safeTxGas of 0 if safeVersion<1.3.0', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -188,7 +186,7 @@ describe('Transactions creation', () => { } const safeTxData = await standardizeSafeTransactionData({ safeContract: safeSdk.getContractManager().safeContract as SafeContract, - ethAdapter, + provider, tx: txDataPartial, contractNetworks }) @@ -199,13 +197,12 @@ describe('Transactions creation', () => { itif(safeVersionDeployed < '1.3.0')( 'should return a transaction with defined safeTxGas if safeVersion<1.3.0', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -218,7 +215,7 @@ describe('Transactions creation', () => { } const safeTxData = await standardizeSafeTransactionData({ safeContract: safeSdk.getContractManager().safeContract as SafeContract, - ethAdapter, + provider, tx: txDataPartial, contractNetworks }) @@ -229,11 +226,10 @@ describe('Transactions creation', () => { describe('createTransaction', async () => { it('should create a single transaction with gasPrice=0', async () => { - const { predictedSafe, accounts, contractNetworks } = await setupTests() - const [account1, account2] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { predictedSafe, accounts, contractNetworks, provider } = await setupTests() + const [, account2] = accounts + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -251,13 +247,12 @@ describe('Transactions creation', () => { }) it('should create a single transaction with gasPrice=0', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -282,13 +277,12 @@ describe('Transactions creation', () => { }) it('should create a single transaction with gasPrice>0', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -313,13 +307,12 @@ describe('Transactions creation', () => { }) it('should create a single transaction when passing a transaction array with length=1', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -335,13 +328,12 @@ describe('Transactions creation', () => { }) it('should create a single transaction when passing a transaction array with length=1 and options', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -364,13 +356,12 @@ describe('Transactions creation', () => { }) it('should fail when creating a MultiSend transaction passing a transaction array with length=0', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -379,13 +370,12 @@ describe('Transactions creation', () => { }) it('should create a MultiSend transaction', async () => { - const { accounts, contractNetworks, erc20Mintable, chainId } = await setupTests() + const { accounts, contractNetworks, erc20Mintable, chainId, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -414,13 +404,12 @@ describe('Transactions creation', () => { }) it('should create a MultiSend transaction with options', async () => { - const { accounts, contractNetworks, erc20Mintable, chainId } = await setupTests() + const { accounts, contractNetworks, erc20Mintable, chainId, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) const safeAddress = await safe.getAddress() - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -460,12 +449,10 @@ describe('Transactions creation', () => { itif(safeVersionDeployed < '1.3.0')( 'should fail to create a transaction if the Safe with version { - const { safe, predictedSafe, accounts, contractNetworks } = await setupTests() - const account = accounts[0] - const ethAdapter = await getEthAdapter(account.signer) + const { safe, predictedSafe, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) diff --git a/packages/protocol-kit/tests/e2e/createTransactionBatch.test.ts b/packages/protocol-kit/tests/e2e/createTransactionBatch.test.ts index e966a713f..0e4547b68 100644 --- a/packages/protocol-kit/tests/e2e/createTransactionBatch.test.ts +++ b/packages/protocol-kit/tests/e2e/createTransactionBatch.test.ts @@ -5,9 +5,9 @@ import { safeVersionDeployed } from '@safe-global/protocol-kit/hardhat/deploy/de import Safe, { PredictedSafeProps } from '@safe-global/protocol-kit/index' import { getContractNetworks } from './utils/setupContractNetworks' import { getERC20Mintable, getSafeWithOwners, getMultiSendCallOnly } from './utils/setupContracts' -import { getEthAdapter } from './utils/setupEthAdapter' +import { getEip1193Provider } from './utils/setupProvider' import { getAccounts } from './utils/setupTestNetwork' -import { OperationType } from 'packages/safe-core-sdk-types/dist/src' +import { OperationType } from '@safe-global/safe-core-sdk-types' chai.use(chaiAsPromised) @@ -44,11 +44,11 @@ describe('createTransactionBatch', () => { const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) + const provider = getEip1193Provider() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) diff --git a/packages/protocol-kit/tests/e2e/eip1271-contract-signatures.test.ts b/packages/protocol-kit/tests/e2e/eip1271-contract-signatures.test.ts index c7aac7a0c..6b8ddbc10 100644 --- a/packages/protocol-kit/tests/e2e/eip1271-contract-signatures.test.ts +++ b/packages/protocol-kit/tests/e2e/eip1271-contract-signatures.test.ts @@ -7,7 +7,7 @@ import chaiAsPromised from 'chai-as-promised' import { deployments } from 'hardhat' import { getContractNetworks } from './utils/setupContractNetworks' import { getSafeWithOwners } from './utils/setupContracts' -import { getEthAdapter } from './utils/setupEthAdapter' +import { getEip1193Provider } from './utils/setupProvider' import { getAccounts } from './utils/setupTestNetwork' import { waitSafeTxReceipt } from './utils/transactions' import { itif } from './utils/helpers' @@ -23,6 +23,7 @@ describe('The EIP1271 implementation', () => { const contractNetworks = await getContractNetworks(BigInt(chainId)) const fallbackHandlerAddress = contractNetworks[chainId].fallbackHandlerAddress const [account1, account2, account3, account4, account5] = accounts + const provider = getEip1193Provider() // Create a 1/1 signer Safe const signerSafe1_1 = await getSafeWithOwners( @@ -59,7 +60,8 @@ describe('The EIP1271 implementation', () => { accounts, contractNetworks, chainId, - fallbackHandlerAddress + fallbackHandlerAddress, + provider } }) @@ -71,20 +73,15 @@ describe('The EIP1271 implementation', () => { accounts, signerSafeAddress1_1, signerSafeAddress2_3, - contractNetworks + contractNetworks, + provider } = await setupTests() // Create adapters and the protocol kit instance const [account1, account2, account3, account4, account5] = accounts - const ethAdapter1 = await getEthAdapter(account1.signer) - const ethAdapter2 = await getEthAdapter(account2.signer) - const ethAdapter3 = await getEthAdapter(account3.signer) - const ethAdapter4 = await getEthAdapter(account4.signer) - const ethAdapter5 = await getEthAdapter(account5.signer) - - let protocolKit = await Safe.create({ - ethAdapter: ethAdapter1, + let protocolKit = await Safe.init({ + provider: provider, safeAddress, contractNetworks }) @@ -102,12 +99,14 @@ describe('The EIP1271 implementation', () => { // EOA signatures tx = await protocolKit.signTransaction(tx) // Owner 1 signature - protocolKit = await protocolKit.connect({ ethAdapter: ethAdapter2 }) // Connect another owner + protocolKit = await protocolKit.connect({ + signer: account2.address + }) // Connect another owner tx = await protocolKit.signTransaction(tx) // Owner 2 signature // 1/1 Signer Safe signature protocolKit = await protocolKit.connect({ - ethAdapter: ethAdapter3, + signer: account3.address, safeAddress: signerSafeAddress1_1 }) let signerSafeTx1_1 = await protocolKit.createTransaction({ @@ -126,7 +125,7 @@ describe('The EIP1271 implementation', () => { // 2/3 Signer Safe signature protocolKit = await protocolKit.connect({ - ethAdapter: ethAdapter4, + signer: account4.address, safeAddress: signerSafeAddress2_3 }) let signerSafeTx2_3 = await protocolKit.createTransaction({ @@ -137,7 +136,9 @@ describe('The EIP1271 implementation', () => { SigningMethod.SAFE_SIGNATURE, safeAddress ) - protocolKit = await protocolKit.connect({ ethAdapter: ethAdapter5 }) + protocolKit = await protocolKit.connect({ + signer: account5.address + }) signerSafeTx2_3 = await protocolKit.signTransaction( signerSafeTx2_3, SigningMethod.SAFE_SIGNATURE, @@ -154,7 +155,11 @@ describe('The EIP1271 implementation', () => { to: safeAddress, value: 1_000_000_000_000_000_000n // 1 ETH }) - protocolKit = await protocolKit.connect({ ethAdapter: ethAdapter1, safeAddress }) + protocolKit = await protocolKit.connect({ + provider: provider, + signer: account1.address, + safeAddress + }) const execResponse = await protocolKit.executeTransaction(tx) await waitSafeTxReceipt(execResponse) @@ -173,7 +178,8 @@ describe('The EIP1271 implementation', () => { signerSafeAddress1_1, signerSafeAddress2_3, contractNetworks, - chainId + chainId, + provider } = await setupTests() const MESSAGE = { @@ -226,14 +232,8 @@ describe('The EIP1271 implementation', () => { // Create adapters and the protocol kit instance const [account1, account2, account3, account4, account5] = accounts - const ethAdapter1 = await getEthAdapter(account1.signer) - const ethAdapter2 = await getEthAdapter(account2.signer) - const ethAdapter3 = await getEthAdapter(account3.signer) - const ethAdapter4 = await getEthAdapter(account4.signer) - const ethAdapter5 = await getEthAdapter(account5.signer) - - let protocolKit = await Safe.create({ - ethAdapter: ethAdapter1, + let protocolKit = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -242,12 +242,14 @@ describe('The EIP1271 implementation', () => { // EOA signatures message = await protocolKit.signMessage(message) // Owner 1 signature - protocolKit = await protocolKit.connect({ ethAdapter: ethAdapter2 }) // Connect another owner + protocolKit = await protocolKit.connect({ + signer: account2.address + }) // Connect another owner message = await protocolKit.signMessage(message) // Owner 2 signature // 1/1 Signer Safe signature protocolKit = await protocolKit.connect({ - ethAdapter: ethAdapter3, + signer: account3.address, safeAddress: signerSafeAddress1_1 }) let signerSafeMessage1_1 = protocolKit.createMessage(MESSAGE) @@ -264,7 +266,7 @@ describe('The EIP1271 implementation', () => { // 2/3 Signer Safe signature protocolKit = await protocolKit.connect({ - ethAdapter: ethAdapter4, + signer: account4.address, safeAddress: signerSafeAddress2_3 }) let signerSafeMessage2_3 = protocolKit.createMessage(MESSAGE) @@ -273,7 +275,9 @@ describe('The EIP1271 implementation', () => { SigningMethod.SAFE_SIGNATURE, safeAddress ) - protocolKit = await protocolKit.connect({ ethAdapter: ethAdapter5 }) + protocolKit = await protocolKit.connect({ + signer: account5.address + }) signerSafeMessage2_3 = await protocolKit.signMessage( signerSafeMessage2_3, SigningMethod.SAFE_SIGNATURE, @@ -286,7 +290,10 @@ describe('The EIP1271 implementation', () => { message.addSignature(signerSafeSig2_3) // Connect the original Safe - protocolKit = await protocolKit.connect({ ethAdapter: ethAdapter1, safeAddress }) + protocolKit = await protocolKit.connect({ + signer: account1.address, + safeAddress + }) chai.expect( await protocolKit.isValidSignature(hashSafeMessage(MESSAGE), message.encodedSignatures()) diff --git a/packages/protocol-kit/tests/e2e/eip1271.test.ts b/packages/protocol-kit/tests/e2e/eip1271.test.ts index 47f772272..307b639dd 100644 --- a/packages/protocol-kit/tests/e2e/eip1271.test.ts +++ b/packages/protocol-kit/tests/e2e/eip1271.test.ts @@ -14,7 +14,7 @@ import chaiAsPromised from 'chai-as-promised' import { deployments } from 'hardhat' import { getContractNetworks } from './utils/setupContractNetworks' import { getSafeWithOwners } from './utils/setupContracts' -import { getEthAdapter } from './utils/setupEthAdapter' +import { getEip1193Provider } from './utils/setupProvider' import { getAccounts } from './utils/setupTestNetwork' import { waitSafeTxReceipt } from './utils/transactions' import { itif } from './utils/helpers' @@ -48,6 +48,7 @@ describe('The EIP1271 implementation', () => { const contractNetworks = await getContractNetworks(BigInt(chainId)) const fallbackHandlerAddress = contractNetworks[chainId].fallbackHandlerAddress const [account1, account2] = accounts + const provider = getEip1193Provider() // Create a 1/2 Safe to sign the messages const signerSafe = await getSafeWithOwners( @@ -65,25 +66,24 @@ describe('The EIP1271 implementation', () => { ) const safeAddress = await safe.getAddress() - // Adapter and Safe instance for owner 1 - const ethAdapter1 = await getEthAdapter(account1.signer) - const safeSdk1 = await Safe.create({ - ethAdapter: ethAdapter1, + const safeSdk1 = await Safe.init({ + provider, safeAddress, contractNetworks }) // Adapter and Safe instance for owner 2 - const ethAdapter2 = await getEthAdapter(account2.signer) - const safeSdk2 = await Safe.create({ - ethAdapter: ethAdapter2, + const safeSdk2 = await Safe.init({ + provider, + signer: account2.address, safeAddress, contractNetworks }) // Adapter and Safe instance for owner 3 - const safeSdk3 = await Safe.create({ - ethAdapter: ethAdapter1, + const safeSdk3 = await Safe.init({ + provider, + signer: account1.address, safeAddress: signerSafeAddress, contractNetworks }) @@ -95,9 +95,8 @@ describe('The EIP1271 implementation', () => { signerSafeAddress, accounts, contractNetworks, + provider, chainId, - ethAdapter1, - ethAdapter2, safeSdk1, safeSdk2, safeSdk3, @@ -108,14 +107,14 @@ describe('The EIP1271 implementation', () => { itif(safeVersionDeployed >= '1.3.0')( 'should validate on-chain messages (Approved hashes)', async () => { - const { contractNetworks, safeSdk1, safeSdk2, ethAdapter1 } = await setupTests() + const { contractNetworks, safeSdk1, safeSdk2 } = await setupTests() const chainId = await safeSdk1.getChainId() const safeVersion = await safeSdk1.getContractVersion() const customContract = contractNetworks[chainId.toString()] - const signMessageLibContract = await ethAdapter1.getSignMessageLibContract({ + const signMessageLibContract = await safeSdk1.getSafeProvider().getSignMessageLibContract({ safeVersion, customContractAddress: customContract.signMessageLibAddress, customContractAbi: customContract.signMessageLibAbi @@ -380,7 +379,7 @@ describe('The EIP1271 implementation', () => { // EOA sign const safeMessage1 = safeSdk1.createMessage(MESSAGE) const signedMessage1: SafeMessage = await safeSdk1.signMessage(safeMessage1) - const signerAddress1 = (await safeSdk1.getEthAdapter().getSignerAddress()) as string + const signerAddress1 = (await safeSdk1.getSafeProvider().getSignerAddress()) as string const ethSig = signedMessage1.getSignature(signerAddress1) as EthSafeSignature // Signer Safe sign @@ -390,7 +389,7 @@ describe('The EIP1271 implementation', () => { SigningMethod.SAFE_SIGNATURE, safeAddress ) - const signerAddress2 = (await safeSdk3.getEthAdapter().getSignerAddress()) as string + const signerAddress2 = (await safeSdk3.getSafeProvider().getSignerAddress()) as string const safeSignerSig = await buildContractSignature( [signedMessage2.getSignature(signerAddress2) as EthSafeSignature], signerSafeAddress diff --git a/packages/protocol-kit/tests/e2e/erc-20.test.ts b/packages/protocol-kit/tests/e2e/erc-20.test.ts index d9018189b..5229e1ee8 100644 --- a/packages/protocol-kit/tests/e2e/erc-20.test.ts +++ b/packages/protocol-kit/tests/e2e/erc-20.test.ts @@ -1,4 +1,5 @@ import Safe, { + SafeProvider, createERC20TokenTransferTransaction, getERC20Decimals, isGasTokenCompatibleWithHandlePayment @@ -11,7 +12,7 @@ import sinonChai from 'sinon-chai' import { deployments } from 'hardhat' import { itif } from './utils/helpers' -import { getEthAdapter } from './utils/setupEthAdapter' +import { getEip1193Provider } from './utils/setupProvider' import { getContractNetworks } from './utils/setupContractNetworks' import { getSafeWithOwners } from './utils/setupContracts' import { getAccounts } from './utils/setupTestNetwork' @@ -23,16 +24,24 @@ chai.use(chaiAsPromised) const ERC20_TOKEN_ADDRESS = '0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d' describe('ERC-20 utils', () => { + let callStub: sinon.SinonStub + + afterEach(() => { + callStub.restore() + }) + const setupTests = deployments.createFixture(async ({ deployments, getChainId }) => { await deployments.fixture() const accounts = await getAccounts() const chainId = BigInt(await getChainId()) const contractNetworks = await getContractNetworks(chainId) + const provider = getEip1193Provider() return { safe: await getSafeWithOwners([accounts[0].address, accounts[1].address]), contractNetworks, - accounts + accounts, + provider } }) @@ -40,19 +49,15 @@ describe('ERC-20 utils', () => { itif(safeVersionDeployed >= '1.3.0')( 'should return the correct decimals for a standard ERC20 token', async () => { - const { safe, accounts, contractNetworks } = await setupTests() + const { safe, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const [account1] = accounts - - const ethAdapter = await getEthAdapter(account1.signer) - // mock decimals() call - sinon.stub(ethAdapter, 'call').returns(Promise.resolve('0x12')) + callStub = sinon.stub(SafeProvider.prototype, 'call').returns(Promise.resolve('0x12')) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -66,18 +71,14 @@ describe('ERC-20 utils', () => { itif(safeVersionDeployed >= '1.3.0')( 'should return the correct decimals for a non-standard ERC20 token', async () => { - const { safe, accounts, contractNetworks } = await setupTests() + const { safe, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const [account1] = accounts - - const ethAdapter = await getEthAdapter(account1.signer) - // mock decimals() call - sinon.stub(ethAdapter, 'call').returns(Promise.resolve('0x06')) + callStub = sinon.stub(SafeProvider.prototype, 'call').returns(Promise.resolve('0x06')) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -91,18 +92,14 @@ describe('ERC-20 utils', () => { itif(safeVersionDeployed >= '1.3.0')( 'should throw an error if decimals() fn is not defined', async () => { - const { safe, accounts, contractNetworks } = await setupTests() + const { safe, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const [account1] = accounts - - const ethAdapter = await getEthAdapter(account1.signer) - // mock decimals() call - sinon.stub(ethAdapter, 'call').returns(Promise.resolve('0x')) + callStub = sinon.stub(SafeProvider.prototype, 'call').returns(Promise.resolve('0x')) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -118,15 +115,11 @@ describe('ERC-20 utils', () => { itif(safeVersionDeployed >= '1.3.0')( 'should return true if it is the Native token', async () => { - const { safe, accounts, contractNetworks } = await setupTests() + const { safe, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const [account1] = accounts - - const ethAdapter = await getEthAdapter(account1.signer) - - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -143,18 +136,14 @@ describe('ERC-20 utils', () => { itif(safeVersionDeployed >= '1.3.0')( 'should return true if it is an standard ERC20 token', async () => { - const { safe, accounts, contractNetworks } = await setupTests() + const { safe, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const [account1] = accounts - - const ethAdapter = await getEthAdapter(account1.signer) - // mock decimals() call - sinon.stub(ethAdapter, 'call').returns(Promise.resolve('0x12')) + callStub = sinon.stub(SafeProvider.prototype, 'call').returns(Promise.resolve('0x12')) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -171,18 +160,14 @@ describe('ERC-20 utils', () => { itif(safeVersionDeployed >= '1.3.0')( 'should return false for a non-standard ERC20 token', async () => { - const { safe, accounts, contractNetworks } = await setupTests() + const { safe, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const [account1] = accounts - - const ethAdapter = await getEthAdapter(account1.signer) - // mock decimals() call - sinon.stub(ethAdapter, 'call').returns(Promise.resolve('0x06')) + callStub = sinon.stub(SafeProvider.prototype, 'call').returns(Promise.resolve('0x06')) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -202,11 +187,7 @@ describe('ERC-20 utils', () => { const toAddress = '0xbc2BB26a6d821e69A38016f3858561a1D80d4182' const amount = '12345' - const transfer = await createERC20TokenTransferTransaction( - ERC20_TOKEN_ADDRESS, - toAddress, - amount - ) + const transfer = createERC20TokenTransferTransaction(ERC20_TOKEN_ADDRESS, toAddress, amount) chai.expect(transfer).to.be.deep.equal({ to: ERC20_TOKEN_ADDRESS, diff --git a/packages/protocol-kit/tests/e2e/execution.test.ts b/packages/protocol-kit/tests/e2e/execution.test.ts index 0baf12792..45135b11d 100644 --- a/packages/protocol-kit/tests/e2e/execution.test.ts +++ b/packages/protocol-kit/tests/e2e/execution.test.ts @@ -1,17 +1,13 @@ import { safeVersionDeployed } from '@safe-global/protocol-kit/hardhat/deploy/deploy-contracts' -import Safe, { - EthersTransactionOptions, - SigningMethod, - Web3TransactionOptions -} from '@safe-global/protocol-kit/index' -import { MetaTransactionData, TransactionOptions } from '@safe-global/safe-core-sdk-types' +import Safe, { SigningMethod } from '@safe-global/protocol-kit/index' +import { TransactionOptions, MetaTransactionData } from '@safe-global/safe-core-sdk-types' import chai from 'chai' import chaiAsPromised from 'chai-as-promised' import { deployments } from 'hardhat' import { itif } from './utils/helpers' import { getContractNetworks } from './utils/setupContractNetworks' import { getERC20Mintable, getSafeWithOwners } from './utils/setupContracts' -import { getEthAdapter } from './utils/setupEthAdapter' +import { getEip1193Provider } from './utils/setupProvider' import { getAccounts } from './utils/setupTestNetwork' import { waitSafeTxReceipt } from './utils/transactions' @@ -23,29 +19,30 @@ describe('Transactions execution', () => { const accounts = await getAccounts() const chainId = BigInt(await getChainId()) const contractNetworks = await getContractNetworks(chainId) + const provider = getEip1193Provider() + return { erc20Mintable: await getERC20Mintable(), safe: await getSafeWithOwners([accounts[0].address, accounts[1].address]), accounts, - contractNetworks + contractNetworks, + provider } }) describe('isValidTransaction', async () => { it('should return false if a transaction will not be executed successfully', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) const safeAddress = await safe.getAddress() - const ethAdapter1 = await getEthAdapter(account1.signer) - const safeSdk1 = await Safe.create({ - ethAdapter: ethAdapter1, + const safeSdk1 = await Safe.init({ + provider, safeAddress, contractNetworks }) - const ethAdapter2 = await getEthAdapter(account2.signer) const safeSdk2 = await safeSdk1.connect({ - ethAdapter: ethAdapter2, + signer: account2.address, contractNetworks }) await account1.signer.sendTransaction({ @@ -71,13 +68,12 @@ describe('Transactions execution', () => { }) it('should return true if a transaction will execute successfully', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) const safeAddress = await safe.getAddress() - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk1 = await Safe.create({ - ethAdapter, + const safeSdk1 = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -101,13 +97,12 @@ describe('Transactions execution', () => { describe('executeTransaction', async () => { it('should fail if there are not enough Ether funds', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) const safeAddress = await safe.getAddress() - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk1 = await Safe.create({ - ethAdapter, + const safeSdk1 = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -125,18 +120,19 @@ describe('Transactions execution', () => { }) it('should fail if there are not enough signatures (1 missing)', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2, account3] = accounts const safe = await getSafeWithOwners([account1.address, account2.address, account3.address]) const safeAddress = await safe.getAddress() - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk1 = await Safe.create({ - ethAdapter, + const safeSdk1 = await Safe.init({ + provider, safeAddress, contractNetworks }) - const ethAdapter2 = await getEthAdapter(account2.signer) - const safeSdk2 = await safeSdk1.connect({ ethAdapter: ethAdapter2 }) + + const safeSdk2 = await safeSdk1.connect({ + signer: account2.address + }) const safeTransactionData = { to: safeAddress, value: '0', @@ -153,13 +149,12 @@ describe('Transactions execution', () => { }) it('should fail if there are not enough signatures (>1 missing)', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2, account3] = accounts const safe = await getSafeWithOwners([account1.address, account2.address, account3.address]) const safeAddress = await safe.getAddress() - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk1 = await Safe.create({ - ethAdapter, + const safeSdk1 = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -175,19 +170,17 @@ describe('Transactions execution', () => { }) it('should fail if the user tries to execute a transaction that was rejected', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) const safeAddress = await safe.getAddress() - const ethAdapter1 = await getEthAdapter(account1.signer) - const safeSdk1 = await Safe.create({ - ethAdapter: ethAdapter1, + const safeSdk1 = await Safe.init({ + provider, safeAddress, contractNetworks }) - const ethAdapter2 = await getEthAdapter(account2.signer) const safeSdk2 = await safeSdk1.connect({ - ethAdapter: ethAdapter2, + signer: account2.address, contractNetworks }) await account1.signer.sendTransaction({ @@ -205,46 +198,33 @@ describe('Transactions execution', () => { const txRejectResponse = await safeSdk2.executeTransaction(signedRejectTx) await waitSafeTxReceipt(txRejectResponse) const signedTx = await safeSdk1.signTransaction(tx) - await chai - .expect(safeSdk2.executeTransaction(signedTx)) - .to.be.rejectedWith(safeVersionDeployed >= '1.3.0' ? 'GS026' : 'Invalid owner provided') - }) - - it('should fail if a user tries to execute a transaction with options: { gas, gasLimit }', async () => { - const { accounts, contractNetworks } = await setupTests() - const [account1, account2] = accounts - const safe = await getSafeWithOwners([account1.address]) - const safeAddress = await safe.getAddress() - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk1 = await Safe.create({ - ethAdapter, - safeAddress, - contractNetworks - }) - await account1.signer.sendTransaction({ - to: safeAddress, - value: 1_000_000_000_000_000_000n // 1 ETH - }) - const safeTransactionData = { - to: account2.address, - value: '500000000000000000', // 0.5 ETH - data: '0x' + try { + await safeSdk2.executeTransaction(signedTx) + } catch (error) { + console.log(error) + } + if (process.env.ETH_LIB === 'viem') { + try { + await safeSdk2.executeTransaction(signedTx) + } catch (error) { + chai + .expect((error as any)?.info?.error?.message) + .includes(safeVersionDeployed >= '1.3.0' ? 'GS026' : 'Invalid owner provided') + } + } else { + await chai + .expect(safeSdk2.executeTransaction(signedTx)) + .to.be.rejectedWith(safeVersionDeployed >= '1.3.0' ? 'GS026' : 'Invalid owner provided') } - const tx = await safeSdk1.createTransaction({ transactions: [safeTransactionData] }) - const options: TransactionOptions = { gas: 123456, gasLimit: 123456 } - await chai - .expect(safeSdk1.executeTransaction(tx, options)) - .to.be.rejectedWith('Cannot specify gas and gasLimit together in transaction options') }) it('should fail if a user tries to execute a transaction with options: { nonce: }', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) const safeAddress = await safe.getAddress() - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk1 = await Safe.create({ - ethAdapter, + const safeSdk1 = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -258,20 +238,19 @@ describe('Transactions execution', () => { data: '0x' } const tx = await safeSdk1.createTransaction({ transactions: [safeTransactionData] }) - const execOptions: EthersTransactionOptions = { nonce: 123456789 } + const execOptions: TransactionOptions = { nonce: 123456789 } await chai .expect(safeSdk1.executeTransaction(tx, execOptions)) .to.be.rejectedWith('Nonce too high') }) it('should execute a transaction with threshold 1', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) const safeAddress = await safe.getAddress() - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk1 = await Safe.create({ - ethAdapter, + const safeSdk1 = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -298,7 +277,7 @@ describe('Transactions execution', () => { itif(process.env.ETH_LIB === 'web3' && safeVersionDeployed === '1.0.0')( 'should execute a transaction with threshold >1 and all different kind of signatures with web3 provider and safeVersion===1.0.0', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2, account3] = accounts const safe = await getSafeWithOwners([account1.address, account2.address, account3.address]) const safeAddress = await safe.getAddress() @@ -306,16 +285,17 @@ describe('Transactions execution', () => { to: safeAddress, value: 1_000_000_000_000_000_000n // 1 ETH }) - const ethAdapter1 = await getEthAdapter(account1.signer) - const ethAdapter2 = await getEthAdapter(account2.signer) - const ethAdapter3 = await getEthAdapter(account3.signer) - const safeSdk1 = await Safe.create({ - ethAdapter: ethAdapter1, + const safeSdk1 = await Safe.init({ + provider, safeAddress, contractNetworks }) - const safeSdk2 = await safeSdk1.connect({ ethAdapter: ethAdapter2 }) - const safeSdk3 = await safeSdk1.connect({ ethAdapter: ethAdapter3 }) + const safeSdk2 = await safeSdk1.connect({ + signer: account2.address + }) + const safeSdk3 = await safeSdk1.connect({ + signer: account3.address + }) const safeInitialBalance = await safeSdk1.getBalance() const safeTransactionData = { to: account2.address, @@ -345,7 +325,7 @@ describe('Transactions execution', () => { itif(process.env.ETH_LIB === 'web3' && safeVersionDeployed > '1.0.0')( 'should execute a transaction with threshold >1 and all different kind of signatures with web3 provider and safeVersion>1.0.0', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2, account3, account4] = accounts const safe = await getSafeWithOwners([ account1.address, @@ -358,18 +338,20 @@ describe('Transactions execution', () => { to: safeAddress, value: 1_000_000_000_000_000_000n // 1 ETH }) - const ethAdapter1 = await getEthAdapter(account1.signer) - const ethAdapter2 = await getEthAdapter(account2.signer) - const ethAdapter3 = await getEthAdapter(account3.signer) - const ethAdapter4 = await getEthAdapter(account4.signer) - const safeSdk1 = await Safe.create({ - ethAdapter: ethAdapter1, + const safeSdk1 = await Safe.init({ + provider, safeAddress, contractNetworks }) - const safeSdk2 = await safeSdk1.connect({ ethAdapter: ethAdapter2 }) - const safeSdk3 = await safeSdk1.connect({ ethAdapter: ethAdapter3 }) - const safeSdk4 = await safeSdk1.connect({ ethAdapter: ethAdapter4 }) + const safeSdk2 = await safeSdk1.connect({ + signer: account2.address + }) + const safeSdk3 = await safeSdk1.connect({ + signer: account3.address + }) + const safeSdk4 = await safeSdk1.connect({ + signer: account4.address + }) const safeInitialBalance = await safeSdk1.getBalance() const safeTransactionData = { to: account2.address, @@ -394,6 +376,7 @@ describe('Transactions execution', () => { const txResponse2 = await safeSdk1.executeTransaction(signedTx) await waitSafeTxReceipt(txResponse2) + await new Promise((resolve) => setTimeout(resolve, 500)) const safeFinalBalance = await safeSdk1.getBalance() chai.expect(safeInitialBalance).to.be.eq(safeFinalBalance + BigInt(tx.data.value)) } @@ -402,7 +385,7 @@ describe('Transactions execution', () => { itif(process.env.ETH_LIB === 'ethers' && safeVersionDeployed === '1.0.0')( 'should execute a transaction with threshold >1 and all different kind of signatures with ethers provider and safeVersion===1.0.0', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2, account3, account4, account5] = accounts const safe = await getSafeWithOwners([ account1.address, @@ -416,20 +399,23 @@ describe('Transactions execution', () => { to: safeAddress, value: 1_000_000_000_000_000_000n // 1 ETH }) - const ethAdapter1 = await getEthAdapter(account1.signer) - const ethAdapter2 = await getEthAdapter(account2.signer) - const ethAdapter3 = await getEthAdapter(account3.signer) - const ethAdapter4 = await getEthAdapter(account4.signer) - const ethAdapter5 = await getEthAdapter(account5.signer) - const safeSdk1 = await Safe.create({ - ethAdapter: ethAdapter1, + const safeSdk1 = await Safe.init({ + provider, safeAddress, contractNetworks }) - const safeSdk2 = await safeSdk1.connect({ ethAdapter: ethAdapter2 }) - const safeSdk3 = await safeSdk1.connect({ ethAdapter: ethAdapter3 }) - const safeSdk4 = await safeSdk1.connect({ ethAdapter: ethAdapter4 }) - const safeSdk5 = await safeSdk1.connect({ ethAdapter: ethAdapter5 }) + const safeSdk2 = await safeSdk1.connect({ + signer: account2.address + }) + const safeSdk3 = await safeSdk1.connect({ + signer: account3.address + }) + const safeSdk4 = await safeSdk1.connect({ + signer: account4.address + }) + const safeSdk5 = await safeSdk1.connect({ + signer: account5.address + }) const safeInitialBalance = await safeSdk1.getBalance() const safeTransactionData = { to: account2.address, @@ -465,7 +451,7 @@ describe('Transactions execution', () => { itif(process.env.ETH_LIB === 'ethers' && safeVersionDeployed > '1.0.0')( 'should execute a transaction with threshold >1 and all different kind of signatures with ethers provider and safeVersion>1.0.0', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2, account3, account4, account5, account6] = accounts const safe = await getSafeWithOwners([ account1.address, @@ -480,22 +466,26 @@ describe('Transactions execution', () => { to: safeAddress, value: 1_000_000_000_000_000_000n // 1 ETH }) - const ethAdapter1 = await getEthAdapter(account1.signer) - const ethAdapter2 = await getEthAdapter(account2.signer) - const ethAdapter3 = await getEthAdapter(account3.signer) - const ethAdapter4 = await getEthAdapter(account4.signer) - const ethAdapter5 = await getEthAdapter(account5.signer) - const ethAdapter6 = await getEthAdapter(account6.signer) - const safeSdk1 = await Safe.create({ - ethAdapter: ethAdapter1, + const safeSdk1 = await Safe.init({ + provider, safeAddress, contractNetworks }) - const safeSdk2 = await safeSdk1.connect({ ethAdapter: ethAdapter2 }) - const safeSdk3 = await safeSdk1.connect({ ethAdapter: ethAdapter3 }) - const safeSdk4 = await safeSdk1.connect({ ethAdapter: ethAdapter4 }) - const safeSdk5 = await safeSdk1.connect({ ethAdapter: ethAdapter5 }) - const safeSdk6 = await safeSdk1.connect({ ethAdapter: ethAdapter6 }) + const safeSdk2 = await safeSdk1.connect({ + signer: account2.address + }) + const safeSdk3 = await safeSdk1.connect({ + signer: account3.address + }) + const safeSdk4 = await safeSdk1.connect({ + signer: account4.address + }) + const safeSdk5 = await safeSdk1.connect({ + signer: account5.address + }) + const safeSdk6 = await safeSdk1.connect({ + signer: account6.address + }) const safeInitialBalance = await safeSdk1.getBalance() const safeTransactionData = { to: account2.address, @@ -532,19 +522,22 @@ describe('Transactions execution', () => { ) it('should execute a transaction when is not submitted by an owner', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1, account2, account3] = accounts - const ethAdapter1 = await getEthAdapter(account1.signer) + const { safe, accounts, contractNetworks, provider } = await setupTests() + const [, account2, account3] = accounts const safeAddress = await safe.getAddress() - const safeSdk1 = await Safe.create({ - ethAdapter: ethAdapter1, + const safeSdk1 = await Safe.init({ + provider, safeAddress, contractNetworks }) - const ethAdapter2 = await getEthAdapter(account2.signer) - const safeSdk2 = await safeSdk1.connect({ ethAdapter: ethAdapter2 }) - const ethAdapter3 = await getEthAdapter(account3.signer) - const safeSdk3 = await safeSdk1.connect({ ethAdapter: ethAdapter3 }) + const safeSdk2 = await safeSdk1.connect({ + signer: account2.address + }) + + const safeSdk3 = await safeSdk1.connect({ + signer: account3.address + }) + await account2.signer.sendTransaction({ to: safeAddress, value: 1_000_000_000_000_000_000n // 1 ETH @@ -569,13 +562,12 @@ describe('Transactions execution', () => { itif(process.env.ETH_LIB === 'ethers')( 'should execute a transaction with options: { gasLimit }', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) const safeAddress = await safe.getAddress() - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk1 = await Safe.create({ - ethAdapter, + const safeSdk1 = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -589,10 +581,10 @@ describe('Transactions execution', () => { data: '0x' } const tx = await safeSdk1.createTransaction({ transactions: [safeTransactionData] }) - const execOptions: EthersTransactionOptions = { gasLimit: 123456 } + const execOptions: TransactionOptions = { gasLimit: 123456 } const txResponse = await safeSdk1.executeTransaction(tx, execOptions) await waitSafeTxReceipt(txResponse) - const txConfirmed = await ethAdapter.getTransaction(txResponse.hash) + const txConfirmed = await safeSdk1.getSafeProvider().getTransaction(txResponse.hash) chai.expect(execOptions.gasLimit).to.be.eq(Number(txConfirmed.gasLimit)) } ) @@ -600,13 +592,12 @@ describe('Transactions execution', () => { itif(process.env.ETH_LIB === 'ethers')( 'should execute a transaction with options: { gasLimit, gasPrice }', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) const safeAddress = await safe.getAddress() - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk1 = await Safe.create({ - ethAdapter, + const safeSdk1 = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -620,13 +611,13 @@ describe('Transactions execution', () => { data: '0x' } const tx = await safeSdk1.createTransaction({ transactions: [safeTransactionData] }) - const execOptions: EthersTransactionOptions = { + const execOptions: TransactionOptions = { gasLimit: 123456, gasPrice: 170000000 } const txResponse = await safeSdk1.executeTransaction(tx, execOptions) await waitSafeTxReceipt(txResponse) - const txConfirmed = await ethAdapter.getTransaction(txResponse.hash) + const txConfirmed = await safeSdk1.getSafeProvider().getTransaction(txResponse.hash) chai.expect(execOptions.gasPrice).to.be.eq(Number(txConfirmed.gasPrice)) chai.expect(execOptions.gasLimit).to.be.eq(Number(txConfirmed.gasLimit)) } @@ -635,13 +626,12 @@ describe('Transactions execution', () => { itif(process.env.ETH_LIB === 'ethers')( 'should execute a transaction with options: { maxFeePerGas, maxPriorityFeePerGas }', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) const safeAddress = await safe.getAddress() - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk1 = await Safe.create({ - ethAdapter, + const safeSdk1 = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -661,7 +651,7 @@ describe('Transactions execution', () => { } const txResponse = await safeSdk1.executeTransaction(tx, execOptions) await waitSafeTxReceipt(txResponse) - const txConfirmed = await ethAdapter.getTransaction(txResponse.hash) + const txConfirmed = await safeSdk1.getSafeProvider().getTransaction(txResponse.hash) chai.expect(BigInt(execOptions.maxFeePerGas)).to.be.eq(txConfirmed.maxFeePerGas) chai .expect(BigInt(execOptions.maxPriorityFeePerGas)) @@ -670,46 +660,14 @@ describe('Transactions execution', () => { ) itif(process.env.ETH_LIB === 'web3')( - 'should execute a transaction with options: { gas }', - async () => { - const { accounts, contractNetworks } = await setupTests() - const [account1, account2] = accounts - const safe = await getSafeWithOwners([account1.address]) - const safeAddress = await safe.getAddress() - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk1 = await Safe.create({ - ethAdapter, - safeAddress, - contractNetworks - }) - await account1.signer.sendTransaction({ - to: safeAddress, - value: 1_000_000_000_000_000_000n // 1 ETH - }) - const safeTransactionData = { - to: account2.address, - value: '500000000000000000', // 0.5 ETH - data: '0x' - } - const tx = await safeSdk1.createTransaction({ transactions: [safeTransactionData] }) - const execOptions: Web3TransactionOptions = { gas: 123456 } - const txResponse = await safeSdk1.executeTransaction(tx, execOptions) - await waitSafeTxReceipt(txResponse) - const txConfirmed = await ethAdapter.getTransaction(txResponse.hash) - chai.expect(execOptions.gas).to.be.eq(txConfirmed.gas) - } - ) - - itif(process.env.ETH_LIB === 'web3')( - 'should execute a transaction with options: { gas, gasPrice }', + 'should execute a transaction with options: { gasPrice }', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) const safeAddress = await safe.getAddress() - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk1 = await Safe.create({ - ethAdapter, + const safeSdk1 = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -723,28 +681,26 @@ describe('Transactions execution', () => { data: '0x' } const tx = await safeSdk1.createTransaction({ transactions: [safeTransactionData] }) - const execOptions: Web3TransactionOptions = { + const execOptions = { gas: 123456, gasPrice: 170000000 } const txResponse = await safeSdk1.executeTransaction(tx, execOptions) await waitSafeTxReceipt(txResponse) - const txConfirmed = await ethAdapter.getTransaction(txResponse.hash) + const txConfirmed = await safeSdk1.getSafeProvider().getTransaction(txResponse.hash) chai.expect(execOptions.gasPrice).to.be.eq(Number(txConfirmed.gasPrice)) - chai.expect(execOptions.gas).to.be.eq(txConfirmed.gas) } ) itif(process.env.ETH_LIB === 'web3')( 'should execute a transaction with options: { maxFeePerGas, maxPriorityFeePerGas }', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) const safeAddress = await safe.getAddress() - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk1 = await Safe.create({ - ethAdapter, + const safeSdk1 = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -764,7 +720,7 @@ describe('Transactions execution', () => { } const txResponse = await safeSdk1.executeTransaction(tx, execOptions) await waitSafeTxReceipt(txResponse) - const txConfirmed = await ethAdapter.getTransaction(txResponse.hash) + const txConfirmed = await safeSdk1.getSafeProvider().getTransaction(txResponse.hash) chai.expect(BigInt(execOptions.maxFeePerGas)).to.be.eq(BigInt(txConfirmed.maxFeePerGas)) chai .expect(BigInt(execOptions.maxPriorityFeePerGas)) @@ -773,13 +729,12 @@ describe('Transactions execution', () => { ) it('should execute a transaction with options: { nonce }', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) const safeAddress = await safe.getAddress() - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk1 = await Safe.create({ - ethAdapter, + const safeSdk1 = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -792,32 +747,35 @@ describe('Transactions execution', () => { value: '500000000000000000', // 0.5 ETH data: '0x' } - const currentNonce = await ethAdapter.getNonce(account1.address, 'pending') + const currentNonce = await safeSdk1.getSafeProvider().getNonce(account1.address, 'pending') const tx = await safeSdk1.createTransaction({ transactions: [safeTransactionData] }) - const execOptions: EthersTransactionOptions = { nonce: currentNonce } + const execOptions: TransactionOptions = { nonce: currentNonce } const txResponse = await safeSdk1.executeTransaction(tx, execOptions) await waitSafeTxReceipt(txResponse) - const txConfirmed = await ethAdapter.getTransaction(txResponse.hash) + const txConfirmed = await safeSdk1.getSafeProvider().getTransaction(txResponse.hash) chai.expect(execOptions.nonce).to.be.eq(txConfirmed.nonce) }) }) describe('executeTransaction (MultiSend)', async () => { it('should execute a batch transaction with threshold >1', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2, account3] = accounts const safe = await getSafeWithOwners([account1.address, account2.address, account3.address]) const safeAddress = await safe.getAddress() - const ethAdapter1 = await getEthAdapter(account1.signer) - const safeSdk1 = await Safe.create({ - ethAdapter: ethAdapter1, + const safeSdk1 = await Safe.init({ + provider, safeAddress, contractNetworks }) - const ethAdapter2 = await getEthAdapter(account2.signer) - const safeSdk2 = await safeSdk1.connect({ ethAdapter: ethAdapter2 }) - const ethAdapter3 = await getEthAdapter(account3.signer) - const safeSdk3 = await safeSdk1.connect({ ethAdapter: ethAdapter3 }) + + const safeSdk2 = await safeSdk1.connect({ + signer: account2.address + }) + + const safeSdk3 = await safeSdk1.connect({ + signer: account3.address + }) await account1.signer.sendTransaction({ to: safeAddress, value: 2_000_000_000_000_000_000n // 2 ETH @@ -849,20 +807,23 @@ describe('Transactions execution', () => { }) it('should execute a batch transaction with contract calls and threshold >1', async () => { - const { accounts, contractNetworks, erc20Mintable } = await setupTests() + const { accounts, contractNetworks, erc20Mintable, provider } = await setupTests() const [account1, account2, account3] = accounts const safe = await getSafeWithOwners([account1.address, account2.address, account3.address]) const safeAddress = await safe.getAddress() - const ethAdapter1 = await getEthAdapter(account1.signer) - const safeSdk1 = await Safe.create({ - ethAdapter: ethAdapter1, + const safeSdk1 = await Safe.init({ + provider, safeAddress, contractNetworks }) - const ethAdapter2 = await getEthAdapter(account2.signer) - const safeSdk2 = await safeSdk1.connect({ ethAdapter: ethAdapter2 }) - const ethAdapter3 = await getEthAdapter(account3.signer) - const safeSdk3 = await safeSdk1.connect({ ethAdapter: ethAdapter3 }) + + const safeSdk2 = await safeSdk1.connect({ + signer: account2.address + }) + + const safeSdk3 = await safeSdk1.connect({ + signer: account3.address + }) await erc20Mintable.mint(safeAddress, '1200000000000000000') // 1.2 ERC20 const safeInitialERC20Balance = await erc20Mintable.balanceOf(safeAddress) diff --git a/packages/protocol-kit/tests/e2e/fallbackHandlerManager.test.ts b/packages/protocol-kit/tests/e2e/fallbackHandlerManager.test.ts index 3adcc3159..bfd136163 100644 --- a/packages/protocol-kit/tests/e2e/fallbackHandlerManager.test.ts +++ b/packages/protocol-kit/tests/e2e/fallbackHandlerManager.test.ts @@ -14,7 +14,7 @@ import { getDefaultCallbackHandler, getSafeWithOwners } from './utils/setupContracts' -import { getEthAdapter } from './utils/setupEthAdapter' +import { getEip1193Provider } from './utils/setupProvider' import { getAccounts } from './utils/setupTestNetwork' import { waitSafeTxReceipt } from './utils/transactions' @@ -35,12 +35,15 @@ describe('Fallback handler manager', () => { safeVersion: safeVersionDeployed } } + const provider = getEip1193Provider() + return { safe: await getSafeWithOwners([accounts[0].address]), accounts, contractNetworks, defaultCallbackHandler: await getDefaultCallbackHandler(), - predictedSafe + predictedSafe, + provider } }) @@ -48,12 +51,10 @@ describe('Fallback handler manager', () => { itif(safeVersionDeployed < '1.1.1')( 'should fail if getting the enabled fallback handler is not supported', async () => { - const { safe, accounts, contractNetworks } = await setupTests() + const { safe, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -67,11 +68,9 @@ describe('Fallback handler manager', () => { ) itif(safeVersionDeployed >= '1.1.1')('should fail if the Safe is not deployed', async () => { - const { predictedSafe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { predictedSafe, contractNetworks, provider } = await setupTests() + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -79,12 +78,10 @@ describe('Fallback handler manager', () => { }) itif(safeVersionDeployed >= '1.1.1')('should return the enabled fallback handler', async () => { - const { safe, accounts, contractNetworks, defaultCallbackHandler } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, defaultCallbackHandler, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -107,12 +104,10 @@ describe('Fallback handler manager', () => { itif(safeVersionDeployed < '1.3.0')( 'should fail if the Safe with version { - const { predictedSafe, accounts, contractNetworks, defaultCallbackHandler } = + const { predictedSafe, contractNetworks, defaultCallbackHandler, provider } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -128,12 +123,10 @@ describe('Fallback handler manager', () => { itif(safeVersionDeployed >= '1.3.0')( 'should fail if the Safe with version >=v1.3.0 is not deployed', async () => { - const { predictedSafe, accounts, contractNetworks, defaultCallbackHandler } = + const { predictedSafe, contractNetworks, defaultCallbackHandler, provider } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -145,12 +138,10 @@ describe('Fallback handler manager', () => { itif(safeVersionDeployed < '1.1.1')( 'should fail if enabling a fallback handler is not supported', async () => { - const { safe, accounts, contractNetworks, defaultCallbackHandler } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, defaultCallbackHandler, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -164,12 +155,10 @@ describe('Fallback handler manager', () => { ) itif(safeVersionDeployed >= '1.1.1')('should fail if address is invalid', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -180,12 +169,10 @@ describe('Fallback handler manager', () => { itif(safeVersionDeployed >= '1.1.1')( 'should fail if address is equal to 0x address', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -195,12 +182,10 @@ describe('Fallback handler manager', () => { ) itif(safeVersionDeployed >= '1.1.1')('should fail if address is already enabled', async () => { - const { safe, accounts, contractNetworks, defaultCallbackHandler } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, defaultCallbackHandler, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -216,12 +201,10 @@ describe('Fallback handler manager', () => { itif(safeVersionDeployed >= '1.1.1')( 'should build the transaction with the optional props', async () => { - const { safe, accounts, contractNetworks, defaultCallbackHandler } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, defaultCallbackHandler, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -247,12 +230,10 @@ describe('Fallback handler manager', () => { ) itif(safeVersionDeployed >= '1.1.1')('should enable a fallback handler', async () => { - const { safe, accounts, contractNetworks, defaultCallbackHandler } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, defaultCallbackHandler, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -275,11 +256,9 @@ describe('Fallback handler manager', () => { itif(safeVersionDeployed < '1.3.0')( 'should fail if the Safe with version { - const { predictedSafe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { predictedSafe, contractNetworks, provider } = await setupTests() + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -295,12 +274,10 @@ describe('Fallback handler manager', () => { itif(safeVersionDeployed >= '1.3.0')( 'should fail if the Safe with version >=v1.3.0 is not deployed', async () => { - const { predictedSafe, accounts, contractNetworks, defaultCallbackHandler } = + const { predictedSafe, contractNetworks, defaultCallbackHandler, provider } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -312,13 +289,12 @@ describe('Fallback handler manager', () => { itif(safeVersionDeployed < '1.1.1')( 'should fail if disabling a fallback handler is not supported', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1] = accounts const safe = await getSafeWithOwners([account1.address]) const safeAddress = await safe.getAddress() - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -334,12 +310,10 @@ describe('Fallback handler manager', () => { itif(safeVersionDeployed >= '1.1.1')( 'should fail if no fallback handler is enabled', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -357,13 +331,12 @@ describe('Fallback handler manager', () => { itif(safeVersionDeployed >= '1.1.1')( 'should build the transaction with the optional props', async () => { - const { accounts, contractNetworks, defaultCallbackHandler } = await setupTests() + const { accounts, contractNetworks, defaultCallbackHandler, provider } = await setupTests() const [account1] = accounts const safe = await getSafeWithOwners([account1.address]) const safeAddress = await safe.getAddress() - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -395,13 +368,12 @@ describe('Fallback handler manager', () => { ) itif(safeVersionDeployed >= '1.1.1')('should disable an enabled fallback handler', async () => { - const { accounts, contractNetworks, defaultCallbackHandler } = await setupTests() + const { accounts, contractNetworks, defaultCallbackHandler, provider } = await setupTests() const [account1] = accounts const safe = await getSafeWithOwners([account1.address]) const safeAddress = await safe.getAddress() - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -411,6 +383,7 @@ describe('Fallback handler manager', () => { ) const txResponse = await safeSdk.executeTransaction(tx) await waitSafeTxReceipt(txResponse) + await new Promise((resolve) => setTimeout(resolve, 500)) chai .expect(await safeSdk.getFallbackHandler()) .to.be.eq(await defaultCallbackHandler.getAddress()) diff --git a/packages/protocol-kit/tests/e2e/getEncodedTransaction.test.ts b/packages/protocol-kit/tests/e2e/getEncodedTransaction.test.ts index 1f4056ec6..7ddeb3c19 100644 --- a/packages/protocol-kit/tests/e2e/getEncodedTransaction.test.ts +++ b/packages/protocol-kit/tests/e2e/getEncodedTransaction.test.ts @@ -4,7 +4,7 @@ import chai from 'chai' import { deployments } from 'hardhat' import { getContractNetworks } from './utils/setupContractNetworks' import { getSafeWithOwners } from './utils/setupContracts' -import { getEthAdapter } from './utils/setupEthAdapter' +import { getEip1193Provider } from './utils/setupProvider' import { getAccounts } from './utils/setupTestNetwork' import { itif } from './utils/helpers' @@ -14,22 +14,24 @@ describe('getEncodedTransaction', () => { const accounts = await getAccounts() const chainId = BigInt(await getChainId()) const contractNetworks = await getContractNetworks(chainId) + const provider = getEip1193Provider() + return { accounts, - contractNetworks + contractNetworks, + provider } }) itif(safeVersionDeployed >= '1.3.0')('should return a transaction encoded', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) const safeAddress = await safe.getAddress() - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -52,15 +54,14 @@ describe('getEncodedTransaction', () => { }) itif(safeVersionDeployed <= '1.2.0')('should return a transaction encoded', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) const safeAddress = await safe.getAddress() - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -83,15 +84,14 @@ describe('getEncodedTransaction', () => { }) it('should return a signed transaction with the signatures encoded', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) const safeAddress = await safe.getAddress() - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) diff --git a/packages/protocol-kit/tests/e2e/guardManager.test.ts b/packages/protocol-kit/tests/e2e/guardManager.test.ts index 1d723acf5..50b830a5a 100644 --- a/packages/protocol-kit/tests/e2e/guardManager.test.ts +++ b/packages/protocol-kit/tests/e2e/guardManager.test.ts @@ -10,7 +10,7 @@ import { deployments } from 'hardhat' import { itif } from './utils/helpers' import { getContractNetworks } from './utils/setupContractNetworks' import { getDebugTransactionGuard, getSafeWithOwners } from './utils/setupContracts' -import { getEthAdapter } from './utils/setupEthAdapter' +import { getEip1193Provider } from './utils/setupProvider' import { getAccounts } from './utils/setupTestNetwork' import { waitSafeTxReceipt } from './utils/transactions' @@ -22,6 +22,7 @@ describe('Safe guard manager', () => { const accounts = await getAccounts() const chainId = BigInt(await getChainId()) const contractNetworks = await getContractNetworks(chainId) + const provider = getEip1193Provider() const predictedSafe: PredictedSafeProps = { safeAccountConfig: { owners: [accounts[0].address], @@ -36,7 +37,8 @@ describe('Safe guard manager', () => { safe: await getSafeWithOwners([accounts[0].address]), accounts, contractNetworks, - predictedSafe + predictedSafe, + provider } }) @@ -44,12 +46,10 @@ describe('Safe guard manager', () => { itif(safeVersionDeployed < '1.3.0')( 'should fail if getting the enabled guard is not supported', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -63,11 +63,9 @@ describe('Safe guard manager', () => { ) itif(safeVersionDeployed >= '1.3.0')('should fail if the Safe is not deployed', async () => { - const { predictedSafe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { predictedSafe, contractNetworks, provider } = await setupTests() + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -77,12 +75,10 @@ describe('Safe guard manager', () => { itif(safeVersionDeployed >= '1.3.0')( 'should return 0x address when no Safe guard is enabled', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -91,12 +87,10 @@ describe('Safe guard manager', () => { ) itif(safeVersionDeployed >= '1.3.0')('should return the enabled Safe guard', async () => { - const { safe, accounts, contractNetworks, debugTransactionGuard } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, debugTransactionGuard, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -112,12 +106,10 @@ describe('Safe guard manager', () => { itif(safeVersionDeployed < '1.3.0')( 'should fail if enabling a Safe guard is not supported', async () => { - const { safe, accounts, contractNetworks, debugTransactionGuard } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, debugTransactionGuard, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -131,12 +123,11 @@ describe('Safe guard manager', () => { ) itif(safeVersionDeployed >= '1.3.0')('should fail if the Safe is not deployed', async () => { - const { predictedSafe, accounts, debugTransactionGuard, contractNetworks } = + const { predictedSafe, debugTransactionGuard, contractNetworks, provider } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -145,12 +136,10 @@ describe('Safe guard manager', () => { }) itif(safeVersionDeployed >= '1.3.0')('should fail if address is invalid', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -161,12 +150,11 @@ describe('Safe guard manager', () => { itif(safeVersionDeployed >= '1.3.0')( 'should fail if address is equal to 0x address', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, provider } = await setupTests() + const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -176,12 +164,11 @@ describe('Safe guard manager', () => { ) itif(safeVersionDeployed >= '1.3.0')('should fail if address is already enabled', async () => { - const { safe, accounts, contractNetworks, debugTransactionGuard } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, debugTransactionGuard, provider } = await setupTests() + const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -195,12 +182,11 @@ describe('Safe guard manager', () => { itif(safeVersionDeployed >= '1.3.0')( 'should build the transaction with the optional props', async () => { - const { safe, accounts, contractNetworks, debugTransactionGuard } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, debugTransactionGuard, provider } = await setupTests() + const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -226,12 +212,11 @@ describe('Safe guard manager', () => { ) itif(safeVersionDeployed >= '1.3.0')('should enable a Safe guard', async () => { - const { safe, accounts, contractNetworks, debugTransactionGuard } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, debugTransactionGuard, provider } = await setupTests() + const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -247,13 +232,12 @@ describe('Safe guard manager', () => { itif(safeVersionDeployed < '1.3.0')( 'should fail if disabling a Safe guard is not supported', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -267,11 +251,10 @@ describe('Safe guard manager', () => { ) itif(safeVersionDeployed >= '1.3.0')('should fail if the Safe is not deployed', async () => { - const { accounts, predictedSafe, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { predictedSafe, contractNetworks, provider } = await setupTests() + + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -280,12 +263,11 @@ describe('Safe guard manager', () => { }) itif(safeVersionDeployed >= '1.3.0')('should fail if no Safe guard is enabled', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, provider } = await setupTests() + const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -296,13 +278,12 @@ describe('Safe guard manager', () => { itif(safeVersionDeployed >= '1.3.0')( 'should build the transaction with the optional props', async () => { - const { accounts, contractNetworks, debugTransactionGuard } = await setupTests() + const { accounts, contractNetworks, debugTransactionGuard, provider } = await setupTests() const [account1] = accounts const safe = await getSafeWithOwners([account1.address]) const safeAddress = await safe.getAddress() - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -329,13 +310,12 @@ describe('Safe guard manager', () => { ) itif(safeVersionDeployed >= '1.3.0')('should disable an enabled Safe guard', async () => { - const { accounts, contractNetworks, debugTransactionGuard } = await setupTests() + const { accounts, contractNetworks, debugTransactionGuard, provider } = await setupTests() const [account1] = accounts const safe = await getSafeWithOwners([account1.address]) const safeAddress = await safe.getAddress() - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) diff --git a/packages/protocol-kit/tests/e2e/moduleManager.test.ts b/packages/protocol-kit/tests/e2e/moduleManager.test.ts index c9366938a..40881c571 100644 --- a/packages/protocol-kit/tests/e2e/moduleManager.test.ts +++ b/packages/protocol-kit/tests/e2e/moduleManager.test.ts @@ -11,11 +11,14 @@ import { getContractNetworks } from './utils/setupContractNetworks' import { getDailyLimitModule, getSafeWithOwners, - getSocialRecoveryModule + getSocialRecoveryModule, + getStateChannelModule, + getWhiteListModule } from './utils/setupContracts' -import { getEthAdapter } from './utils/setupEthAdapter' +import { getEip1193Provider } from './utils/setupProvider' import { getAccounts } from './utils/setupTestNetwork' import { waitSafeTxReceipt } from './utils/transactions' +import semverSatisfies from 'semver/functions/satisfies' chai.use(chaiAsPromised) @@ -34,23 +37,26 @@ describe('Safe modules manager', () => { safeVersion: safeVersionDeployed } } + const provider = getEip1193Provider() + return { dailyLimitModule: await getDailyLimitModule(), socialRecoveryModule: await getSocialRecoveryModule(), + stateChannelModule: await getStateChannelModule(), + whiteListModule: await getWhiteListModule(), safe: await getSafeWithOwners([accounts[0].address]), accounts, contractNetworks, - predictedSafe + predictedSafe, + provider } }) describe('getModules', async () => { it('should fail if the Safe is not deployed', async () => { - const { predictedSafe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { predictedSafe, contractNetworks, provider } = await setupTests() + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -58,30 +64,38 @@ describe('Safe modules manager', () => { }) it('should return all the enabled modules', async () => { - const { safe, accounts, dailyLimitModule, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, dailyLimitModule, socialRecoveryModule, contractNetworks, provider } = + await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) chai.expect((await safeSdk.getModules()).length).to.be.eq(0) - const tx = await safeSdk.createEnableModuleTx(await dailyLimitModule.getAddress()) - const txResponse = await safeSdk.executeTransaction(tx) - await waitSafeTxReceipt(txResponse) - chai.expect((await safeSdk.getModules()).length).to.be.eq(1) + const enableDailyLimitModuleTx = await safeSdk.createEnableModuleTx( + await dailyLimitModule.getAddress() + ) + const enableDailyLimitModuleTxResponse = + await safeSdk.executeTransaction(enableDailyLimitModuleTx) + const socialRecoveryModuleTx = await safeSdk.createEnableModuleTx( + await socialRecoveryModule.getAddress() + ) + const socialRecoveryModuleTxResponse = + await safeSdk.executeTransaction(socialRecoveryModuleTx) + await Promise.all([ + waitSafeTxReceipt(enableDailyLimitModuleTxResponse), + waitSafeTxReceipt(socialRecoveryModuleTxResponse) + ]) + chai.expect((await safeSdk.getModules()).length).to.be.eq(2) }) }) describe('getModulesPaginated', async () => { it('should fail if the Safe is not deployed', async () => { - const { predictedSafe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { predictedSafe, contractNetworks, provider } = await setupTests() + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -91,83 +105,149 @@ describe('Safe modules manager', () => { }) it('should return the enabled modules', async () => { - const { safe, accounts, dailyLimitModule, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, dailyLimitModule, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) - chai.expect((await safeSdk.getModulesPaginated(SENTINEL_ADDRESS, 10)).length).to.be.eq(0) + + const emptyModuleList = await safeSdk.getModulesPaginated(SENTINEL_ADDRESS, 10) const tx = await safeSdk.createEnableModuleTx(await dailyLimitModule.getAddress()) const txResponse = await safeSdk.executeTransaction(tx) await waitSafeTxReceipt(txResponse) - chai.expect((await safeSdk.getModulesPaginated(SENTINEL_ADDRESS, 10)).length).to.be.eq(1) + const moduleList = await safeSdk.getModulesPaginated(SENTINEL_ADDRESS, 10) + + chai.expect(emptyModuleList.modules.length).to.be.eq(0) + chai.expect(emptyModuleList.next).to.be.eq(SENTINEL_ADDRESS) + chai.expect(moduleList.modules.length).to.be.eq(1) + chai.expect(emptyModuleList.next).to.be.eq(SENTINEL_ADDRESS) }) it('should constraint returned modules by pageSize', async () => { - const { safe, accounts, dailyLimitModule, contractNetworks, socialRecoveryModule } = - await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { + safe, + dailyLimitModule, + contractNetworks, + socialRecoveryModule, + stateChannelModule, + whiteListModule, + provider + } = await setupTests() const safeAddress = await safe.getAddress() - const dailyLimitsAddress = await await dailyLimitModule.getAddress() - const socialRecoveryAddress = await await socialRecoveryModule.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const dailyLimitsAddress = await dailyLimitModule.getAddress() + const socialRecoveryAddress = await socialRecoveryModule.getAddress() + const stateChannelAddress = await stateChannelModule.getAddress() + const whiteListAddress = await whiteListModule.getAddress() + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) + const currentPageNext = semverSatisfies(await safeSdk.getContractVersion(), '>=1.4.1') + + chai + .expect((await safeSdk.getModulesPaginated(SENTINEL_ADDRESS, 10)).modules.length) + .to.be.eq(0) + + const moduleDeployment = [ + dailyLimitsAddress, + socialRecoveryAddress, + stateChannelAddress, + whiteListAddress + ].map(async (moduleAddress) => { + const txModule = await safeSdk.createEnableModuleTx(moduleAddress) + const moduleResponse = await safeSdk.executeTransaction(txModule) + await waitSafeTxReceipt(moduleResponse) + }) + + await Promise.all(moduleDeployment) - chai.expect((await safeSdk.getModulesPaginated(SENTINEL_ADDRESS, 10)).length).to.be.eq(0) - const txDailyLimits = await safeSdk.createEnableModuleTx(dailyLimitsAddress) - const dailyLimitsResponse = await safeSdk.executeTransaction(txDailyLimits) - await waitSafeTxReceipt(dailyLimitsResponse) - const txSocialRecovery = await safeSdk.createEnableModuleTx(socialRecoveryAddress) - const soecialRecoveryResponse = await safeSdk.executeTransaction(txSocialRecovery) - await waitSafeTxReceipt(soecialRecoveryResponse) - - chai.expect((await safeSdk.getModulesPaginated(SENTINEL_ADDRESS, 10)).length).to.be.eq(2) - chai.expect((await safeSdk.getModulesPaginated(SENTINEL_ADDRESS, 1)).length).to.be.eq(1) - chai.expect((await safeSdk.getModulesPaginated(SENTINEL_ADDRESS, 1)).length).to.be.eq(1) + const modules1 = await safeSdk.getModulesPaginated(SENTINEL_ADDRESS, 10) + const modules2 = await safeSdk.getModulesPaginated(SENTINEL_ADDRESS, 1) + const modules3 = await safeSdk.getModulesPaginated(SENTINEL_ADDRESS, 2) + + chai.expect(modules1.modules.length).to.be.eq(4) + chai + .expect(modules1.modules) + .to.deep.eq([ + whiteListAddress, + stateChannelAddress, + socialRecoveryAddress, + dailyLimitsAddress + ]) + chai.expect(modules1.next).to.be.eq(SENTINEL_ADDRESS) + + chai.expect(modules2.modules.length).to.be.eq(1) + chai.expect(modules2.modules).to.deep.eq([whiteListAddress]) + chai.expect(modules2.next).to.be.eq(currentPageNext ? whiteListAddress : stateChannelAddress) + + chai.expect(modules3.modules.length).to.be.eq(2) + chai.expect(modules3.modules).to.deep.eq([whiteListAddress, stateChannelAddress]) + chai + .expect(modules3.next) + .to.be.eq(currentPageNext ? stateChannelAddress : socialRecoveryAddress) }) it('should offset the returned modules', async () => { - const { safe, accounts, dailyLimitModule, contractNetworks, socialRecoveryModule } = - await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { + safe, + dailyLimitModule, + contractNetworks, + socialRecoveryModule, + stateChannelModule, + whiteListModule, + provider + } = await setupTests() const safeAddress = await safe.getAddress() - const dailyLimitsAddress = await await dailyLimitModule.getAddress() - const socialRecoveryAddress = await await socialRecoveryModule.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const dailyLimitsAddress = await dailyLimitModule.getAddress() + const socialRecoveryAddress = await socialRecoveryModule.getAddress() + const stateChannelAddress = await stateChannelModule.getAddress() + const whiteListAddress = await whiteListModule.getAddress() + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) + const currentPageNext = semverSatisfies(await safeSdk.getContractVersion(), '>=1.4.1') + + const moduleDeployment = [ + dailyLimitsAddress, + socialRecoveryAddress, + stateChannelAddress, + whiteListAddress + ].map(async (moduleAddress) => { + const txModule = await safeSdk.createEnableModuleTx(moduleAddress) + const moduleResponse = await safeSdk.executeTransaction(txModule) + await waitSafeTxReceipt(moduleResponse) + }) + + await Promise.all(moduleDeployment) - const txDailyLimits = await safeSdk.createEnableModuleTx(dailyLimitsAddress) - const dailyLimitsResponse = await safeSdk.executeTransaction(txDailyLimits) - await waitSafeTxReceipt(dailyLimitsResponse) - const txSocialRecovery = await safeSdk.createEnableModuleTx(socialRecoveryAddress) - const soecialRecoveryResponse = await safeSdk.executeTransaction(txSocialRecovery) - await waitSafeTxReceipt(soecialRecoveryResponse) + const { + modules: [firstModule, secondModule, thirdModule, fourthModule] + } = await safeSdk.getModulesPaginated(SENTINEL_ADDRESS, 10) - const [firstModule, secondModule] = await safeSdk.getModulesPaginated(SENTINEL_ADDRESS, 10) + const modules1 = await safeSdk.getModulesPaginated(firstModule, 10) + const modules2 = await safeSdk.getModulesPaginated(firstModule, 2) + const modules3 = await safeSdk.getModulesPaginated(firstModule, 3) - chai.expect((await safeSdk.getModulesPaginated(SENTINEL_ADDRESS, 10)).length).to.be.eq(2) - chai.expect((await safeSdk.getModulesPaginated(firstModule, 10)).length).to.be.eq(1) - chai.expect((await safeSdk.getModulesPaginated(secondModule, 10)).length).to.be.eq(0) + chai + .expect((await safeSdk.getModulesPaginated(SENTINEL_ADDRESS, 10)).modules.length) + .to.be.eq(4) + chai.expect(modules1.modules).to.deep.eq([secondModule, thirdModule, fourthModule]) + chai.expect(modules1.next).to.be.eq(SENTINEL_ADDRESS) + chai.expect(modules2.modules).to.deep.eq([secondModule, thirdModule]) + chai.expect(modules2.next).to.be.eq(currentPageNext ? thirdModule : fourthModule) + chai.expect(modules3.modules).to.deep.eq([secondModule, thirdModule, fourthModule]) + chai.expect(modules3.next).to.be.eq(SENTINEL_ADDRESS) }) it('should fail if pageSize is invalid', async () => { - const { predictedSafe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { predictedSafe, contractNetworks, provider } = await setupTests() + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -180,11 +260,9 @@ describe('Safe modules manager', () => { describe('isModuleEnabled', async () => { it('should fail if the Safe is not deployed', async () => { - const { predictedSafe, accounts, dailyLimitModule, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { predictedSafe, dailyLimitModule, contractNetworks, provider } = await setupTests() + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -193,12 +271,10 @@ describe('Safe modules manager', () => { }) it('should return true if a module is enabled', async () => { - const { safe, accounts, dailyLimitModule, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, dailyLimitModule, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -212,11 +288,9 @@ describe('Safe modules manager', () => { describe('createEnableModuleTx', async () => { it('should fail if the Safe is not deployed', async () => { - const { predictedSafe, accounts, dailyLimitModule, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { predictedSafe, dailyLimitModule, contractNetworks, provider } = await setupTests() + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -225,12 +299,10 @@ describe('Safe modules manager', () => { }) it('should fail if address is invalid', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -239,12 +311,10 @@ describe('Safe modules manager', () => { }) it('should fail if address is equal to sentinel', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -253,12 +323,10 @@ describe('Safe modules manager', () => { }) it('should fail if address is equal to 0x address', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -267,12 +335,10 @@ describe('Safe modules manager', () => { }) it('should fail if address is already enabled', async () => { - const { safe, accounts, dailyLimitModule, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, dailyLimitModule, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -284,12 +350,10 @@ describe('Safe modules manager', () => { }) it('should build the transaction with the optional props', async () => { - const { safe, accounts, dailyLimitModule, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, dailyLimitModule, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -311,12 +375,10 @@ describe('Safe modules manager', () => { }) it('should enable a Safe module', async () => { - const { safe, accounts, dailyLimitModule, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, dailyLimitModule, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -332,11 +394,9 @@ describe('Safe modules manager', () => { describe('createDisableModuleTx', async () => { it('should fail if the Safe is not deployed', async () => { - const { predictedSafe, accounts, dailyLimitModule, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { predictedSafe, dailyLimitModule, contractNetworks, provider } = await setupTests() + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -345,12 +405,10 @@ describe('Safe modules manager', () => { }) it('should fail if address is invalid', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -359,12 +417,10 @@ describe('Safe modules manager', () => { }) it('should fail if address is equal to sentinel', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -373,12 +429,10 @@ describe('Safe modules manager', () => { }) it('should fail if address is equal to 0x address', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -387,12 +441,10 @@ describe('Safe modules manager', () => { }) it('should fail if address is not enabled', async () => { - const { safe, accounts, dailyLimitModule, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, dailyLimitModule, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -401,13 +453,12 @@ describe('Safe modules manager', () => { }) it('should build the transaction with the optional props', async () => { - const { dailyLimitModule, accounts, contractNetworks } = await setupTests() + const { dailyLimitModule, accounts, contractNetworks, provider } = await setupTests() const [account1] = accounts const safe = await getSafeWithOwners([account1.address]) const safeAddress = await safe.getAddress() - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -436,14 +487,13 @@ describe('Safe modules manager', () => { }) it('should disable Safe modules', async () => { - const { dailyLimitModule, accounts, socialRecoveryModule, contractNetworks } = + const { dailyLimitModule, accounts, socialRecoveryModule, contractNetworks, provider } = await setupTests() const [account1] = accounts const safe = await getSafeWithOwners([account1.address]) const safeAddress = await safe.getAddress() - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) diff --git a/packages/protocol-kit/tests/e2e/offChainSignatures.test.ts b/packages/protocol-kit/tests/e2e/offChainSignatures.test.ts index 5d463c998..b10a3c7db 100644 --- a/packages/protocol-kit/tests/e2e/offChainSignatures.test.ts +++ b/packages/protocol-kit/tests/e2e/offChainSignatures.test.ts @@ -7,7 +7,7 @@ import { deployments } from 'hardhat' import { itif } from './utils/helpers' import { getContractNetworks } from './utils/setupContractNetworks' import { getSafeWithOwners } from './utils/setupContracts' -import { getEthAdapter } from './utils/setupEthAdapter' +import { getEip1193Provider } from './utils/setupProvider' import { getAccounts } from './utils/setupTestNetwork' chai.use(chaiAsPromised) @@ -27,21 +27,22 @@ describe('Off-chain signatures', () => { safeVersion: safeVersionDeployed } } + const provider = getEip1193Provider() + return { safe: await getSafeWithOwners([accounts[0].address, accounts[1].address]), accounts, contractNetworks, - predictedSafe + predictedSafe, + provider } }) describe('signHash', async () => { it('should sign a transaction hash with the current signer if the Safe is not deployed', async () => { - const { predictedSafe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { predictedSafe, contractNetworks, provider } = await setupTests() + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -51,12 +52,10 @@ describe('Off-chain signatures', () => { }) it('should sign a transaction hash with the current signer', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -76,17 +75,15 @@ describe('Off-chain signatures', () => { itif(safeVersionDeployed < '1.3.0')( 'should fail to sign a transaction if the Safe with version { - const { safe, predictedSafe, accounts, contractNetworks } = await setupTests() - const account = accounts[0] - const ethAdapter = await getEthAdapter(account.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { safe, predictedSafe, contractNetworks, provider } = await setupTests() + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) const safeAddress = await safe.getAddress() - const safeSdkExistingSafe = await Safe.create({ - ethAdapter, + const safeSdkExistingSafe = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -110,11 +107,9 @@ describe('Off-chain signatures', () => { itif(safeVersionDeployed >= '1.3.0')( 'should sign a transaction with the current signer if the Safe with version >=v1.3.0 is using predicted config', async () => { - const { safe, predictedSafe, accounts, contractNetworks } = await setupTests() - const account = accounts[0] - const ethAdapter = await getEthAdapter(account.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { safe, predictedSafe, contractNetworks, provider } = await setupTests() + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -133,13 +128,13 @@ describe('Off-chain signatures', () => { ) it('should fail if the signature is added by an account that is not an owner', async () => { - const { safe, accounts, contractNetworks } = await setupTests() + const { safe, accounts, contractNetworks, provider } = await setupTests() const account3 = accounts[2] - const ethAdapter = await getEthAdapter(account3.signer) const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, + signer: account3.address, contractNetworks }) const safeTransactionData = { @@ -154,12 +149,10 @@ describe('Off-chain signatures', () => { }) it('should ignore duplicated signatures', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -180,12 +173,10 @@ describe('Off-chain signatures', () => { itif(safeVersionDeployed === '1.0.0')( 'should fail if the signature of the current signer is added using eth_sign and safeVersion===1.0.0', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress: safeAddress, contractNetworks }) @@ -204,12 +195,10 @@ describe('Off-chain signatures', () => { itif(safeVersionDeployed > '1.0.0')( 'should add the signature of the current signer using eth_sign if safeVersion>1.0.0', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -226,111 +215,51 @@ describe('Off-chain signatures', () => { } ) - itif(process.env.ETH_LIB === 'ethers')( - 'should add the signature of the current signer using eth_signTypedData with ethers provider', - async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, - safeAddress, - contractNetworks - }) - const safeTransactionData = { - to: safeAddress, - value: '0', - data: '0x' - } - const tx = await safeSdk.createTransaction({ transactions: [safeTransactionData] }) - chai.expect(tx.signatures.size).to.be.eq(0) - const signedTx = await safeSdk.signTransaction(tx, SigningMethod.ETH_SIGN_TYPED_DATA) - chai.expect(tx.signatures.size).to.be.eq(0) - chai.expect(signedTx.signatures.size).to.be.eq(1) - } - ) - - itif(process.env.ETH_LIB === 'web3')( - 'should fail if the signature of the current signer is added using eth_signTypedData with web3 provider', - async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, - safeAddress, - contractNetworks - }) - const safeTransactionData = { - to: safeAddress, - value: '0', - data: '0x' - } - const tx = await safeSdk.createTransaction({ transactions: [safeTransactionData] }) - await chai - .expect(safeSdk.signTransaction(tx, SigningMethod.ETH_SIGN_TYPED_DATA)) - .to.be.rejectedWith("EIP-712 is not supported by user's wallet") - } - ) - - itif(process.env.ETH_LIB === 'ethers')( - 'should add the signature of the current signer using eth_signTypedData_v3 with ethers provider', - async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, - safeAddress, - contractNetworks - }) - const safeTransactionData = { - to: safeAddress, - value: '0', - data: '0x' - } - const tx = await safeSdk.createTransaction({ transactions: [safeTransactionData] }) - chai.expect(tx.signatures.size).to.be.eq(0) - const signedTx = await safeSdk.signTransaction(tx, SigningMethod.ETH_SIGN_TYPED_DATA_V3) - chai.expect(tx.signatures.size).to.be.eq(0) - chai.expect(signedTx.signatures.size).to.be.eq(1) + it('should add the signature of the current signer using eth_signTypedData', async () => { + const { safe, contractNetworks, provider } = await setupTests() + const safeAddress = await safe.getAddress() + const safeSdk = await Safe.init({ + provider, + safeAddress, + contractNetworks + }) + const safeTransactionData = { + to: safeAddress, + value: '0', + data: '0x' } - ) + const tx = await safeSdk.createTransaction({ transactions: [safeTransactionData] }) + chai.expect(tx.signatures.size).to.be.eq(0) + const signedTx = await safeSdk.signTransaction(tx, SigningMethod.ETH_SIGN_TYPED_DATA) + chai.expect(tx.signatures.size).to.be.eq(0) + chai.expect(signedTx.signatures.size).to.be.eq(1) + }) - itif(process.env.ETH_LIB === 'web3')( - 'should fail if the signature of the current signer is added using eth_signTypedData_v3 with web3 provider', - async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, - safeAddress, - contractNetworks - }) - const safeTransactionData = { - to: safeAddress, - value: '0', - data: '0x' - } - const tx = await safeSdk.createTransaction({ transactions: [safeTransactionData] }) - await chai - .expect(safeSdk.signTransaction(tx, SigningMethod.ETH_SIGN_TYPED_DATA_V3)) - .to.be.rejectedWith("EIP-712 is not supported by user's wallet") + it('should add the signature of the current signer using eth_signTypedData_v3', async () => { + const { safe, contractNetworks, provider } = await setupTests() + const safeAddress = await safe.getAddress() + const safeSdk = await Safe.init({ + provider, + safeAddress, + contractNetworks + }) + const safeTransactionData = { + to: safeAddress, + value: '0', + data: '0x' } - ) + const tx = await safeSdk.createTransaction({ transactions: [safeTransactionData] }) + chai.expect(tx.signatures.size).to.be.eq(0) + const signedTx = await safeSdk.signTransaction(tx, SigningMethod.ETH_SIGN_TYPED_DATA_V3) + chai.expect(tx.signatures.size).to.be.eq(0) + chai.expect(signedTx.signatures.size).to.be.eq(1) + }) it('should add the signature of the current signer using eth_signTypedData_v4', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -347,12 +276,10 @@ describe('Off-chain signatures', () => { }) it('should add the signature of the current signer using eth_signTypedData_v4 by default', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { safe, contractNetworks, provider } = await setupTests() const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -369,12 +296,11 @@ describe('Off-chain signatures', () => { }) it('should sign a transaction received from the Safe Transaction Service', async () => { - const { safe, accounts, contractNetworks } = await setupTests() + const { safe, accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts - const ethAdapter = await getEthAdapter(account1.signer) const safeAddress = await safe.getAddress() - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -429,7 +355,7 @@ describe('Off-chain signatures', () => { const signedTx = await safeSdk.signTransaction(safeServiceTransaction) chai.expect(safeServiceTransaction.confirmations?.length).to.be.eq(2) chai.expect(signedTx.signatures.size).to.be.eq(3) - const signerAddress = await ethAdapter.getSignerAddress() + const signerAddress = account1.address const signerSignature = signedTx.signatures.get(signerAddress!.toLowerCase())?.data chai .expect(signedTx.encodedSignatures()) diff --git a/packages/protocol-kit/tests/e2e/onChainSignatures.test.ts b/packages/protocol-kit/tests/e2e/onChainSignatures.test.ts index dfbe38e61..b18b456e8 100644 --- a/packages/protocol-kit/tests/e2e/onChainSignatures.test.ts +++ b/packages/protocol-kit/tests/e2e/onChainSignatures.test.ts @@ -5,7 +5,7 @@ import chaiAsPromised from 'chai-as-promised' import { deployments } from 'hardhat' import { getContractNetworks } from './utils/setupContractNetworks' import { getSafeWithOwners } from './utils/setupContracts' -import { getEthAdapter } from './utils/setupEthAdapter' +import { getEip1193Provider } from './utils/setupProvider' import { getAccounts } from './utils/setupTestNetwork' import { waitSafeTxReceipt } from './utils/transactions' @@ -26,21 +26,22 @@ describe('On-chain signatures', () => { safeVersion: safeVersionDeployed } } + const provider = getEip1193Provider() + return { safe: await getSafeWithOwners([accounts[0].address, accounts[1].address]), accounts, contractNetworks, - predictedSafe + predictedSafe, + provider } }) describe('approveTransactionHash', async () => { it('should fail if the Safe is not deployed', async () => { - const { predictedSafe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk1 = await Safe.create({ - ethAdapter, + const { predictedSafe, contractNetworks, provider } = await setupTests() + const safeSdk1 = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -51,12 +52,12 @@ describe('On-chain signatures', () => { }) it('should fail if a transaction hash is approved by an account that is not an owner', async () => { - const { safe, accounts, contractNetworks } = await setupTests() + const { safe, accounts, contractNetworks, provider } = await setupTests() const account3 = accounts[2] - const ethAdapter = await getEthAdapter(account3.signer) const safeAddress = await safe.getAddress() - const safeSdk1 = await Safe.create({ - ethAdapter, + const safeSdk1 = await Safe.init({ + provider, + signer: account3.address, safeAddress, contractNetworks }) @@ -73,12 +74,11 @@ describe('On-chain signatures', () => { }) it('should approve the transaction hash', async () => { - const { safe, accounts, contractNetworks } = await setupTests() + const { safe, accounts, contractNetworks, provider } = await setupTests() const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) const safeAddress = await safe.getAddress() - const safeSdk1 = await Safe.create({ - ethAdapter, + const safeSdk1 = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -95,12 +95,11 @@ describe('On-chain signatures', () => { }) it('should ignore a duplicated signatures', async () => { - const { safe, accounts, contractNetworks } = await setupTests() + const { safe, accounts, contractNetworks, provider } = await setupTests() const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) const safeAddress = await safe.getAddress() - const safeSdk1 = await Safe.create({ - ethAdapter, + const safeSdk1 = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -123,11 +122,9 @@ describe('On-chain signatures', () => { describe('getOwnersWhoApprovedTx', async () => { it('should fail if Safe is not deployed', async () => { - const { predictedSafe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter1 = await getEthAdapter(account1.signer) - const safeSdk1 = await Safe.create({ - ethAdapter: ethAdapter1, + const { predictedSafe, contractNetworks, provider } = await setupTests() + const safeSdk1 = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -137,17 +134,17 @@ describe('On-chain signatures', () => { }) it('should return the list of owners who approved a transaction hash', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1, account2] = accounts - const ethAdapter1 = await getEthAdapter(account1.signer) + const { safe, accounts, contractNetworks, provider } = await setupTests() + const [, account2] = accounts const safeAddress = await safe.getAddress() - const safeSdk1 = await Safe.create({ - ethAdapter: ethAdapter1, + const safeSdk1 = await Safe.init({ + provider, safeAddress: safeAddress, contractNetworks }) - const ethAdapter2 = await getEthAdapter(account2.signer) - const safeSdk2 = await safeSdk1.connect({ ethAdapter: ethAdapter2 }) + const safeSdk2 = await safeSdk1.connect({ + signer: account2.address + }) const safeTransactionData = { to: safeAddress, value: '0', diff --git a/packages/protocol-kit/tests/e2e/ownerManager.test.ts b/packages/protocol-kit/tests/e2e/ownerManager.test.ts index 801428580..735e520dc 100644 --- a/packages/protocol-kit/tests/e2e/ownerManager.test.ts +++ b/packages/protocol-kit/tests/e2e/ownerManager.test.ts @@ -9,7 +9,7 @@ import chaiAsPromised from 'chai-as-promised' import { deployments } from 'hardhat' import { getContractNetworks } from './utils/setupContractNetworks' import { getSafeWithOwners } from './utils/setupContracts' -import { getEthAdapter } from './utils/setupEthAdapter' +import { getEip1193Provider } from './utils/setupProvider' import { getAccounts } from './utils/setupTestNetwork' import { waitSafeTxReceipt } from './utils/transactions' @@ -21,6 +21,7 @@ describe('Safe owners manager', () => { const accounts = await getAccounts() const chainId = BigInt(await getChainId()) const contractNetworks = await getContractNetworks(chainId) + const provider = getEip1193Provider() const predictedSafe: PredictedSafeProps = { safeAccountConfig: { owners: [accounts[0].address], @@ -38,17 +39,16 @@ describe('Safe owners manager', () => { ]), accounts, contractNetworks, - predictedSafe + predictedSafe, + provider } }) describe('getOwners', async () => { it('should fail if the Safe is not deployed', async () => { - const { predictedSafe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { predictedSafe, contractNetworks, provider } = await setupTests() + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -56,12 +56,11 @@ describe('Safe owners manager', () => { }) it('should return the list of Safe owners', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address, account2.address]) - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -74,11 +73,10 @@ describe('Safe owners manager', () => { describe('isOwner', async () => { it('should fail if the Safe is not deployed', async () => { - const { predictedSafe, accounts, contractNetworks } = await setupTests() + const { predictedSafe, accounts, contractNetworks, provider } = await setupTests() const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -86,12 +84,11 @@ describe('Safe owners manager', () => { }) it('should return true if an account is an owner of the connected Safe', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -100,12 +97,11 @@ describe('Safe owners manager', () => { }) it('should return false if an account is not an owner of the connected Safe', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -116,11 +112,10 @@ describe('Safe owners manager', () => { describe('createAddOwnerTx', async () => { it('should fail if the Safe is not deployed', async () => { - const { predictedSafe, accounts, contractNetworks } = await setupTests() - const [account1, account2] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { predictedSafe, accounts, contractNetworks, provider } = await setupTests() + const [, account2] = accounts + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -129,12 +124,11 @@ describe('Safe owners manager', () => { }) it('should fail if address is invalid', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -143,12 +137,11 @@ describe('Safe owners manager', () => { }) it('should fail if address is equal to sentinel', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -157,12 +150,11 @@ describe('Safe owners manager', () => { }) it('should fail if address is equal to 0x address', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -171,12 +163,11 @@ describe('Safe owners manager', () => { }) it('should fail if address is already an owner', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -185,12 +176,11 @@ describe('Safe owners manager', () => { }) it('should fail if the threshold is bigger than the number of owners', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -205,12 +195,11 @@ describe('Safe owners manager', () => { }) it('should fail if the threshold is not bigger than 0', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -219,12 +208,11 @@ describe('Safe owners manager', () => { }) it('should build the transaction with the optional props', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -246,12 +234,11 @@ describe('Safe owners manager', () => { }) it('should add an owner and keep the same threshold', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -271,12 +258,11 @@ describe('Safe owners manager', () => { }) it('should add an owner and update the threshold', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -300,11 +286,10 @@ describe('Safe owners manager', () => { describe('createRemoveOwnerTx', async () => { it('should fail if the Safe is not deployed', async () => { - const { predictedSafe, accounts, contractNetworks } = await setupTests() - const [account1, account2] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { predictedSafe, accounts, contractNetworks, provider } = await setupTests() + const [, account2] = accounts + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -313,11 +298,9 @@ describe('Safe owners manager', () => { }) it('should fail if address is invalid', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { safe, contractNetworks, provider } = await setupTests() + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -326,11 +309,9 @@ describe('Safe owners manager', () => { }) it('should fail if address is equal to sentinel', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { safe, contractNetworks, provider } = await setupTests() + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -339,11 +320,9 @@ describe('Safe owners manager', () => { }) it('should fail if address is equal to 0x address', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { safe, contractNetworks, provider } = await setupTests() + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -352,11 +331,10 @@ describe('Safe owners manager', () => { }) it('should fail if address is not an owner', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1, , , account4] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { safe, accounts, contractNetworks, provider } = await setupTests() + const [, , , account4] = accounts + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -365,11 +343,10 @@ describe('Safe owners manager', () => { }) it('should fail if the threshold is bigger than the number of owners', async () => { - const { safe, accounts, contractNetworks } = await setupTests() + const { safe, accounts, contractNetworks, provider } = await setupTests() const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -384,11 +361,10 @@ describe('Safe owners manager', () => { }) it('should fail if the threshold is not bigger than 0', async () => { - const { safe, accounts, contractNetworks } = await setupTests() + const { safe, accounts, contractNetworks, provider } = await setupTests() const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -397,11 +373,10 @@ describe('Safe owners manager', () => { }) it('should build the transaction with the optional props', async () => { - const { safe, accounts, contractNetworks } = await setupTests() + const { safe, accounts, contractNetworks, provider } = await setupTests() const [account1] = accounts - const ethAdapter1 = await getEthAdapter(account1.signer) - const safeSdk1 = await Safe.create({ - ethAdapter: ethAdapter1, + const safeSdk1 = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -423,18 +398,19 @@ describe('Safe owners manager', () => { }) it('should remove the first owner of a Safe and decrease the threshold', async () => { - const { safe, accounts, contractNetworks } = await setupTests() + const { safe, accounts, contractNetworks, provider } = await setupTests() const [account1, account2, account3] = accounts - const ethAdapter1 = await getEthAdapter(account1.signer) - const safeSdk1 = await Safe.create({ - ethAdapter: ethAdapter1, + const safeSdk1 = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) - const ethAdapter2 = await getEthAdapter(account2.signer) - const safeSdk2 = await safeSdk1.connect({ ethAdapter: ethAdapter2 }) - const ethAdapter3 = await getEthAdapter(account3.signer) - const safeSdk3 = await safeSdk1.connect({ ethAdapter: ethAdapter3 }) + const safeSdk2 = await safeSdk1.connect({ + signer: account2.address + }) + const safeSdk3 = await safeSdk1.connect({ + signer: account3.address + }) const initialThreshold = await safeSdk1.getThreshold() const initialOwners = await safeSdk1.getOwners() chai.expect(initialOwners.length).to.be.eq(3) @@ -455,19 +431,18 @@ describe('Safe owners manager', () => { }) it('should remove any owner of a Safe and decrease the threshold', async () => { - const { safe, accounts, contractNetworks } = await setupTests() + const { safe, accounts, contractNetworks, provider } = await setupTests() const [account1, account2, account3] = accounts - const ethAdapter1 = await getEthAdapter(account1.signer) - const safeSdk1 = await Safe.create({ - ethAdapter: ethAdapter1, + const safeSdk1 = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) - const ethAdapter2 = await getEthAdapter(account2.signer) - const safeSdk2 = await safeSdk1.connect({ ethAdapter: ethAdapter2 }) - const ethAdapter3 = await getEthAdapter(account3.signer) + const safeSdk2 = await safeSdk1.connect({ + signer: account2.address + }) const safeSdk3 = await safeSdk1.connect({ - ethAdapter: ethAdapter3, + signer: account3.address, contractNetworks }) const initialThreshold = await safeSdk1.getThreshold() @@ -490,18 +465,19 @@ describe('Safe owners manager', () => { }) it('should remove an owner and update the threshold', async () => { - const { safe, accounts, contractNetworks } = await setupTests() + const { safe, accounts, contractNetworks, provider } = await setupTests() const [account1, account2, account3] = accounts - const ethAdapter1 = await getEthAdapter(account1.signer) - const safeSdk1 = await Safe.create({ - ethAdapter: ethAdapter1, + const safeSdk1 = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) - const ethAdapter2 = await getEthAdapter(account2.signer) - const safeSdk2 = await safeSdk1.connect({ ethAdapter: ethAdapter2 }) - const ethAdapter3 = await getEthAdapter(account3.signer) - const safeSdk3 = await safeSdk1.connect({ ethAdapter: ethAdapter3 }) + const safeSdk2 = await safeSdk1.connect({ + signer: account2.address + }) + const safeSdk3 = await safeSdk1.connect({ + signer: account3.address + }) const newThreshold = 1 const initialOwners = await safeSdk1.getOwners() chai.expect(initialOwners.length).to.be.eq(3) @@ -526,11 +502,10 @@ describe('Safe owners manager', () => { describe('createSwapOwnerTx', async () => { it('should fail if the Safe is not deployed', async () => { - const { predictedSafe, accounts, contractNetworks } = await setupTests() + const { predictedSafe, accounts, contractNetworks, provider } = await setupTests() const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -542,12 +517,11 @@ describe('Safe owners manager', () => { }) it('should fail if old address is invalid', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -559,12 +533,11 @@ describe('Safe owners manager', () => { }) it('should fail if new address is invalid', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -576,12 +549,11 @@ describe('Safe owners manager', () => { }) it('should fail if old address is equal to sentinel', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -593,12 +565,11 @@ describe('Safe owners manager', () => { }) it('should fail if new address is equal to sentinel', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -610,12 +581,11 @@ describe('Safe owners manager', () => { }) it('should fail if old address is equal to 0x address', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -627,12 +597,11 @@ describe('Safe owners manager', () => { }) it('should fail if new address is equal to 0x address', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -644,12 +613,11 @@ describe('Safe owners manager', () => { }) it('should fail if old address is not an owner', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2, , account4] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -661,12 +629,11 @@ describe('Safe owners manager', () => { }) it('should fail if new address is already an owner', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -678,12 +645,11 @@ describe('Safe owners manager', () => { }) it('should build the transaction with the optional props', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -708,12 +674,11 @@ describe('Safe owners manager', () => { }) it('should replace the first owner of a Safe', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -732,18 +697,19 @@ describe('Safe owners manager', () => { }) it('should replace any owner of a Safe', async () => { - const { safe, accounts, contractNetworks } = await setupTests() + const { safe, accounts, contractNetworks, provider } = await setupTests() const [account1, account2, account3, account4] = accounts - const ethAdapter1 = await getEthAdapter(account1.signer) - const safeSdk1 = await Safe.create({ - ethAdapter: ethAdapter1, + const safeSdk1 = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) - const ethAdapter2 = await getEthAdapter(account2.signer) - const safeSdk2 = await safeSdk1.connect({ ethAdapter: ethAdapter2 }) - const ethAdapter3 = await getEthAdapter(account3.signer) - const safeSdk3 = await safeSdk1.connect({ ethAdapter: ethAdapter3 }) + const safeSdk2 = await safeSdk1.connect({ + signer: account2.address + }) + const safeSdk3 = await safeSdk1.connect({ + signer: account3.address + }) const initialOwners = await safeSdk1.getOwners() chai.expect(initialOwners.length).to.be.eq(3) chai.expect(initialOwners[0]).to.be.eq(account1.address) diff --git a/packages/protocol-kit/tests/e2e/safeFactory.test.ts b/packages/protocol-kit/tests/e2e/safeFactory.test.ts index 6d4d3c3bb..20998fd50 100644 --- a/packages/protocol-kit/tests/e2e/safeFactory.test.ts +++ b/packages/protocol-kit/tests/e2e/safeFactory.test.ts @@ -4,7 +4,8 @@ import { ContractNetworksConfig, DeploySafeProps, SafeAccountConfig, - SafeFactory + SafeFactory, + SafeProvider } from '@safe-global/protocol-kit/index' import { ZERO_ADDRESS } from '@safe-global/protocol-kit/utils/constants' import chai from 'chai' @@ -23,7 +24,7 @@ import { getSignMessageLib, getSimulateTxAccessor } from './utils/setupContracts' -import { getEthAdapter } from './utils/setupEthAdapter' +import { getEip1193Provider } from './utils/setupProvider' import { getAccounts } from './utils/setupTestNetwork' chai.use(chaiAsPromised) @@ -34,28 +35,25 @@ describe('SafeProxyFactory', () => { const accounts = await getAccounts() const chainId = BigInt(await getChainId()) const contractNetworks = await getContractNetworks(chainId) + const provider = getEip1193Provider() + return { defaultCallbackHandler: await getDefaultCallbackHandler(), chainId, accounts, - contractNetworks + contractNetworks, + provider } }) describe('create', async () => { it('should fail if the current network is not a default network and no contractNetworks is provided', async () => { - const { accounts } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - chai - .expect(SafeFactory.create({ ethAdapter })) - .rejectedWith('Invalid SafeProxyFactory contract') + const { provider } = await setupTests() + chai.expect(SafeFactory.init({ provider })).rejectedWith('Invalid SafeProxyFactory contract') }) it('should fail if the contractNetworks provided are not deployed', async () => { - const { accounts, chainId } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { chainId, provider } = await setupTests() const contractNetworks: ContractNetworksConfig = { [chainId.toString()]: { safeSingletonAddress: ZERO_ADDRESS, @@ -77,50 +75,44 @@ describe('SafeProxyFactory', () => { } } chai - .expect(SafeFactory.create({ ethAdapter, contractNetworks })) + .expect(SafeFactory.init({ provider, contractNetworks })) .rejectedWith('SafeProxyFactory contract is not deployed on the current network') }) it('should instantiate the SafeProxyFactory', async () => { - const { accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeFactory = await SafeFactory.create({ ethAdapter, contractNetworks }) - const networkId = await ethAdapter.getChainId() + const { contractNetworks, provider } = await setupTests() + const safeProvider = new SafeProvider({ provider }) + const safeFactory = await SafeFactory.init({ provider, contractNetworks }) + const networkId = await safeProvider.getChainId() chai .expect(await safeFactory.getAddress()) - .to.be.eq(contractNetworks[networkId].safeProxyFactoryAddress) + .to.be.eq(contractNetworks[networkId.toString()].safeProxyFactoryAddress) }) }) - describe('getEthAdapter', async () => { - it('should return the connected EthAdapter', async () => { - const { accounts, contractNetworks } = await setupTests() + describe('getEip1193Provider', async () => { + it('should return the connected SafeProvider', async () => { + const { accounts, contractNetworks, provider } = await setupTests() const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeFactory = await SafeFactory.create({ ethAdapter, contractNetworks }) + const safeFactory = await SafeFactory.init({ provider, contractNetworks }) chai - .expect(await safeFactory.getEthAdapter().getSignerAddress()) + .expect(await safeFactory.getSafeProvider().getSignerAddress()) .to.be.eq(await account1.signer.getAddress()) }) }) describe('getChainId', async () => { it('should return the chainId of the current network', async () => { - const { accounts, chainId, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeFactory = await SafeFactory.create({ ethAdapter, contractNetworks }) + const { chainId, contractNetworks, provider } = await setupTests() + const safeFactory = await SafeFactory.init({ provider, contractNetworks }) chai.expect(await safeFactory.getChainId()).to.be.eq(chainId) }) }) describe('predictSafeAddress', async () => { it('should fail if there are no owners', async () => { - const { accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeFactory = await SafeFactory.create({ ethAdapter, contractNetworks }) + const { contractNetworks, provider } = await setupTests() + const safeFactory = await SafeFactory.init({ provider, contractNetworks }) const owners: string[] = [] const threshold = 2 const safeAccountConfig: SafeAccountConfig = { owners, threshold } @@ -132,10 +124,9 @@ describe('SafeProxyFactory', () => { }) it('should fail if the threshold is lower than 0', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeFactory = await SafeFactory.create({ ethAdapter, contractNetworks }) + const safeFactory = await SafeFactory.init({ provider, contractNetworks }) const owners = [account1.address, account2.address] const invalidThreshold = 0 const safeAccountConfig: SafeAccountConfig = { owners, threshold: invalidThreshold } @@ -147,10 +138,9 @@ describe('SafeProxyFactory', () => { }) it('should fail if the threshold is higher than the threshold', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeFactory = await SafeFactory.create({ ethAdapter, contractNetworks }) + const safeFactory = await SafeFactory.init({ provider, contractNetworks }) const owners = [account1.address, account2.address] const invalidThreshold = 3 const safeAccountConfig: SafeAccountConfig = { owners, threshold: invalidThreshold } @@ -162,11 +152,10 @@ describe('SafeProxyFactory', () => { }) it('should fail if the saltNonce is lower than 0', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeFactory = await SafeFactory.create({ - ethAdapter, + const safeFactory = await SafeFactory.init({ + provider, safeVersion: safeVersionDeployed, contractNetworks }) @@ -181,11 +170,10 @@ describe('SafeProxyFactory', () => { }) it('should predict a new Safe with saltNonce', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeFactory = await SafeFactory.create({ - ethAdapter, + const safeFactory = await SafeFactory.init({ + provider, safeVersion: safeVersionDeployed, contractNetworks }) @@ -208,11 +196,10 @@ describe('SafeProxyFactory', () => { itif(safeVersionDeployed > '1.0.0')( 'should predict a new Safe with the default CompatibilityFallbackHandler', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeFactory = await SafeFactory.create({ - ethAdapter, + const safeFactory = await SafeFactory.init({ + provider, safeVersion: safeVersionDeployed, contractNetworks }) @@ -237,11 +224,10 @@ describe('SafeProxyFactory', () => { itif(safeVersionDeployed > '1.0.0')( 'should predict a new Safe with a custom fallback handler', async () => { - const { accounts, contractNetworks, defaultCallbackHandler } = await setupTests() + const { accounts, contractNetworks, defaultCallbackHandler, provider } = await setupTests() const [account1, account2] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeFactory = await SafeFactory.create({ - ethAdapter, + const safeFactory = await SafeFactory.init({ + provider, safeVersion: safeVersionDeployed, contractNetworks }) @@ -269,10 +255,8 @@ describe('SafeProxyFactory', () => { describe('deploySafe', async () => { it('should fail if there are no owners', async () => { - const { accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeFactory = await SafeFactory.create({ ethAdapter, contractNetworks }) + const { contractNetworks, provider } = await setupTests() + const safeFactory = await SafeFactory.init({ provider, contractNetworks }) const owners: string[] = [] const threshold = 2 const safeAccountConfig: SafeAccountConfig = { owners, threshold } @@ -283,10 +267,9 @@ describe('SafeProxyFactory', () => { }) it('should fail if the threshold is lower than 0', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeFactory = await SafeFactory.create({ ethAdapter, contractNetworks }) + const safeFactory = await SafeFactory.init({ provider, contractNetworks }) const owners = [account1.address, account2.address] const threshold = 0 const safeAccountConfig: SafeAccountConfig = { owners, threshold } @@ -297,10 +280,9 @@ describe('SafeProxyFactory', () => { }) it('should fail if the threshold is higher than the threshold', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeFactory = await SafeFactory.create({ ethAdapter, contractNetworks }) + const safeFactory = await SafeFactory.init({ provider, contractNetworks }) const owners = [account1.address, account2.address] const threshold = 3 const safeAccountConfig: SafeAccountConfig = { owners, threshold } @@ -311,11 +293,10 @@ describe('SafeProxyFactory', () => { }) it('should fail if the saltNonce is lower than 0', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeFactory = await SafeFactory.create({ - ethAdapter, + const safeFactory = await SafeFactory.init({ + provider, safeVersion: safeVersionDeployed, contractNetworks }) @@ -332,11 +313,10 @@ describe('SafeProxyFactory', () => { itif(safeVersionDeployed > '1.0.0')( 'should deploy a new Safe with custom fallback handler', async () => { - const { accounts, contractNetworks, defaultCallbackHandler } = await setupTests() + const { accounts, contractNetworks, defaultCallbackHandler, provider } = await setupTests() const [account1, account2] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeFactory = await SafeFactory.create({ - ethAdapter, + const safeFactory = await SafeFactory.init({ + provider, safeVersion: safeVersionDeployed, contractNetworks }) @@ -361,11 +341,10 @@ describe('SafeProxyFactory', () => { itif(safeVersionDeployed > '1.0.0')( 'should deploy a new Safe with the default CompatibilityFallbackHandler', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeFactory = await SafeFactory.create({ - ethAdapter, + const safeFactory = await SafeFactory.init({ + provider, safeVersion: safeVersionDeployed, contractNetworks }) @@ -383,11 +362,10 @@ describe('SafeProxyFactory', () => { ) it('should deploy a new Safe without saltNonce', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeFactory = await SafeFactory.create({ - ethAdapter, + const safeFactory = await SafeFactory.init({ + provider, safeVersion: safeVersionDeployed, contractNetworks }) @@ -403,11 +381,10 @@ describe('SafeProxyFactory', () => { }) it('should deploy a new Safe with saltNonce', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeFactory = await SafeFactory.create({ - ethAdapter, + const safeFactory = await SafeFactory.init({ + provider, safeVersion: safeVersionDeployed, contractNetworks }) @@ -424,15 +401,14 @@ describe('SafeProxyFactory', () => { }) it('should deploy a new Safe with callback', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts let callbackResult = '' const callback = (txHash: string) => { callbackResult = txHash } - const ethAdapter = await getEthAdapter(account1.signer) - const safeFactory = await SafeFactory.create({ - ethAdapter, + const safeFactory = await SafeFactory.init({ + provider, safeVersion: safeVersionDeployed, contractNetworks }) @@ -450,10 +426,9 @@ describe('SafeProxyFactory', () => { itif(safeVersionDeployed === DEFAULT_SAFE_VERSION)( 'should deploy last Safe version by default', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeFactory = await SafeFactory.create({ ethAdapter, contractNetworks }) + const safeFactory = await SafeFactory.init({ provider, contractNetworks }) const owners = [account1.address, account2.address] const threshold = 2 const safeAccountConfig: SafeAccountConfig = { owners, threshold } @@ -465,11 +440,10 @@ describe('SafeProxyFactory', () => { ) it('should deploy a specific Safe version', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeFactory = await SafeFactory.create({ - ethAdapter, + const safeFactory = await SafeFactory.init({ + provider, safeVersion: safeVersionDeployed, contractNetworks }) diff --git a/packages/protocol-kit/tests/e2e/ethAdapters.test.ts b/packages/protocol-kit/tests/e2e/safeProvider.test.ts similarity index 61% rename from packages/protocol-kit/tests/e2e/ethAdapters.test.ts rename to packages/protocol-kit/tests/e2e/safeProvider.test.ts index db74f44b6..8e6344be2 100644 --- a/packages/protocol-kit/tests/e2e/ethAdapters.test.ts +++ b/packages/protocol-kit/tests/e2e/safeProvider.test.ts @@ -1,12 +1,3 @@ -import { - getCompatibilityFallbackHandlerContractDeployment, - getCreateCallContractDeployment, - getMultiSendCallOnlyContractDeployment, - getMultiSendContractDeployment, - getSafeContractDeployment, - getSafeProxyFactoryContractDeployment, - getSignMessageLibContractDeployment -} from '@safe-global/protocol-kit/contracts/safeDeploymentContracts' import { SafeVersion } from '@safe-global/safe-core-sdk-types' import chai from 'chai' import chaiAsPromised from 'chai-as-promised' @@ -21,8 +12,10 @@ import { getSafeSingleton, getSignMessageLib } from './utils/setupContracts' -import { getEthAdapter, getNetworkProvider } from './utils/setupEthAdapter' +import { getEip1193Provider, getSafeProviderFromNetwork } from './utils/setupProvider' import { getAccounts } from './utils/setupTestNetwork' +import { SafeProvider } from '@safe-global/protocol-kit/index' +import { AbstractSigner, BrowserProvider, JsonRpcProvider } from 'ethers' chai.use(chaiAsPromised) @@ -32,22 +25,22 @@ describe('Safe contracts', () => { const accounts = await getAccounts() const chainId = BigInt(await getChainId()) const contractNetworks = await getContractNetworks(chainId) + const provider = getEip1193Provider() + return { accounts, contractNetworks, - chainId + chainId, + provider } }) describe('getSafeContract', async () => { it('should return an L1 Safe contract from safe-deployments', async () => { - const ethAdapter = await getEthAdapter(getNetworkProvider('mainnet')) + const safeProvider = getSafeProviderFromNetwork('mainnet') const safeVersion: SafeVersion = '1.3.0' - const chainId = 1n - const singletonDeployment = getSafeContractDeployment(safeVersion, chainId) - const safeContract = await ethAdapter.getSafeContract({ - safeVersion, - singletonDeployment + const safeContract = await safeProvider.getSafeContract({ + safeVersion }) chai .expect(await safeContract.getAddress()) @@ -55,13 +48,10 @@ describe('Safe contracts', () => { }) it('should return an L2 Safe contract from safe-deployments', async () => { - const ethAdapter = await getEthAdapter(getNetworkProvider('gnosis')) + const safeProvider = getSafeProviderFromNetwork('gnosis') const safeVersion: SafeVersion = '1.3.0' - const chainId = 100n - const singletonDeployment = getSafeContractDeployment(safeVersion, chainId) - const safeContract = await ethAdapter.getSafeContract({ - safeVersion, - singletonDeployment + const safeContract = await safeProvider.getSafeContract({ + safeVersion }) chai .expect(await safeContract.getAddress()) @@ -69,14 +59,12 @@ describe('Safe contracts', () => { }) it('should return an L1 Safe contract from safe-deployments using the L1 flag', async () => { - const ethAdapter = await getEthAdapter(getNetworkProvider('gnosis')) + const safeProvider = getSafeProviderFromNetwork('gnosis') const safeVersion: SafeVersion = '1.3.0' - const chainId = 100n const isL1SafeSingleton = true - const singletonDeployment = getSafeContractDeployment(safeVersion, chainId, isL1SafeSingleton) - const safeContract = await ethAdapter.getSafeContract({ + const safeContract = await safeProvider.getSafeContract({ safeVersion, - singletonDeployment + isL1SafeSingleton }) chai .expect(await safeContract.getAddress()) @@ -84,12 +72,11 @@ describe('Safe contracts', () => { }) it('should return a Safe contract from the custom addresses', async () => { - const { accounts, contractNetworks, chainId } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { contractNetworks, chainId, provider } = await setupTests() + const safeProvider = new SafeProvider({ provider }) const safeVersion: SafeVersion = '1.3.0' const customContract = contractNetworks[chainId.toString()] - const safeContract = await ethAdapter.getSafeContract({ + const safeContract = await safeProvider.getSafeContract({ safeVersion, customContractAddress: customContract?.safeSingletonAddress, customContractAbi: customContract?.safeSingletonAbi @@ -102,13 +89,10 @@ describe('Safe contracts', () => { describe('getMultiSendContract', async () => { it('should return a MultiSend contract from safe-deployments', async () => { - const ethAdapter = await getEthAdapter(getNetworkProvider('mainnet')) + const safeProvider = getSafeProviderFromNetwork('mainnet') const safeVersion: SafeVersion = '1.3.0' - const chainId = 1n - const singletonDeployment = getMultiSendContractDeployment(safeVersion, chainId) - const multiSendContract = await ethAdapter.getMultiSendContract({ - safeVersion, - singletonDeployment + const multiSendContract = await safeProvider.getMultiSendContract({ + safeVersion }) chai .expect(await multiSendContract.getAddress()) @@ -116,12 +100,11 @@ describe('Safe contracts', () => { }) it('should return a MultiSend contract from the custom addresses', async () => { - const { accounts, contractNetworks, chainId } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { contractNetworks, chainId, provider } = await setupTests() + const safeProvider = new SafeProvider({ provider }) const safeVersion: SafeVersion = '1.3.0' const customContract = contractNetworks[chainId.toString()] - const multiSendContract = await ethAdapter.getMultiSendContract({ + const multiSendContract = await safeProvider.getMultiSendContract({ safeVersion, customContractAddress: customContract.multiSendAddress, customContractAbi: customContract.multiSendAbi @@ -134,13 +117,10 @@ describe('Safe contracts', () => { describe('getMultiSendCallOnlyContract', async () => { it('should return a MultiSendCallOnly contract from safe-deployments', async () => { - const ethAdapter = await getEthAdapter(getNetworkProvider('mainnet')) + const safeProvider = getSafeProviderFromNetwork('mainnet') const safeVersion: SafeVersion = '1.3.0' - const chainId = 1n - const singletonDeployment = getMultiSendCallOnlyContractDeployment(safeVersion, chainId) - const multiSendCallOnlyContract = await ethAdapter.getMultiSendCallOnlyContract({ - safeVersion, - singletonDeployment + const multiSendCallOnlyContract = await safeProvider.getMultiSendCallOnlyContract({ + safeVersion }) chai .expect(await multiSendCallOnlyContract.getAddress()) @@ -148,12 +128,11 @@ describe('Safe contracts', () => { }) it('should return a MultiSendCallOnly contract from the custom addresses', async () => { - const { accounts, contractNetworks, chainId } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { contractNetworks, chainId, provider } = await setupTests() + const safeProvider = new SafeProvider({ provider }) const safeVersion: SafeVersion = '1.3.0' const customContract = contractNetworks[chainId.toString()] - const multiSendCallOnlyContract = await ethAdapter.getMultiSendCallOnlyContract({ + const multiSendCallOnlyContract = await safeProvider.getMultiSendCallOnlyContract({ safeVersion, customContractAddress: customContract.multiSendCallOnlyAddress, customContractAbi: customContract.multiSendCallOnlyAbi @@ -166,17 +145,11 @@ describe('Safe contracts', () => { describe('getCompatibilityFallbackHandlerContract', async () => { it('should return a CompatibilityFallbackHandler contract from safe-deployments', async () => { - const ethAdapter = await getEthAdapter(getNetworkProvider('mainnet')) + const safeProvider = getSafeProviderFromNetwork('mainnet') const safeVersion: SafeVersion = '1.3.0' - const chainId = 1n - const singletonDeployment = getCompatibilityFallbackHandlerContractDeployment( - safeVersion, - chainId - ) const compatibilityFallbackHandlerContract = - await ethAdapter.getCompatibilityFallbackHandlerContract({ - safeVersion, - singletonDeployment + await safeProvider.getCompatibilityFallbackHandlerContract({ + safeVersion }) chai .expect(await compatibilityFallbackHandlerContract.getAddress()) @@ -184,13 +157,12 @@ describe('Safe contracts', () => { }) it('should return a CompatibilityFallbackHandler contract from the custom addresses', async () => { - const { accounts, contractNetworks, chainId } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { contractNetworks, chainId, provider } = await setupTests() + const safeProvider = new SafeProvider({ provider }) const safeVersion: SafeVersion = '1.3.0' const customContract = contractNetworks[chainId.toString()] const compatibilityFallbackHandlerContract = - await ethAdapter.getCompatibilityFallbackHandlerContract({ + await safeProvider.getCompatibilityFallbackHandlerContract({ safeVersion, customContractAddress: customContract.fallbackHandlerAddress, customContractAbi: customContract.fallbackHandlerAbi @@ -203,13 +175,10 @@ describe('Safe contracts', () => { describe('getSafeProxyFactoryContract', async () => { it('should return a SafeProxyFactory contract from safe-deployments', async () => { - const ethAdapter = await getEthAdapter(getNetworkProvider('mainnet')) + const safeProvider = getSafeProviderFromNetwork('mainnet') const safeVersion: SafeVersion = '1.3.0' - const chainId = 1n - const singletonDeployment = getSafeProxyFactoryContractDeployment(safeVersion, chainId) - const factoryContract = await ethAdapter.getSafeProxyFactoryContract({ - safeVersion, - singletonDeployment + const factoryContract = await safeProvider.getSafeProxyFactoryContract({ + safeVersion }) chai .expect(await factoryContract.getAddress()) @@ -217,12 +186,11 @@ describe('Safe contracts', () => { }) it('should return a SafeProxyFactory contract from the custom addresses', async () => { - const { accounts, contractNetworks, chainId } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { contractNetworks, chainId, provider } = await setupTests() + const safeProvider = new SafeProvider({ provider }) const safeVersion: SafeVersion = '1.3.0' const customContract = contractNetworks[chainId.toString()] - const factoryContract = await ethAdapter.getSafeProxyFactoryContract({ + const factoryContract = await safeProvider.getSafeProxyFactoryContract({ safeVersion, customContractAddress: customContract.safeProxyFactoryAddress, customContractAbi: customContract.safeProxyFactoryAbi @@ -235,13 +203,10 @@ describe('Safe contracts', () => { describe('getSignMessageLibContract', async () => { it('should return a SignMessageLib contract from safe-deployments', async () => { - const ethAdapter = await getEthAdapter(getNetworkProvider('mainnet')) + const safeProvider = getSafeProviderFromNetwork('mainnet') const safeVersion: SafeVersion = '1.3.0' - const chainId = 1n - const singletonDeployment = getSignMessageLibContractDeployment(safeVersion, chainId) - const signMessageLibContract = await ethAdapter.getSignMessageLibContract({ - safeVersion, - singletonDeployment + const signMessageLibContract = await safeProvider.getSignMessageLibContract({ + safeVersion }) chai .expect(await signMessageLibContract.getAddress()) @@ -249,12 +214,11 @@ describe('Safe contracts', () => { }) it('should return a SignMessageLib contract from the custom addresses', async () => { - const { accounts, contractNetworks, chainId } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { contractNetworks, chainId, provider } = await setupTests() + const safeProvider = new SafeProvider({ provider }) const safeVersion: SafeVersion = '1.3.0' const customContract = contractNetworks[chainId.toString()] - const signMessageLibContract = await ethAdapter.getSignMessageLibContract({ + const signMessageLibContract = await safeProvider.getSignMessageLibContract({ safeVersion, customContractAddress: customContract.signMessageLibAddress, customContractAbi: customContract.signMessageLibAbi @@ -267,13 +231,10 @@ describe('Safe contracts', () => { describe('getCreateCallContract', async () => { it('should return a CreateCall contract from safe-deployments', async () => { - const ethAdapter = await getEthAdapter(getNetworkProvider('mainnet')) + const safeProvider = getSafeProviderFromNetwork('mainnet') const safeVersion: SafeVersion = '1.3.0' - const chainId = 1n - const singletonDeployment = getCreateCallContractDeployment(safeVersion, chainId) - const createCallContract = await ethAdapter.getCreateCallContract({ - safeVersion, - singletonDeployment + const createCallContract = await safeProvider.getCreateCallContract({ + safeVersion }) chai .expect(await createCallContract.getAddress()) @@ -281,12 +242,11 @@ describe('Safe contracts', () => { }) it('should return a SafeProxyFactory contract from the custom addresses', async () => { - const { accounts, contractNetworks, chainId } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) + const { contractNetworks, chainId, provider } = await setupTests() + const safeProvider = new SafeProvider({ provider }) const safeVersion: SafeVersion = '1.3.0' const customContract = contractNetworks[chainId.toString()] - const createCallContract = await ethAdapter.getCreateCallContract({ + const createCallContract = await safeProvider.getCreateCallContract({ safeVersion, customContractAddress: customContract.createCallAddress, customContractAbi: customContract.createCallAbi @@ -295,5 +255,33 @@ describe('Safe contracts', () => { .expect(await createCallContract.getAddress()) .to.be.eq(await (await getCreateCall()).contract.getAddress()) }) + + it('should return an external provider (BrowserProvider) and signer (AbstractSigner) when using an EIP1193 provider', async () => { + const { provider } = await setupTests() + + const safeProvider = new SafeProvider({ provider }) + + chai.expect(safeProvider.getExternalProvider()).to.be.instanceOf(BrowserProvider) + chai.expect(await safeProvider.getExternalSigner()).to.be.instanceOf(AbstractSigner) + }) + + it('should return an external provider (JsonRpcProvider) and signer (AbstractSigner) when using a private key', async () => { + const safeProvider = new SafeProvider({ + provider: 'https://sepolia.gateway.tenderly.co', + signer: '4ff03ace1395691975678c93449d552dc83df6b773a8024d4c368b39042a7610' + }) + + chai.expect(safeProvider.getExternalProvider()).to.be.instanceOf(JsonRpcProvider) + chai.expect(await safeProvider.getExternalSigner()).to.be.instanceOf(AbstractSigner) + }) + + it('should return an undefined signer when using an RPC without signer', async () => { + const safeProvider = new SafeProvider({ + provider: 'https://sepolia.gateway.tenderly.co' + }) + + chai.expect(safeProvider.getExternalProvider()).to.be.instanceOf(JsonRpcProvider) + chai.expect(await safeProvider.getExternalSigner()).to.be.undefined + }) }) }) diff --git a/packages/protocol-kit/tests/e2e/threshold.test.ts b/packages/protocol-kit/tests/e2e/threshold.test.ts index 7397ad20f..03df88b85 100644 --- a/packages/protocol-kit/tests/e2e/threshold.test.ts +++ b/packages/protocol-kit/tests/e2e/threshold.test.ts @@ -8,7 +8,7 @@ import chaiAsPromised from 'chai-as-promised' import { deployments } from 'hardhat' import { getContractNetworks } from './utils/setupContractNetworks' import { getSafeWithOwners } from './utils/setupContracts' -import { getEthAdapter } from './utils/setupEthAdapter' +import { getEip1193Provider } from './utils/setupProvider' import { getAccounts } from './utils/setupTestNetwork' import { waitSafeTxReceipt } from './utils/transactions' @@ -29,21 +29,22 @@ describe('Safe Threshold', () => { safeVersion: safeVersionDeployed } } + const provider = getEip1193Provider() + return { safe: await getSafeWithOwners([accounts[0].address]), accounts, contractNetworks, - predictedSafe + predictedSafe, + provider } }) describe('getThreshold', async () => { it('should fail if the Safe is not deployed', async () => { - const { predictedSafe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { predictedSafe, contractNetworks, provider } = await setupTests() + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -51,11 +52,9 @@ describe('Safe Threshold', () => { }) it('should return the Safe threshold', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { safe, contractNetworks, provider } = await setupTests() + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -65,11 +64,9 @@ describe('Safe Threshold', () => { describe('createChangeThresholdTx', async () => { it('should fail if the Safe is not deployed', async () => { - const { predictedSafe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { predictedSafe, contractNetworks, provider } = await setupTests() + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -80,11 +77,9 @@ describe('Safe Threshold', () => { }) it('should fail if the threshold is bigger than the number of owners', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { safe, contractNetworks, provider } = await setupTests() + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -97,11 +92,9 @@ describe('Safe Threshold', () => { }) it('should fail if the threshold is not bigger than 0', async () => { - const { safe, accounts, contractNetworks } = await setupTests() - const [account1] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const { safe, contractNetworks, provider } = await setupTests() + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -112,12 +105,11 @@ describe('Safe Threshold', () => { }) it('should build the transaction with the optional props', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address, account2.address], 1) - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) @@ -141,12 +133,11 @@ describe('Safe Threshold', () => { }) it('should change the threshold', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address, account2.address], 1) - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress: await safe.getAddress(), contractNetworks }) diff --git a/packages/protocol-kit/tests/e2e/utils/setupContracts.ts b/packages/protocol-kit/tests/e2e/utils/setupContracts.ts index 4c4231288..af82e3ba7 100644 --- a/packages/protocol-kit/tests/e2e/utils/setupContracts.ts +++ b/packages/protocol-kit/tests/e2e/utils/setupContracts.ts @@ -1,4 +1,4 @@ -import { ZeroAddress } from 'ethers' +import { Contract, ZeroAddress, JsonFragment } from 'ethers' import { compatibilityFallbackHandlerDeployed, createCallDeployed, @@ -10,86 +10,36 @@ import { signMessageLibDeployed, simulateTxAccessorDeployed } from '@safe-global/protocol-kit/hardhat/deploy/deploy-contracts' -import { - Proxy_factory as SafeProxyFactory_V1_0_0, - Gnosis_safe as Safe_V1_0_0 -} from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.0.0' -import { - Multi_send as MultiSend_V1_1_1, - Proxy_factory as SafeProxyFactory_V1_1_1, - Gnosis_safe as Safe_V1_1_1 -} from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.1.1' -import { Gnosis_safe as Safe_V1_2_0 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.2.0' -import { - Compatibility_fallback_handler as CompatibilityFallbackHandler_V1_3_0, - Create_call as CreateCall_V1_3_0, - Multi_send_call_only as MultiSendCallOnly_V1_3_0, - Multi_send as MultiSend_V1_3_0, - Proxy_factory as SafeProxyFactory_V1_3_0, - Gnosis_safe as Safe_V1_3_0, - Sign_message_lib as SignMessageLib_V1_3_0, - Simulate_tx_accessor as SimulateTxAccessor_V1_3_0 -} from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.3.0' -import { - Compatibility_fallback_handler as CompatibilityFallbackHandler_V1_4_1, - Create_call as CreateCall_V1_4_1, - Multi_send_call_only as MultiSendCallOnly_V1_4_1, - Multi_send as MultiSend_V1_4_1, - Safe_proxy_factory as SafeProxyFactory_V1_4_1, - Safe as Safe_V1_4_1, - Sign_message_lib as SignMessageLib_V1_4_1, - Simulate_tx_accessor as SimulateTxAccessor_V1_4_1 -} from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.4.1' -import { - DailyLimitModule, - ERC20Mintable, - SocialRecoveryModule -} from '@safe-global/protocol-kit/typechain/tests/ethers-v6/v1.2.0' -import { DebugTransactionGuard } from '@safe-global/protocol-kit/typechain/tests/ethers-v6/v1.3.0' import { deployments, ethers } from 'hardhat' import semverSatisfies from 'semver/functions/satisfies' -import { AbiItem } from 'web3-utils' + +// TODO: changue contract por abitype objts export const getSafeSingleton = async (): Promise<{ - contract: Safe_V1_4_1 | Safe_V1_3_0 | Safe_V1_2_0 | Safe_V1_1_1 | Safe_V1_0_0 - abi: AbiItem | AbiItem[] + contract: Contract + abi: JsonFragment | JsonFragment[] }> => { const SafeDeployment = await deployments.get(safeDeployed.name) const Safe = await ethers.getContractFactory(safeDeployed.name) return { - contract: Safe.attach(SafeDeployment.address) as - | Safe_V1_4_1 - | Safe_V1_3_0 - | Safe_V1_2_0 - | Safe_V1_1_1 - | Safe_V1_0_0, + contract: Safe.attach(SafeDeployment.address), abi: SafeDeployment.abi } } export const getFactory = async (): Promise<{ - contract: - | SafeProxyFactory_V1_4_1 - | SafeProxyFactory_V1_3_0 - | SafeProxyFactory_V1_1_1 - | SafeProxyFactory_V1_0_0 - abi: AbiItem | AbiItem[] + contract: Contract + abi: JsonFragment | JsonFragment[] }> => { const FactoryDeployment = await deployments.get(proxyFactoryDeployed.name) const Factory = await ethers.getContractFactory(proxyFactoryDeployed.name) return { - contract: Factory.attach(FactoryDeployment.address) as - | SafeProxyFactory_V1_4_1 - | SafeProxyFactory_V1_3_0 - | SafeProxyFactory_V1_1_1 - | SafeProxyFactory_V1_0_0, + contract: Factory.attach(FactoryDeployment.address), abi: FactoryDeployment.abi } } -export const getSafeTemplate = async (): Promise< - Safe_V1_4_1 | Safe_V1_3_0 | Safe_V1_2_0 | Safe_V1_1_1 | Safe_V1_0_0 -> => { +export const getSafeTemplate = async (): Promise => { const randomSaltNonce = Math.floor(Math.random() * 1000000000) + 1 const singleton = (await getSafeSingleton()).contract const factory = (await getFactory()).contract @@ -103,22 +53,17 @@ export const getSafeTemplate = async (): Promise< .createProxyWithNonce(singletonAddress, '0x', randomSaltNonce) .then((tx: any) => tx.wait()) const Safe = await ethers.getContractFactory(safeDeployed.name) - return Safe.attach(template) as - | Safe_V1_4_1 - | Safe_V1_3_0 - | Safe_V1_2_0 - | Safe_V1_1_1 - | Safe_V1_0_0 + return Safe.attach(template) } export const getSafeWithOwners = async ( owners: string[], threshold?: number, fallbackHandler?: string -): Promise => { +): Promise => { const template = await getSafeTemplate() if (semverSatisfies(safeVersionDeployed, '<=1.0.0')) { - await (template as Safe_V1_0_0).setup( + await template.setup( owners, threshold || owners.length, ZeroAddress, @@ -128,7 +73,7 @@ export const getSafeWithOwners = async ( ZeroAddress ) } else { - await (template as Safe_V1_4_1 | Safe_V1_3_0 | Safe_V1_2_0 | Safe_V1_1_1).setup( + await template.setup( owners, threshold || owners.length, ZeroAddress, @@ -139,12 +84,12 @@ export const getSafeWithOwners = async ( ZeroAddress ) } - return template as Safe_V1_4_1 | Safe_V1_3_0 | Safe_V1_2_0 | Safe_V1_1_1 | Safe_V1_0_0 + return template } export const getCompatibilityFallbackHandler = async (): Promise<{ - contract: CompatibilityFallbackHandler_V1_4_1 | CompatibilityFallbackHandler_V1_3_0 - abi: AbiItem | AbiItem[] + contract: Contract + abi: JsonFragment | JsonFragment[] }> => { const CompatibilityFallbackHandlerDeployment = await deployments.get( compatibilityFallbackHandlerDeployed.name @@ -153,122 +98,115 @@ export const getCompatibilityFallbackHandler = async (): Promise<{ compatibilityFallbackHandlerDeployed.name ) return { - contract: CompatibilityFallbackHandler.attach( - CompatibilityFallbackHandlerDeployment.address - ) as CompatibilityFallbackHandler_V1_4_1 | CompatibilityFallbackHandler_V1_3_0, + contract: CompatibilityFallbackHandler.attach(CompatibilityFallbackHandlerDeployment.address), abi: CompatibilityFallbackHandlerDeployment.abi } } export const getMultiSend = async (): Promise<{ - contract: MultiSend_V1_4_1 | MultiSend_V1_3_0 | MultiSend_V1_1_1 - abi: AbiItem | AbiItem[] + contract: Contract + abi: JsonFragment | JsonFragment[] }> => { const MultiSendDeployment = await deployments.get(multiSendDeployed.name) const MultiSend = await ethers.getContractFactory(multiSendDeployed.name) return { - contract: MultiSend.attach(MultiSendDeployment.address) as - | MultiSend_V1_4_1 - | MultiSend_V1_3_0 - | MultiSend_V1_1_1, + contract: MultiSend.attach(MultiSendDeployment.address), abi: MultiSendDeployment.abi } } export const getMultiSendCallOnly = async (): Promise<{ - contract: MultiSendCallOnly_V1_4_1 | MultiSendCallOnly_V1_3_0 - abi: AbiItem | AbiItem[] + contract: Contract + abi: JsonFragment | JsonFragment[] }> => { const MultiSendCallOnlyDeployment = await deployments.get(multiSendCallOnlyDeployed.name) const MultiSendCallOnly = await ethers.getContractFactory(multiSendCallOnlyDeployed.name) return { - contract: MultiSendCallOnly.attach(MultiSendCallOnlyDeployment.address) as - | MultiSendCallOnly_V1_4_1 - | MultiSendCallOnly_V1_3_0, + contract: MultiSendCallOnly.attach(MultiSendCallOnlyDeployment.address), abi: MultiSendCallOnlyDeployment.abi } } export const getSignMessageLib = async (): Promise<{ - contract: SignMessageLib_V1_4_1 | SignMessageLib_V1_3_0 - abi: AbiItem | AbiItem[] + contract: Contract + abi: JsonFragment | JsonFragment[] }> => { const SignMessageLibDeployment = await deployments.get(signMessageLibDeployed.name) const SignMessageLib = await ethers.getContractFactory(signMessageLibDeployed.name) return { - contract: SignMessageLib.attach(SignMessageLibDeployment.address) as - | SignMessageLib_V1_4_1 - | SignMessageLib_V1_3_0, + contract: SignMessageLib.attach(SignMessageLibDeployment.address), abi: SignMessageLibDeployment.abi } } export const getCreateCall = async (): Promise<{ - contract: CreateCall_V1_4_1 | CreateCall_V1_3_0 - abi: AbiItem | AbiItem[] + contract: Contract + abi: JsonFragment | JsonFragment[] }> => { const CreateCallDeployment = await deployments.get(createCallDeployed.name) const CreateCall = await ethers.getContractFactory(createCallDeployed.name) return { - contract: CreateCall.attach(CreateCallDeployment.address) as - | CreateCall_V1_4_1 - | CreateCall_V1_3_0, + contract: CreateCall.attach(CreateCallDeployment.address), abi: CreateCallDeployment.abi } } export const getSimulateTxAccessor = async (): Promise<{ - contract: SimulateTxAccessor_V1_4_1 | SimulateTxAccessor_V1_3_0 - abi: AbiItem | AbiItem[] + contract: Contract + abi: JsonFragment | JsonFragment[] }> => { const SimulateTxAccessorDeployment = await deployments.get(simulateTxAccessorDeployed.name) const SimulateTxAccessor = await ethers.getContractFactory(simulateTxAccessorDeployed.name) return { - contract: SimulateTxAccessor.attach(SimulateTxAccessorDeployment.address) as - | SimulateTxAccessor_V1_4_1 - | SimulateTxAccessor_V1_3_0, + contract: SimulateTxAccessor.attach(SimulateTxAccessorDeployment.address), abi: SimulateTxAccessorDeployment.abi } } -export const getDailyLimitModule = async (): Promise => { +export const getDailyLimitModule = async (): Promise => { const DailyLimitModuleDeployment = await deployments.get('DailyLimitModule') const DailyLimitModule = await ethers.getContractFactory('DailyLimitModule') - return DailyLimitModule.attach(DailyLimitModuleDeployment.address) as DailyLimitModule + return DailyLimitModule.attach(DailyLimitModuleDeployment.address) } -export const getSocialRecoveryModule = async (): Promise => { +export const getSocialRecoveryModule = async (): Promise => { const SocialRecoveryModuleDeployment = await deployments.get('SocialRecoveryModule') const SocialRecoveryModule = await ethers.getContractFactory('SocialRecoveryModule') - return SocialRecoveryModule.attach(SocialRecoveryModuleDeployment.address) as SocialRecoveryModule + return SocialRecoveryModule.attach(SocialRecoveryModuleDeployment.address) +} + +export const getStateChannelModule = async (): Promise => { + const StateChannelModuleDeployment = await deployments.get('StateChannelModule') + const StateChannelModule = await ethers.getContractFactory('StateChannelModule') + return StateChannelModule.attach(StateChannelModuleDeployment.address) +} + +export const getWhiteListModule = async (): Promise => { + const WhiteListModuleDeployment = await deployments.get('WhitelistModule') + const WhiteListModule = await ethers.getContractFactory('WhitelistModule') + return WhiteListModule.attach(WhiteListModuleDeployment.address) } -export const getERC20Mintable = async (): Promise => { +export const getERC20Mintable = async (): Promise => { const ERC20MintableDeployment = await deployments.get('ERC20Mintable') const ERC20Mintable = await ethers.getContractFactory('ERC20Mintable') - return ERC20Mintable.attach(ERC20MintableDeployment.address) as ERC20Mintable + return ERC20Mintable.attach(ERC20MintableDeployment.address) } -export const getDebugTransactionGuard = async (): Promise => { +export const getDebugTransactionGuard = async (): Promise => { const contractName = semverSatisfies(safeVersionDeployed, '<=1.3.0') ? 'DebugTransactionGuard_SV1_3_0' : 'DebugTransactionGuard_SV1_4_1' const DebugTransactionGuardDeployment = await deployments.get(contractName) const DebugTransactionGuard = await ethers.getContractFactory(contractName) - return DebugTransactionGuard.attach( - DebugTransactionGuardDeployment.address - ) as DebugTransactionGuard + return DebugTransactionGuard.attach(DebugTransactionGuardDeployment.address) } -//@ts-expect-error Type not found -export const getDefaultCallbackHandler = async (): Promise => { +export const getDefaultCallbackHandler = async (): Promise => { const contractName = semverSatisfies(safeVersionDeployed, '<=1.3.0') ? 'DefaultCallbackHandler_SV1_3_0' : 'TokenCallbackHandler_SV1_4_1' const DefaultCallbackHandlerDeployment = await deployments.get(contractName) const DefaultCallbackHandler = await ethers.getContractFactory(contractName) - return DefaultCallbackHandler.attach( - DefaultCallbackHandlerDeployment.address - //@ts-expect-error Type not found - ) as DefaultCallbackHandler + return DefaultCallbackHandler.attach(DefaultCallbackHandlerDeployment.address) } diff --git a/packages/protocol-kit/tests/e2e/utils/setupEthAdapter.ts b/packages/protocol-kit/tests/e2e/utils/setupEthAdapter.ts deleted file mode 100644 index ed4783583..000000000 --- a/packages/protocol-kit/tests/e2e/utils/setupEthAdapter.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { Provider, AbstractSigner } from 'ethers' -import { - EthersAdapter, - EthersAdapterConfig, - Web3Adapter, - Web3AdapterConfig -} from '@safe-global/protocol-kit/index' -import { EthAdapter } from '@safe-global/safe-core-sdk-types' -import { ethers, web3 } from 'hardhat' -import Web3 from 'web3' -import { HardhatEthersSigner } from '@nomicfoundation/hardhat-ethers/signers' - -type Network = 'mainnet' | 'gnosis' | 'zksync' | 'goerli' | 'sepolia' - -export async function getEthAdapter( - signerOrProvider: AbstractSigner | Provider | Web3 -): Promise { - let ethAdapter: EthAdapter - switch (process.env.ETH_LIB) { - case 'web3': - const signerAddress = - signerOrProvider instanceof HardhatEthersSigner - ? await signerOrProvider.getAddress() - : undefined - - const web3Instance = signerOrProvider instanceof Web3 ? signerOrProvider : web3 - const web3AdapterConfig: Web3AdapterConfig = { web3: web3Instance, signerAddress } - ethAdapter = new Web3Adapter(web3AdapterConfig) - break - case 'ethers': - const ethersAdapterConfig: EthersAdapterConfig = { - ethers, - signerOrProvider: signerOrProvider as Provider - } - ethAdapter = new EthersAdapter(ethersAdapterConfig) - break - default: - throw new Error('Ethereum library not supported') - } - - return ethAdapter -} - -export function getNetworkProvider(network: Network): Provider | Web3 { - let rpcUrl: string - switch (network) { - case 'zksync': - rpcUrl = 'https://mainnet.era.zksync.io' - break - case 'gnosis': - rpcUrl = 'https://rpc.gnosischain.com' - break - case 'goerli': - rpcUrl = 'https://rpc.ankr.com/eth_goerli' - break - case 'sepolia': - rpcUrl = 'https://rpc.ankr.com/eth_sepolia' - break - case 'mainnet': - rpcUrl = 'https://rpc.ankr.com/eth' - break - default: - throw new Error('Chain not supported') - } - - let provider - switch (process.env.ETH_LIB) { - case 'web3': - provider = new Web3(rpcUrl) - break - case 'ethers': - provider = new ethers.JsonRpcProvider(rpcUrl) - break - default: - throw new Error('Ethereum library not supported') - } - - return provider -} diff --git a/packages/protocol-kit/tests/e2e/utils/setupProvider.ts b/packages/protocol-kit/tests/e2e/utils/setupProvider.ts new file mode 100644 index 000000000..35d8bf59b --- /dev/null +++ b/packages/protocol-kit/tests/e2e/utils/setupProvider.ts @@ -0,0 +1,64 @@ +import hre, { ethers } from 'hardhat' +import Web3 from 'web3' +import { HardhatEthersSigner } from '@nomicfoundation/hardhat-ethers/signers' +import { custom, createWalletClient } from 'viem' + +import { SafeProvider } from '@safe-global/protocol-kit/index' +import { Eip1193Provider } from '@safe-global/protocol-kit/types' + +type Network = 'mainnet' | 'gnosis' | 'zksync' | 'goerli' | 'sepolia' + +export function getEip1193Provider(): Eip1193Provider { + switch (process.env.ETH_LIB) { + case 'viem': + const client = createWalletClient({ + transport: custom(hre.network.provider) + }) + + return { request: client.request } as Eip1193Provider + + case 'web3': + const web3Provider = new Web3(hre.network.provider) + + return web3Provider.currentProvider as Eip1193Provider + + case 'ethers': + const browserProvider = new ethers.BrowserProvider(hre.network.provider) + + return { + request: async (request) => { + return browserProvider.send(request.method, [...((request.params as unknown[]) ?? [])]) + } + } + default: + throw new Error('ETH_LIB not set') + } +} + +export function getSafeProviderFromNetwork( + network: Network, + signer?: HardhatEthersSigner +): SafeProvider { + let rpcUrl: string + switch (network) { + case 'zksync': + rpcUrl = 'https://mainnet.era.zksync.io' + break + case 'gnosis': + rpcUrl = 'https://rpc.gnosischain.com' + break + case 'goerli': + rpcUrl = 'https://rpc.ankr.com/eth_goerli' + break + case 'sepolia': + rpcUrl = 'https://sepolia.gateway.tenderly.co' + break + case 'mainnet': + rpcUrl = 'https://rpc.ankr.com/eth' + break + default: + throw new Error('Chain not supported') + } + + return new SafeProvider({ provider: rpcUrl, signer: signer?.address }) +} diff --git a/packages/protocol-kit/tests/e2e/utils/setupTestNetwork.ts b/packages/protocol-kit/tests/e2e/utils/setupTestNetwork.ts index 8e08c7cb0..43455ad0d 100644 --- a/packages/protocol-kit/tests/e2e/utils/setupTestNetwork.ts +++ b/packages/protocol-kit/tests/e2e/utils/setupTestNetwork.ts @@ -1,22 +1,10 @@ import { HardhatEthersSigner } from '@nomicfoundation/hardhat-ethers/signers' -import { ethers, Web3 } from 'hardhat' +import { ethers } from 'hardhat' interface Account { signer: HardhatEthersSigner address: string } -async function getGanacheAccounts(): Promise { - const web3 = new Web3('http://localhost:8545') - const provider = new ethers.BrowserProvider(web3.currentProvider as any) - const accounts: Account[] = [] - for (let i = 0; i < 10; i++) { - const signer = provider.getSigner(i) - const account: Account = { signer, address: await signer.getAddress() } - accounts.push(account) - } - return accounts -} - async function getHardhatAccounts(): Promise { const wallets = await ethers.getSigners() @@ -32,7 +20,6 @@ async function getHardhatAccounts(): Promise { } export async function getAccounts(): Promise { - const accounts = - process.env.TEST_NETWORK === 'ganache' ? await getGanacheAccounts() : await getHardhatAccounts() + const accounts = await getHardhatAccounts() return accounts } diff --git a/packages/protocol-kit/tests/e2e/utils/transactions.ts b/packages/protocol-kit/tests/e2e/utils/transactions.ts index 5cb7f6d7d..27265dbd1 100644 --- a/packages/protocol-kit/tests/e2e/utils/transactions.ts +++ b/packages/protocol-kit/tests/e2e/utils/transactions.ts @@ -1,27 +1,19 @@ import { ContractTransactionReceipt } from 'ethers' -import { EthAdapter, TransactionResult } from '@safe-global/safe-core-sdk-types' -import { TransactionReceipt } from 'web3-core/types' +import { TransactionResult } from '@safe-global/safe-core-sdk-types' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' export async function waitSafeTxReceipt( txResult: TransactionResult -): Promise { - const receipt: ContractTransactionReceipt | TransactionReceipt | undefined = txResult.promiEvent - ? await new Promise( - (resolve, reject) => - txResult.promiEvent && - txResult.promiEvent - .on('confirmation', (_confirmationNumber: any, receipt: TransactionReceipt) => - resolve(receipt) - ) - .catch(reject) - ) - : txResult.transactionResponse && (await txResult.transactionResponse.wait()) +): Promise { + const receipt: ContractTransactionReceipt | null | undefined = + txResult.transactionResponse && (await txResult.transactionResponse.wait()) + return receipt } export async function getTransaction( - ethAdapter: EthAdapter, + safeProvider: SafeProvider, transactionHash: string ): Promise { - return ethAdapter.getTransaction(transactionHash) + return safeProvider.getTransaction(transactionHash) } diff --git a/packages/protocol-kit/tests/e2e/utilsContracts.test.ts b/packages/protocol-kit/tests/e2e/utilsContracts.test.ts index 74b01790a..c2827e7f4 100644 --- a/packages/protocol-kit/tests/e2e/utilsContracts.test.ts +++ b/packages/protocol-kit/tests/e2e/utilsContracts.test.ts @@ -1,10 +1,9 @@ import chai from 'chai' import { deployments } from 'hardhat' - import { getAccounts } from './utils/setupTestNetwork' import { getContractNetworks } from './utils/setupContractNetworks' import { getDefaultCallbackHandler } from './utils/setupContracts' -import { getEthAdapter, getNetworkProvider } from './utils/setupEthAdapter' +import { getEip1193Provider, getSafeProviderFromNetwork } from './utils/setupProvider' import { PREDETERMINED_SALT_NONCE, predictSafeAddress @@ -13,20 +12,23 @@ import { safeVersionDeployed } from '@safe-global/protocol-kit/hardhat/deploy/de import { SafeDeploymentConfig, SafeAccountConfig, - ContractNetworksConfig + ContractNetworksConfig, + Eip1193Provider } from '@safe-global/protocol-kit/types' import Safe, { SafeFactory, DeploySafeProps } from '@safe-global/protocol-kit/index' -import { EthAdapter } from '@safe-global/safe-core-sdk-types' +import SafeProvider from '@safe-global/protocol-kit/SafeProvider' import { itif } from './utils/helpers' // test util funcion to deploy a safe (needed to check the expected Safe Address) async function deploySafe( deploySafeProps: DeploySafeProps, - ethAdapter: EthAdapter, - contractNetworks: ContractNetworksConfig + provider: Eip1193Provider, + contractNetworks: ContractNetworksConfig, + signerAddress?: string ): Promise { - const safeFactory = await SafeFactory.create({ - ethAdapter, + const safeFactory = await SafeFactory.init({ + provider, + signer: signerAddress, safeVersion: safeVersionDeployed, contractNetworks }) @@ -40,24 +42,27 @@ describe('Contract utils', () => { const accounts = await getAccounts() const chainId = BigInt(await getChainId()) const contractNetworks = await getContractNetworks(chainId) + const provider = getEip1193Provider() + return { defaultCallbackHandler: await getDefaultCallbackHandler(), chainId, accounts, - contractNetworks + contractNetworks, + provider } }) describe('predictSafeAddress', () => { it('returns the predicted address of a 1/1 Safe', async () => { - const { accounts, contractNetworks, chainId } = await setupTests() + const { accounts, contractNetworks, chainId, provider } = await setupTests() // 1/1 Safe const [owner1] = accounts const owners = [owner1.address] const threshold = 1 const safeVersion = safeVersionDeployed - const ethAdapter = await getEthAdapter(owner1.signer) + const safeProvider = new SafeProvider({ provider }) const customContracts = contractNetworks[chainId.toString()] const safeAccountConfig: SafeAccountConfig = { @@ -71,7 +76,7 @@ describe('Contract utils', () => { } const predictedSafeAddress = await predictSafeAddress({ - ethAdapter, + safeProvider, chainId, safeAccountConfig, safeDeploymentConfig, @@ -81,8 +86,9 @@ describe('Contract utils', () => { // we deploy the Safe with the given configuration and the deployed Safe address should be equal to the predicted one const deployedSafe = await deploySafe( { safeAccountConfig, saltNonce: safeDeploymentConfig.saltNonce }, - ethAdapter, - contractNetworks + provider, + contractNetworks, + owner1.address ) // We ensure the Safe is deployed, as getAddress() function is able to return an address for a predictedSafe @@ -94,14 +100,14 @@ describe('Contract utils', () => { }) it('returns the predicted address of a 1/2 Safe', async () => { - const { accounts, contractNetworks, chainId } = await setupTests() + const { accounts, contractNetworks, chainId, provider } = await setupTests() // 1/2 Safe const [owner1, owner2] = accounts const owners = [owner1.address, owner2.address] const threshold = 1 const safeVersion = safeVersionDeployed - const ethAdapter = await getEthAdapter(owner1.signer) + const safeProvider = new SafeProvider({ provider }) const customContracts = contractNetworks[chainId.toString()] const safeAccountConfig: SafeAccountConfig = { @@ -115,7 +121,7 @@ describe('Contract utils', () => { } const predictedSafeAddress = await predictSafeAddress({ - ethAdapter, + safeProvider, chainId, safeAccountConfig, safeDeploymentConfig, @@ -125,8 +131,9 @@ describe('Contract utils', () => { // we deploy the Safe with the given configuration and the deployed Safe address should be equal to the predicted one const deployedSafe = await deploySafe( { safeAccountConfig, saltNonce: safeDeploymentConfig.saltNonce }, - ethAdapter, - contractNetworks + provider, + contractNetworks, + owner1.address ) // We ensure the Safe is deployed, as getAddress() function is able to return an address for a predictedSafe @@ -138,14 +145,14 @@ describe('Contract utils', () => { }) it('returns the predicted address of a 2/2 Safe', async () => { - const { accounts, contractNetworks, chainId } = await setupTests() + const { accounts, contractNetworks, chainId, provider } = await setupTests() // 2/2 Safe const [owner1, owner2] = accounts const owners = [owner1.address, owner2.address] const threshold = 2 const safeVersion = safeVersionDeployed - const ethAdapter = await getEthAdapter(owner1.signer) + const safeProvider = new SafeProvider({ provider }) const customContracts = contractNetworks[chainId.toString()] const safeAccountConfig: SafeAccountConfig = { @@ -159,7 +166,7 @@ describe('Contract utils', () => { } const predictedSafeAddress = await predictSafeAddress({ - ethAdapter, + safeProvider, chainId, safeAccountConfig, safeDeploymentConfig, @@ -169,8 +176,9 @@ describe('Contract utils', () => { // we deploy the Safe with the given configuration and the deployed Safe address should be equal to the predicted one const deployedSafe = await deploySafe( { safeAccountConfig, saltNonce: safeDeploymentConfig.saltNonce }, - ethAdapter, - contractNetworks + provider, + contractNetworks, + owner1.address ) // We ensure the Safe is deployed, as getAddress() function is able to return an address for a predictedSafe @@ -182,14 +190,14 @@ describe('Contract utils', () => { }) it('should fail if the provided threshold is invalid (greater than owners length)', async () => { - const { accounts, contractNetworks, chainId } = await setupTests() + const { accounts, contractNetworks, chainId, provider } = await setupTests() // invalid threshold 3/2 Safe const [owner1, owner2] = accounts const owners = [owner1.address, owner2.address] const invalidThreshold = 3 const safeVersion = safeVersionDeployed - const ethAdapter = await getEthAdapter(owner1.signer) + const safeProvider = new SafeProvider({ provider }) const customContracts = contractNetworks[chainId.toString()] const safeAccountConfig: SafeAccountConfig = { @@ -203,7 +211,7 @@ describe('Contract utils', () => { } const predictSafeAddressWithInvalidThreshold = { - ethAdapter, + safeProvider, chainId, safeAccountConfig, safeDeploymentConfig, @@ -216,14 +224,14 @@ describe('Contract utils', () => { }) it('should fail if the provided threshold is invalid (zero value)', async () => { - const { accounts, contractNetworks, chainId } = await setupTests() + const { accounts, contractNetworks, chainId, provider } = await setupTests() // invalid threshold 0/2 Safe const [owner1, owner2] = accounts const owners = [owner1.address, owner2.address] const invalidThreshold = 0 const safeVersion = safeVersionDeployed - const ethAdapter = await getEthAdapter(owner1.signer) + const safeProvider = new SafeProvider({ provider }) const customContracts = contractNetworks[chainId.toString()] const safeAccountConfig: SafeAccountConfig = { @@ -237,7 +245,7 @@ describe('Contract utils', () => { } const predictSafeAddressWithInvalidThreshold = { - ethAdapter, + safeProvider, chainId, safeAccountConfig, safeDeploymentConfig, @@ -250,14 +258,14 @@ describe('Contract utils', () => { }) it('should fail if the provided threshold is invalid (negative value)', async () => { - const { accounts, contractNetworks, chainId } = await setupTests() + const { accounts, contractNetworks, chainId, provider } = await setupTests() // invalid threshold -2/2 Safe const [owner1, owner2] = accounts const owners = [owner1.address, owner2.address] const invalidThreshold = -2 const safeVersion = safeVersionDeployed - const ethAdapter = await getEthAdapter(owner1.signer) + const safeProvider = new SafeProvider({ provider }) const customContracts = contractNetworks[chainId.toString()] const safeAccountConfig: SafeAccountConfig = { @@ -271,7 +279,7 @@ describe('Contract utils', () => { } const predictSafeAddressWithInvalidThreshold = { - ethAdapter, + safeProvider, chainId, safeAccountConfig, safeDeploymentConfig, @@ -284,13 +292,13 @@ describe('Contract utils', () => { }) it('should fail if no owners are present (empty array)', async () => { - const { accounts, contractNetworks, chainId } = await setupTests() + const { contractNetworks, chainId, provider } = await setupTests() // invalid owners 1/0 Safe const invalidOwners: string[] = [] const threshold = 1 const safeVersion = safeVersionDeployed - const ethAdapter = await getEthAdapter(accounts[0].signer) + const safeProvider = new SafeProvider({ provider }) const customContracts = contractNetworks[chainId.toString()] const safeAccountConfig: SafeAccountConfig = { @@ -304,7 +312,7 @@ describe('Contract utils', () => { } const predictSafeAddressWithInvalidThreshold = { - ethAdapter, + safeProvider, chainId, safeAccountConfig, safeDeploymentConfig, @@ -317,14 +325,14 @@ describe('Contract utils', () => { }) it('returns different addresses with different saltNonce value but same Safe config (threshold & owners)', async () => { - const { accounts, contractNetworks, chainId } = await setupTests() + const { accounts, contractNetworks, chainId, provider } = await setupTests() // 1/2 Safe const [owner1, owner2] = accounts const owners = [owner1.address, owner2.address] const threshold = 1 const safeVersion = safeVersionDeployed - const ethAdapter = await getEthAdapter(owner1.signer) + const safeProvider = new SafeProvider({ provider }) const customContracts = contractNetworks[chainId.toString()] const safeAccountConfig: SafeAccountConfig = { @@ -337,7 +345,7 @@ describe('Contract utils', () => { const thirdSaltNonce = '3' const predictedSafeAddress1 = await predictSafeAddress({ - ethAdapter, + safeProvider, chainId, safeAccountConfig, safeDeploymentConfig: { @@ -350,8 +358,9 @@ describe('Contract utils', () => { // we deploy the Safe with the given configuration and the deployed Safe address should be equal to the predicted one const firstDeployedSafe = await deploySafe( { safeAccountConfig, saltNonce: firstSaltNonce }, - ethAdapter, - contractNetworks + provider, + contractNetworks, + owner1.address ) // We ensure the Safe is deployed, as getAddress() function is able to return an address for a predictedSafe @@ -360,7 +369,7 @@ describe('Contract utils', () => { chai.expect(predictedSafeAddress1).to.be.equal(await firstDeployedSafe.getAddress()) const predictedSafeAddress2 = await predictSafeAddress({ - ethAdapter, + safeProvider, chainId, safeAccountConfig, safeDeploymentConfig: { @@ -373,8 +382,9 @@ describe('Contract utils', () => { // we deploy the Safe with the given configuration and the deployed Safe address should be equal to the predicted one const secondDeployedSafe = await deploySafe( { safeAccountConfig, saltNonce: secondSaltNonce }, - ethAdapter, - contractNetworks + provider, + contractNetworks, + owner1.address ) // We ensure the Safe is deployed, as getAddress() function is able to return an address for a predictedSafe @@ -383,7 +393,7 @@ describe('Contract utils', () => { chai.expect(predictedSafeAddress2).to.be.equal(await secondDeployedSafe.getAddress()) const predictedSafeAddress3 = await predictSafeAddress({ - ethAdapter, + safeProvider, chainId, safeAccountConfig, safeDeploymentConfig: { @@ -396,8 +406,9 @@ describe('Contract utils', () => { // we deploy the Safe with the given configuration and the deployed Safe address should be equal to the predicted one const thirdDeployedSafe = await deploySafe( { safeAccountConfig, saltNonce: thirdSaltNonce }, - ethAdapter, - contractNetworks + provider, + contractNetworks, + owner1.address ) // We ensure the Safe is deployed, as getAddress() function is able to return an address for a predictedSafe @@ -407,14 +418,14 @@ describe('Contract utils', () => { }) it('returns the same predicted address for multiple calls to predictedSafeAddress with the same config (owners, threshold & saltNonce)', async () => { - const { accounts, contractNetworks, chainId } = await setupTests() + const { accounts, contractNetworks, chainId, provider } = await setupTests() // 2/2 Safe const [owner1, owner2] = accounts const owners = [owner1.address, owner2.address] const threshold = 2 const safeVersion = safeVersionDeployed - const ethAdapter = await getEthAdapter(owner1.signer) + const safeProvider = new SafeProvider({ provider }) const customContracts = contractNetworks[chainId.toString()] const safeAccountConfig: SafeAccountConfig = { @@ -430,15 +441,16 @@ describe('Contract utils', () => { // we deploy the Safe with the given configuration and the deployed Safe address should be equal to the predicted one const deployedSafe = await deploySafe( { safeAccountConfig, saltNonce: safeDeploymentConfig.saltNonce }, - ethAdapter, - contractNetworks + provider, + contractNetworks, + owner1.address ) // We ensure the Safe is deployed, as getAddress() function is able to return an address for a predictedSafe const isSafeDeployed = await deployedSafe.isSafeDeployed() const expectedSafeAddress = await deployedSafe.getAddress() const firstPredictedSafeAddress = await predictSafeAddress({ - ethAdapter, + safeProvider, chainId, safeAccountConfig, safeDeploymentConfig, @@ -446,7 +458,7 @@ describe('Contract utils', () => { }) const secondPredictedSafeAddress = await predictSafeAddress({ - ethAdapter, + safeProvider, chainId, safeAccountConfig, safeDeploymentConfig, @@ -454,7 +466,7 @@ describe('Contract utils', () => { }) const thirdPredictedSafeAddress = await predictSafeAddress({ - ethAdapter, + safeProvider, chainId, safeAccountConfig, safeDeploymentConfig, @@ -471,13 +483,12 @@ describe('Contract utils', () => { itif(safeVersionDeployed > '1.0.0')( 'safeDeploymentConfig is an optional parameter', async () => { - const { accounts, contractNetworks, chainId } = await setupTests() + const { accounts, contractNetworks, chainId, provider } = await setupTests() // 1/1 Safe const [owner1] = accounts const owners = [owner1.address] const threshold = 1 - const ethAdapter = await getEthAdapter(owner1.signer) const customContracts = contractNetworks[chainId.toString()] const safeAccountConfig: SafeAccountConfig = { @@ -485,15 +496,22 @@ describe('Contract utils', () => { threshold } + const safeProvider = new SafeProvider({ provider }) + const predictedSafeAddress = await predictSafeAddress({ - ethAdapter, + safeProvider, chainId, safeAccountConfig, customContracts }) // we deploy the Safe by providing only the safeAccountConfig (owners & threshold) - const deployedSafe = await deploySafe({ safeAccountConfig }, ethAdapter, contractNetworks) + const deployedSafe = await deploySafe( + { safeAccountConfig }, + provider, + contractNetworks, + owner1.address + ) // We ensure the Safe is deployed const isSafeDeployed = await deployedSafe.isSafeDeployed() @@ -511,9 +529,9 @@ describe('Contract utils', () => { const { contractNetworks } = await setupTests() const safeVersion = safeVersionDeployed - // Create EthAdapter instance - const ethAdapter = await getEthAdapter(getNetworkProvider('zksync')) - const chainId = await ethAdapter.getChainId() + // Create SafeProvider instance + const safeProvider = getSafeProviderFromNetwork('zksync') + const chainId = await safeProvider.getChainId() const customContracts = contractNetworks[chainId.toString()] // We check real deployments from zksync return the expected address. @@ -530,7 +548,7 @@ describe('Contract utils', () => { const expectedSafeAddress1 = '0x4e19dA81a54eFbaBeb9AD50646f7643076475D65' const firstPredictedSafeAddress = await predictSafeAddress({ - ethAdapter, + safeProvider, chainId, safeAccountConfig: safeAccountConfig1, safeDeploymentConfig: safeDeploymentConfig1, @@ -552,7 +570,7 @@ describe('Contract utils', () => { const expectedSafeAddress2 = '0x60c7F13dE7C8Fb88b3845e58859658bdc44243F8' const secondPredictedSafeAddress = await predictSafeAddress({ - ethAdapter, + safeProvider, chainId, safeAccountConfig: safeAccountConfig2, safeDeploymentConfig: safeDeploymentConfig2, @@ -575,7 +593,7 @@ describe('Contract utils', () => { const expectedSafeAddress3 = '0xD971FAA20db3ad4d51D453047ca03Ce4ec164CE2' const thirdPredictedSafeAddress = await predictSafeAddress({ - ethAdapter, + safeProvider, chainId, safeAccountConfig: safeAccountConfig3, safeDeploymentConfig: safeDeploymentConfig3, @@ -597,10 +615,10 @@ describe('Contract utils', () => { const [owner] = accounts const safeVersion = safeVersionDeployed - const gnosisEthAdapter = await getEthAdapter(getNetworkProvider('gnosis')) - const zkSyncEthAdapter = await getEthAdapter(getNetworkProvider('zksync')) - const sepoliaEthAdapter = await getEthAdapter(getNetworkProvider('sepolia')) - const mainnetEthAdapter = await getEthAdapter(getNetworkProvider('mainnet')) + const gnosisSafeProvider = getSafeProviderFromNetwork('gnosis') + const zkSyncSafeProvider = getSafeProviderFromNetwork('zksync') + const sepoliaSafeProvider = getSafeProviderFromNetwork('sepolia') + const mainnetSafeProvider = getSafeProviderFromNetwork('mainnet') // 1/1 Safe const safeAccountConfig: SafeAccountConfig = { @@ -613,37 +631,37 @@ describe('Contract utils', () => { } const gnosisPredictedSafeAddress = await predictSafeAddress({ - ethAdapter: gnosisEthAdapter, - chainId: await gnosisEthAdapter.getChainId(), + safeProvider: gnosisSafeProvider, + chainId: await gnosisSafeProvider.getChainId(), safeAccountConfig: safeAccountConfig, safeDeploymentConfig: safeDeploymentConfig }) const zkSyncPredictedSafeAddress = await predictSafeAddress({ - ethAdapter: zkSyncEthAdapter, - chainId: await zkSyncEthAdapter.getChainId(), + safeProvider: zkSyncSafeProvider, + chainId: await zkSyncSafeProvider.getChainId(), safeAccountConfig: safeAccountConfig, safeDeploymentConfig: safeDeploymentConfig }) const sepoliaPredictedSafeAddress = await predictSafeAddress({ - ethAdapter: sepoliaEthAdapter, - chainId: await sepoliaEthAdapter.getChainId(), + safeProvider: sepoliaSafeProvider, + chainId: await sepoliaSafeProvider.getChainId(), safeAccountConfig: safeAccountConfig, safeDeploymentConfig: safeDeploymentConfig }) const mainnetPredictedSafeAddress = await predictSafeAddress({ - ethAdapter: mainnetEthAdapter, - chainId: await mainnetEthAdapter.getChainId(), + safeProvider: mainnetSafeProvider, + chainId: await mainnetSafeProvider.getChainId(), safeAccountConfig: safeAccountConfig, safeDeploymentConfig: safeDeploymentConfig }) - const expectedGnosisSafeAddress = '0x30421B2bE26942448CD6C690f21F551BF6C8A45F' + const expectedGnosisSafeAddress = '0x39aC50A7B35c43429397D0481EBa8769B5e4b9a6' const expectedSkSyncSafeAddress = '0x4680B7AC23A98d5D68c21e3d6F8cBC9576A5920A' - const expectedSepoliaSafeAddress = '0x7f44E49C9E4C7D19fA2A704c2E66527Bd4688f99' - const expectedMainnetSafeAddress = '0x9C1C8c37a68242cEC6d68Ab091583c81FBF479C0' + const expectedSepoliaSafeAddress = '0x643bD5C3Fd6c546c1452A16f978C350F8a0A2a8D' + const expectedMainnetSafeAddress = '0x22b257EABfA3B8BC9e0C5f6BA03400933834675B' // returns the correct predicted address for each chain chai.expect(gnosisPredictedSafeAddress).to.be.equal(expectedGnosisSafeAddress) diff --git a/packages/protocol-kit/tests/e2e/wrapSafeTransactionIntoDeploymentBatch.test.ts b/packages/protocol-kit/tests/e2e/wrapSafeTransactionIntoDeploymentBatch.test.ts index ba6c14285..be1f3bb03 100644 --- a/packages/protocol-kit/tests/e2e/wrapSafeTransactionIntoDeploymentBatch.test.ts +++ b/packages/protocol-kit/tests/e2e/wrapSafeTransactionIntoDeploymentBatch.test.ts @@ -6,7 +6,7 @@ import Safe, { PredictedSafeProps } from '@safe-global/protocol-kit/index' import { getContractNetworks } from './utils/setupContractNetworks' import { itif } from './utils/helpers' import { getSafeWithOwners, getMultiSendCallOnly } from './utils/setupContracts' -import { getEthAdapter } from './utils/setupEthAdapter' +import { getEip1193Provider } from './utils/setupProvider' import { getAccounts } from './utils/setupTestNetwork' chai.use(chaiAsPromised) @@ -29,25 +29,26 @@ describe('wrapSafeTransactionIntoDeploymentBatch', () => { safeVersion: safeVersionDeployed } } + const provider = getEip1193Provider() return { accounts, contractNetworks, predictedSafe, - chainId + chainId, + provider } }) it('should throw an error if the Safe is already deployed', async () => { - const { accounts, contractNetworks } = await setupTests() + const { accounts, contractNetworks, provider } = await setupTests() const [account1, account2] = accounts const safe = await getSafeWithOwners([account1.address]) const safeAddress = await safe.getAddress() - const ethAdapter = await getEthAdapter(account1.signer) - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, safeAddress, contractNetworks }) @@ -70,13 +71,11 @@ describe('wrapSafeTransactionIntoDeploymentBatch', () => { itif(safeVersionDeployed == '1.4.1')( 'should return a batch transaction with the Safe deployment Transaction and the Safe Transaction', async () => { - const { accounts, contractNetworks, predictedSafe } = await setupTests() - const [account1, account2] = accounts + const { accounts, contractNetworks, predictedSafe, provider } = await setupTests() + const [, account2] = accounts - const ethAdapter = await getEthAdapter(account1.signer) - - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -106,13 +105,11 @@ describe('wrapSafeTransactionIntoDeploymentBatch', () => { itif(safeVersionDeployed == '1.3.0')( 'should return a batch transaction with the Safe deployment Transaction and the Safe Transaction', async () => { - const { accounts, contractNetworks, predictedSafe } = await setupTests() - const [account1, account2] = accounts - - const ethAdapter = await getEthAdapter(account1.signer) + const { accounts, contractNetworks, predictedSafe, provider } = await setupTests() + const [, account2] = accounts - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -142,13 +139,11 @@ describe('wrapSafeTransactionIntoDeploymentBatch', () => { itif(safeVersionDeployed >= '1.3.0')( 'should include the custom salt nonce in the Safe deployment data', async () => { - const { accounts, contractNetworks, predictedSafe } = await setupTests() - const [account1, account2] = accounts - - const ethAdapter = await getEthAdapter(account1.signer) + const { accounts, contractNetworks, predictedSafe, provider } = await setupTests() + const [, account2] = accounts - const safeSdk = await Safe.create({ - ethAdapter, + const safeSdk = await Safe.init({ + provider, predictedSafe, contractNetworks }) @@ -171,7 +166,9 @@ describe('wrapSafeTransactionIntoDeploymentBatch', () => { customSaltNonce ) - const customSaltNonceEncoded = ethAdapter.encodeParameters(['uint256'], [customSaltNonce]) + const customSaltNonceEncoded = safeSdk + .getSafeProvider() + .encodeParameters(['uint256'], [customSaltNonce]) // custom salt nonce included in the deployment data chai.expect(batchTransaction.data).to.contains(customSaltNonceEncoded.replace('0x', '')) diff --git a/packages/protocol-kit/tsconfig.build.json b/packages/protocol-kit/tsconfig.build.json index 7c1f1d48c..c05e497c4 100644 --- a/packages/protocol-kit/tsconfig.build.json +++ b/packages/protocol-kit/tsconfig.build.json @@ -4,5 +4,5 @@ "composite": true, "outDir": "dist" }, - "include": ["src/**/*", "typechain/**/*"] + "include": ["src/**/*"] } diff --git a/packages/protocol-kit/tsconfig.json b/packages/protocol-kit/tsconfig.json index bf7362a55..5f6bc90a7 100644 --- a/packages/protocol-kit/tsconfig.json +++ b/packages/protocol-kit/tsconfig.json @@ -4,5 +4,5 @@ "composite": true, "outDir": "dist" }, - "include": ["src/**/*", "typechain/**/*", "tests/**/*", "hardhat/**/*", "hardhat.config.ts"] + "include": ["src/**/*", "tests/**/*", "hardhat/**/*", "hardhat.config.ts"] } diff --git a/packages/relay-kit/.env.sample b/packages/relay-kit/.env.example similarity index 100% rename from packages/relay-kit/.env.sample rename to packages/relay-kit/.env.example diff --git a/packages/relay-kit/LICENSE.md b/packages/relay-kit/LICENSE.md index b6358a76f..0d2a4f29d 100644 --- a/packages/relay-kit/LICENSE.md +++ b/packages/relay-kit/LICENSE.md @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2023 Safe Ecosystem Foundation +Copyright (c) 2023-2024 Safe Ecosystem Foundation 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/packages/relay-kit/README.md b/packages/relay-kit/README.md index fc20ee327..b3d529c1c 100644 --- a/packages/relay-kit/README.md +++ b/packages/relay-kit/README.md @@ -4,11 +4,26 @@ [![GitHub Release](https://img.shields.io/github/release/safe-global/safe-core-sdk.svg?style=flat)](https://github.com/safe-global/safe-core-sdk/releases) [![GitHub](https://img.shields.io/github/license/safe-global/safe-core-sdk)](https://github.com/safe-global/safe-core-sdk/blob/main/LICENSE.md) -The Relay Kit allows to abstract users from the transaction fees payment (gas fees) allowing the use of native token or ERC-20 tokens. This will enable you to pay transaction fees directly from funding available in a Safe. +The Relay Kit lets users pay transaction fees (gas fees) using the native blockchain token or ERC-20 tokens. Gas fees can be payed with this kit using any ERC-20 token in your Safe, even if there is no native token balance. This kit enables the use of ERC-4337 with Safe. -## Reference +## Table of contents -- [Relay Kit docs](https://docs.safe.global/safe-core-aa-sdk/relay-kit) +- [Documentation](#documentation) +- [Need Help or Have Questions?](#need-help-or-have-questions) +- [Contributing](#contributing) +- [License](#license) + +## Documentation + +Head to the [Relay Kit docs](https://docs.safe.global/sdk/relay-kit) to learn more about how to use this SDK. + +## Need Help or Have Questions? + +If you have any doubts, questions, or need assistance, feel free to reach out! [Here you will find how to get support.](https://github.com/safe-global/safe-core-sdk/tree/main/SUPPORT.md) + +## Contributing + +Please read our [contribution guidelines](https://github.com/safe-global/safe-core-sdk/tree/main/CONTRIBUTING.md) before submitting any changes. We appreciate your help! 🙌 ## License diff --git a/packages/relay-kit/jest.config.js b/packages/relay-kit/jest.config.js index dae675804..be3545182 100644 --- a/packages/relay-kit/jest.config.js +++ b/packages/relay-kit/jest.config.js @@ -5,7 +5,6 @@ const config = { '^.+\\.ts?$': 'ts-jest' }, moduleNameMapper: { - '^@safe-global/protocol-kit/typechain/(.*)$': '/../protocol-kit/typechain/$1', '^@safe-global/protocol-kit/(.*)$': '/../protocol-kit/src/$1', '^@safe-global/relay-kit/(.*)$': '/src/$1' }, diff --git a/packages/relay-kit/package.json b/packages/relay-kit/package.json index 6981edba0..6a1cb677e 100644 --- a/packages/relay-kit/package.json +++ b/packages/relay-kit/package.json @@ -1,6 +1,6 @@ { "name": "@safe-global/relay-kit", - "version": "2.1.1", + "version": "3.0.0-alpha.0", "description": "Safe Relay Kit", "main": "dist/src/index.js", "typings": "dist/src/index.d.ts", @@ -9,7 +9,8 @@ "Ethereum", "Account Abstraction", "SDK", - "Relay" + "Relay", + "4337" ], "scripts": { "test": "jest src --coverage", @@ -36,9 +37,9 @@ }, "dependencies": { "@gelatonetwork/relay-sdk": "^5.5.0", - "@safe-global/protocol-kit": "^3.1.1", - "@safe-global/safe-core-sdk-types": "^4.1.1", + "@safe-global/protocol-kit": "^4.0.0-alpha.0", + "@safe-global/safe-core-sdk-types": "^5.0.0-alpha.0", "@safe-global/safe-modules-deployments": "^2.0.0", - "ethers": "^6.7.1" + "ethers": "^6.12.1" } } diff --git a/packages/relay-kit/src/packs/gelato/GelatoRelayPack.test.ts b/packages/relay-kit/src/packs/gelato/GelatoRelayPack.test.ts index 14936baaf..fa842ba2a 100644 --- a/packages/relay-kit/src/packs/gelato/GelatoRelayPack.test.ts +++ b/packages/relay-kit/src/packs/gelato/GelatoRelayPack.test.ts @@ -7,6 +7,7 @@ import Safe, { createERC20TokenTransferTransaction } from '@safe-global/protocol-kit' import { MetaTransactionData, OperationType } from '@safe-global/safe-core-sdk-types' +import { SafeTransaction } from '@safe-global/safe-core-sdk-types' import { GELATO_FEE_COLLECTOR, @@ -14,7 +15,6 @@ import { ZERO_ADDRESS } from '@safe-global/relay-kit/constants' import { GelatoRelayPack } from './GelatoRelayPack' -import { SafeTransaction } from 'packages/safe-core-sdk-types/dist/src' enum TaskState { CheckPending = 'CheckPending' diff --git a/packages/relay-kit/src/packs/safe-4337/Safe4337Pack.test.ts b/packages/relay-kit/src/packs/safe-4337/Safe4337Pack.test.ts index cc84ca34f..808da64d7 100644 --- a/packages/relay-kit/src/packs/safe-4337/Safe4337Pack.test.ts +++ b/packages/relay-kit/src/packs/safe-4337/Safe4337Pack.test.ts @@ -182,7 +182,7 @@ describe('Safe4337Pack', () => { it('should encode the enableModules transaction as deployment data', async () => { const encodeFunctionDataSpy = jest.spyOn(constants.INTERFACES, 'encodeFunctionData') - const safeCreateSpy = jest.spyOn(Safe, 'create') + const safeCreateSpy = jest.spyOn(Safe, 'init') const safe4337Pack = await createSafe4337Pack({ options: { @@ -193,7 +193,8 @@ describe('Safe4337Pack', () => { expect(encodeFunctionDataSpy).toHaveBeenCalledWith('enableModules', [[safe4337ModuleAddress]]) expect(safeCreateSpy).toHaveBeenCalledWith({ - ethAdapter: safe4337Pack.protocolKit.getEthAdapter(), + provider: safe4337Pack.protocolKit.getSafeProvider().provider, + signer: safe4337Pack.protocolKit.getSafeProvider().signer, predictedSafe: { safeDeploymentConfig: { safeVersion: constants.DEFAULT_SAFE_VERSION, @@ -217,7 +218,7 @@ describe('Safe4337Pack', () => { it('should encode the enablesModule transaction together with a specific token approval in a multiSend call when trying to use a paymaster', async () => { const encodeFunctionDataSpy = jest.spyOn(constants.INTERFACES, 'encodeFunctionData') - const safeCreateSpy = jest.spyOn(Safe, 'create') + const safeCreateSpy = jest.spyOn(Safe, 'init') const safe4337Pack = await createSafe4337Pack({ options: { @@ -259,7 +260,8 @@ describe('Safe4337Pack', () => { expect(encodeFunctionDataSpy).toHaveBeenNthCalledWith(4, 'multiSend', [multiSendData]) expect(safeCreateSpy).toHaveBeenCalledWith({ - ethAdapter: safe4337Pack.protocolKit.getEthAdapter(), + provider: safe4337Pack.protocolKit.getSafeProvider().provider, + signer: safe4337Pack.protocolKit.getSafeProvider().signer, predictedSafe: { safeDeploymentConfig: { safeVersion: constants.DEFAULT_SAFE_VERSION, diff --git a/packages/relay-kit/src/packs/safe-4337/Safe4337Pack.ts b/packages/relay-kit/src/packs/safe-4337/Safe4337Pack.ts index 9453aedbd..5afab37e7 100644 --- a/packages/relay-kit/src/packs/safe-4337/Safe4337Pack.ts +++ b/packages/relay-kit/src/packs/safe-4337/Safe4337Pack.ts @@ -2,7 +2,7 @@ import { ethers } from 'ethers' import semverSatisfies from 'semver/functions/satisfies' import Safe, { EthSafeSignature, - EthersAdapter, + SafeProvider, SigningMethod, encodeMultiSendData, getMultiSendContract @@ -105,7 +105,7 @@ export class Safe4337Pack extends RelayKitBasePack<{ * @return {Promise} The Promise object that will be resolved into an instance of Safe4337Pack. */ static async init(initOptions: Safe4337InitOptions): Promise { - const { ethersAdapter, options, bundlerUrl, rpcUrl, customContracts, paymasterOptions } = + const { provider, signer, options, bundlerUrl, rpcUrl, customContracts, paymasterOptions } = initOptions let protocolKit: Safe const bundlerClient = getEip4337BundlerProvider(bundlerUrl) @@ -142,8 +142,9 @@ export class Safe4337Pack extends RelayKitBasePack<{ // Existing Safe if ('safeAddress' in options) { - protocolKit = await Safe.create({ - ethAdapter: ethersAdapter, + protocolKit = await Safe.init({ + provider, + signer, safeAddress: options.safeAddress }) @@ -211,7 +212,7 @@ export class Safe4337Pack extends RelayKitBasePack<{ ]) const multiSendContract = await getMultiSendContract({ - ethAdapter: ethersAdapter, + safeProvider: new SafeProvider({ provider, signer }), safeVersion: options.safeVersion || DEFAULT_SAFE_VERSION }) @@ -219,8 +220,9 @@ export class Safe4337Pack extends RelayKitBasePack<{ deploymentData = batchData } - protocolKit = await Safe.create({ - ethAdapter: ethersAdapter, + protocolKit = await Safe.init({ + provider, + signer, predictedSafe: { safeDeploymentConfig: { safeVersion: options.safeVersion || DEFAULT_SAFE_VERSION, @@ -422,9 +424,9 @@ export class Safe4337Pack extends RelayKitBasePack<{ signingMethod: SigningMethod = SigningMethod.ETH_SIGN_TYPED_DATA_V4 ): Promise { const owners = await this.protocolKit.getOwners() - const signerAddress = await this.protocolKit.getEthAdapter().getSignerAddress() + const signerAddress = await this.protocolKit.getSafeProvider().getSignerAddress() if (!signerAddress) { - throw new Error('EthAdapter must be initialized with a signer to use this method') + throw new Error('There is no signer address available to sign the SafeOperation') } const addressIsOwner = owners.some( @@ -444,7 +446,7 @@ export class Safe4337Pack extends RelayKitBasePack<{ ) { signature = await this.#signTypedData(safeOperation.data) } else { - const chainId = await this.protocolKit.getEthAdapter().getChainId() + const chainId = await this.protocolKit.getSafeProvider().getChainId() const safeOpHash = this.#getSafeUserOperationHash(safeOperation.data, chainId) signature = await this.protocolKit.signHash(safeOpHash) @@ -568,17 +570,14 @@ export class Safe4337Pack extends RelayKitBasePack<{ /** * Signs typed data. - * This is currently only EthersAdapter compatible (Reflected in the init() props). If I want to make it compatible with any EthAdapter I need to either: - * - Add a SafeOp type to the protocol-kit (createSafeOperation, signSafeOperation, etc) - * - Allow to pass the data types (SafeOp, SafeMessage, SafeTx) to the signTypedData method and refactor the protocol-kit to allow any kind of data signing from outside (Currently only SafeTx and SafeMessage) * * @param {SafeUserOperation} safeUserOperation - Safe user operation to sign. * @return {Promise} The SafeSignature object containing the data and the signatures. */ async #signTypedData(safeUserOperation: SafeUserOperation): Promise { - const ethAdapter = this.protocolKit.getEthAdapter() as EthersAdapter - const signer = ethAdapter.getSigner() as ethers.Signer - const chainId = await ethAdapter.getChainId() + const safeProvider = this.protocolKit.getSafeProvider() + const signer = (await safeProvider.getExternalSigner()) as ethers.Signer + const chainId = await safeProvider.getChainId() const signerAddress = await signer.getAddress() const signature = await signer.signTypedData( { diff --git a/packages/relay-kit/src/packs/safe-4337/testing-utils/fixtures.ts b/packages/relay-kit/src/packs/safe-4337/testing-utils/fixtures.ts index ea321ebba..cb77da712 100644 --- a/packages/relay-kit/src/packs/safe-4337/testing-utils/fixtures.ts +++ b/packages/relay-kit/src/packs/safe-4337/testing-utils/fixtures.ts @@ -9,7 +9,7 @@ export const PAYMASTER_ADDRESS = '0x0000000000325602a77416A16136FDafd04b299f' export const PAYMASTER_TOKEN_ADDRESS = '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238' export const CHAIN_ID = '0xaa36a7' -export const RPC_URL = 'https://rpc.ankr.com/eth_sepolia' +export const RPC_URL = 'https://sepolia.gateway.tenderly.co' export const BUNDLER_URL = 'https://bundler.url' export const PAYMASTER_URL = 'https://paymaster.url' diff --git a/packages/relay-kit/src/packs/safe-4337/testing-utils/helpers.ts b/packages/relay-kit/src/packs/safe-4337/testing-utils/helpers.ts index 69a7f67a7..0e347508e 100644 --- a/packages/relay-kit/src/packs/safe-4337/testing-utils/helpers.ts +++ b/packages/relay-kit/src/packs/safe-4337/testing-utils/helpers.ts @@ -1,5 +1,4 @@ import { ethers } from 'ethers' -import * as protocolKit from '@safe-global/protocol-kit' import { Safe4337InitOptions } from '../types' import { Safe4337Pack } from '../Safe4337Pack' import * as fixtures from './fixtures' @@ -14,19 +13,13 @@ export const generateTransferCallData = (to: string, value: bigint) => { export const createSafe4337Pack = async ( initOptions: Partial ): Promise => { - const provider = new ethers.JsonRpcProvider(fixtures.RPC_URL) - const signer = new ethers.Wallet(process.env.PRIVATE_KEY || '0x', provider) - const ethersAdapter = new protocolKit.EthersAdapter({ - ethers, - signerOrProvider: signer - }) - const safe4337Pack = await Safe4337Pack.init({ + provider: fixtures.RPC_URL, + signer: process.env.PRIVATE_KEY, options: { safeAddress: '' }, ...initOptions, - ethersAdapter, rpcUrl: fixtures.RPC_URL, bundlerUrl: fixtures.BUNDLER_URL }) diff --git a/packages/relay-kit/src/packs/safe-4337/types.ts b/packages/relay-kit/src/packs/safe-4337/types.ts index ddb701b37..95458c849 100644 --- a/packages/relay-kit/src/packs/safe-4337/types.ts +++ b/packages/relay-kit/src/packs/safe-4337/types.ts @@ -1,4 +1,4 @@ -import Safe, { EthersAdapter } from '@safe-global/protocol-kit' +import Safe, { SafeProviderConfig } from '@safe-global/protocol-kit' import { MetaTransactionData, SafeVersion } from '@safe-global/safe-core-sdk-types' import { ethers } from 'ethers' import SafeOperation from './SafeOperation' @@ -24,7 +24,8 @@ export type PaymasterOptions = { } export type Safe4337InitOptions = { - ethersAdapter: EthersAdapter + provider: SafeProviderConfig['provider'] + signer?: SafeProviderConfig['signer'] bundlerUrl: string rpcUrl: string safeModulesVersion?: string diff --git a/packages/safe-core-sdk-types/LICENSE.md b/packages/safe-core-sdk-types/LICENSE.md index 310e6e37c..0e923d187 100644 --- a/packages/safe-core-sdk-types/LICENSE.md +++ b/packages/safe-core-sdk-types/LICENSE.md @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021-2023 Safe Ecosystem Foundation +Copyright (c) 2021-2024 Safe Ecosystem Foundation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/packages/safe-core-sdk-types/README.md b/packages/safe-core-sdk-types/README.md index 2cdb851da..1753518ad 100644 --- a/packages/safe-core-sdk-types/README.md +++ b/packages/safe-core-sdk-types/README.md @@ -1,3 +1,19 @@ # Safe Core SDK Types +[![NPM Version](https://badge.fury.io/js/@safe-global%2Fsafe-core-sdk-types.svg)](https://badge.fury.io/js/@safe-global%2Fsafe-core-sdk-types) +[![GitHub Release](https://img.shields.io/github/release/safe-global/safe-core-sdk.svg?style=flat)](https://github.com/safe-global/safe-core-sdk/releases) +[![GitHub](https://img.shields.io/github/license/safe-global/safe-core-sdk)](https://github.com/safe-global/safe-core-sdk/blob/main/LICENSE.md) + Common types in the [Safe Core SDK](https://github.com/safe-global/safe-core-sdk) + +## Need Help or Have Questions? + +If you have any doubts, questions, or need assistance, feel free to reach out! [Here you will find how to get support.](https://github.com/safe-global/safe-core-sdk/tree/main/SUPPORT.md) + +## Contributing + +Please read our [contribution guidelines](https://github.com/safe-global/safe-core-sdk/tree/main/CONTRIBUTING.md) before submitting any changes. We appreciate your help! 🙌 + +## License + +This library is [released under MIT](https://github.com/safe-global/safe-core-sdk/blob/main/LICENSE.md). diff --git a/packages/safe-core-sdk-types/package.json b/packages/safe-core-sdk-types/package.json index 1feffec35..84a4a69e5 100644 --- a/packages/safe-core-sdk-types/package.json +++ b/packages/safe-core-sdk-types/package.json @@ -1,6 +1,6 @@ { "name": "@safe-global/safe-core-sdk-types", - "version": "4.1.1", + "version": "5.0.0-alpha.0", "description": "Safe Core SDK types", "main": "dist/src/index.js", "types": "dist/src/index.d.ts", @@ -29,9 +29,6 @@ ], "homepage": "https://github.com/safe-global/safe-core-sdk#readme", "dependencies": { - "@safe-global/safe-deployments": "^1.36.0", - "ethers": "^6.7.1", - "web3-core": "^1.10.3", - "web3-utils": "^1.10.3" + "abitype": "^1.0.2" } } diff --git a/packages/safe-core-sdk-types/src/contracts/CompatibilityFallbackHandler/CompatibilityFallbackHandlerBaseContract.ts b/packages/safe-core-sdk-types/src/contracts/CompatibilityFallbackHandler/CompatibilityFallbackHandlerBaseContract.ts new file mode 100644 index 000000000..0424bfac8 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/CompatibilityFallbackHandler/CompatibilityFallbackHandlerBaseContract.ts @@ -0,0 +1,13 @@ +import { Abi } from 'abitype' +import BaseContract from '../common/BaseContract' + +/** + * Represents the base contract type for a CompatibilityFallbackHandler contract. + * + * @template CompatibilityFallbackHandlerContractAbi - The ABI of the CompatibilityFallbackHandler contract. + * @type {CompatibilityFallbackHandlerBaseContract} + */ +type CompatibilityFallbackHandlerBaseContract = + BaseContract + +export default CompatibilityFallbackHandlerBaseContract diff --git a/packages/safe-core-sdk-types/src/contracts/CompatibilityFallbackHandler/index.ts b/packages/safe-core-sdk-types/src/contracts/CompatibilityFallbackHandler/index.ts new file mode 100644 index 000000000..96a8b3d8f --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/CompatibilityFallbackHandler/index.ts @@ -0,0 +1,9 @@ +import { CompatibilityFallbackHandlerContract_v1_3_0_Contract } from './v1.3.0/CompatibilityFallbackHandlerContract_v1_3_0' +import { CompatibilityFallbackHandlerContract_v1_4_1_Contract } from './v1.4.1/CompatibilityFallbackHandlerContract_v1_4_1' + +export * from './v1.3.0/CompatibilityFallbackHandlerContract_v1_3_0' +export * from './v1.4.1/CompatibilityFallbackHandlerContract_v1_4_1' + +export type CompatibilityFallbackHandlerContractType = + | CompatibilityFallbackHandlerContract_v1_3_0_Contract + | CompatibilityFallbackHandlerContract_v1_4_1_Contract diff --git a/packages/safe-core-sdk-types/src/contracts/CompatibilityFallbackHandler/v1.3.0/CompatibilityFallbackHandlerContract_v1_3_0.ts b/packages/safe-core-sdk-types/src/contracts/CompatibilityFallbackHandler/v1.3.0/CompatibilityFallbackHandlerContract_v1_3_0.ts new file mode 100644 index 000000000..5f4d5c5c6 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/CompatibilityFallbackHandler/v1.3.0/CompatibilityFallbackHandlerContract_v1_3_0.ts @@ -0,0 +1,24 @@ +import { narrow } from 'abitype' +import compatibilityFallbackHandler_1_3_0_ContractArtifacts from '../../assets/CompatibilityFallbackHandler/v1.3.0/compatibility_fallback_handler' +import CompatibilityFallbackHandlerBaseContract from '../CompatibilityFallbackHandlerBaseContract' + +const compatibilityFallbackHandlerContract_v1_3_0_AbiTypes = narrow( + compatibilityFallbackHandler_1_3_0_ContractArtifacts.abi +) + +/** + * Represents the ABI of the CompatibilityFallbackHandler contract version 1.3.0. + * + * @type {CompatibilityFallbackHandlerContract_v1_3_0_Abi} + */ +export type CompatibilityFallbackHandlerContract_v1_3_0_Abi = + typeof compatibilityFallbackHandlerContract_v1_3_0_AbiTypes + +/** + * Represents the contract type for a CompatibilityFallbackHandler contract version 1.3.0 defining read and write methods. + * Utilizes the generic CompatibilityFallbackHandlerBaseContract with the ABI specific to version 1.3.0. + * + * @type {CompatibilityFallbackHandlerContract_v1_3_0_Contract} + */ +export type CompatibilityFallbackHandlerContract_v1_3_0_Contract = + CompatibilityFallbackHandlerBaseContract diff --git a/packages/safe-core-sdk-types/src/contracts/CompatibilityFallbackHandler/v1.4.1/CompatibilityFallbackHandlerContract_v1_4_1.ts b/packages/safe-core-sdk-types/src/contracts/CompatibilityFallbackHandler/v1.4.1/CompatibilityFallbackHandlerContract_v1_4_1.ts new file mode 100644 index 000000000..5f64b9651 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/CompatibilityFallbackHandler/v1.4.1/CompatibilityFallbackHandlerContract_v1_4_1.ts @@ -0,0 +1,24 @@ +import { narrow } from 'abitype' +import compatibilityFallbackHandler_1_4_1_ContractArtifacts from '../../assets/CompatibilityFallbackHandler/v1.4.1/compatibility_fallback_handler' +import CompatibilityFallbackHandlerBaseContract from '../CompatibilityFallbackHandlerBaseContract' + +const compatibilityFallbackHandlerContract_v1_4_1_AbiTypes = narrow( + compatibilityFallbackHandler_1_4_1_ContractArtifacts.abi +) + +/** + * Represents the ABI of the CompatibilityFallbackHandler contract version 1.4.1. + * + * @type {CompatibilityFallbackHandlerContract_v1_4_1_Abi} + */ +export type CompatibilityFallbackHandlerContract_v1_4_1_Abi = + typeof compatibilityFallbackHandlerContract_v1_4_1_AbiTypes + +/** + * Represents the contract type for a CompatibilityFallbackHandler contract version 1.4.1 defining read and write methods. + * Utilizes the generic CompatibilityFallbackHandlerBaseContract with the ABI specific to version 1.4.1. + * + * @type {CompatibilityFallbackHandlerContract_v1_4_1_Contract} + */ +export type CompatibilityFallbackHandlerContract_v1_4_1_Contract = + CompatibilityFallbackHandlerBaseContract diff --git a/packages/safe-core-sdk-types/src/contracts/CompatibilityFallbackHandlerContract.ts b/packages/safe-core-sdk-types/src/contracts/CompatibilityFallbackHandlerContract.ts deleted file mode 100644 index a5eb871fd..000000000 --- a/packages/safe-core-sdk-types/src/contracts/CompatibilityFallbackHandlerContract.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface CompatibilityFallbackHandlerContract { - getAddress(): Promise - encode(methodName: any, params: any): string -} diff --git a/packages/safe-core-sdk-types/src/contracts/CreateCall/CreateCallBaseContract.ts b/packages/safe-core-sdk-types/src/contracts/CreateCall/CreateCallBaseContract.ts new file mode 100644 index 000000000..c88aad08e --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/CreateCall/CreateCallBaseContract.ts @@ -0,0 +1,23 @@ +import { Abi } from 'abitype' +import BaseContract, { + SafeContractFunction, + ContractReadFunctionNames, + EstimateGasFunction +} from '../common/BaseContract' + +/** + * Represents the base contract type for a CreateCall contract. + * + * @template CreateCallContractAbi - The ABI of the CreateCall contract. + * @type {CreateCallBaseContract} + */ +export type CreateCallBaseContract = BaseContract< + CreateCallContractAbi, + ContractReadFunctionNames +> & { + estimateGas: EstimateGasFunction + performCreate: SafeContractFunction + performCreate2: SafeContractFunction +} + +export default CreateCallBaseContract diff --git a/packages/safe-core-sdk-types/src/contracts/CreateCall/index.ts b/packages/safe-core-sdk-types/src/contracts/CreateCall/index.ts new file mode 100644 index 000000000..9f3e29f8b --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/CreateCall/index.ts @@ -0,0 +1,9 @@ +import { CreateCallContract_v1_3_0_Contract } from './v1.3.0/CreateCallContract_v1_3_0' +import { CreateCallContract_v1_4_1_Contract } from './v1.4.1/CreateCallContract_v1_4_1' + +export * from './v1.3.0/CreateCallContract_v1_3_0' +export * from './v1.4.1/CreateCallContract_v1_4_1' + +export type CreateCallContractType = + | CreateCallContract_v1_3_0_Contract + | CreateCallContract_v1_4_1_Contract diff --git a/packages/safe-core-sdk-types/src/contracts/CreateCall/v1.3.0/CreateCallContract_v1_3_0.ts b/packages/safe-core-sdk-types/src/contracts/CreateCall/v1.3.0/CreateCallContract_v1_3_0.ts new file mode 100644 index 000000000..3351d4f85 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/CreateCall/v1.3.0/CreateCallContract_v1_3_0.ts @@ -0,0 +1,20 @@ +import { narrow } from 'abitype' +import createCall_1_3_0_ContractArtifacts from '../../assets/CreateCall/v1.3.0/create_call' +import CreateCallBaseContract from '../CreateCallBaseContract' + +const createCallContract_v1_3_0_AbiTypes = narrow(createCall_1_3_0_ContractArtifacts.abi) + +/** + * Represents the ABI of the CreateCall contract version 1.3.0. + * + * @type {CreateCallContract_v1_3_0_Abi} + */ +export type CreateCallContract_v1_3_0_Abi = typeof createCallContract_v1_3_0_AbiTypes + +/** + * Represents the contract type for a CreateCall contract version 1.3.0 defining read and write methods. + * Utilizes the generic CreateCallBaseContract with the ABI specific to version 1.3.0. + * @type {CreateCallContract_v1_3_0_Contract} + */ +export type CreateCallContract_v1_3_0_Contract = + CreateCallBaseContract diff --git a/packages/safe-core-sdk-types/src/contracts/CreateCall/v1.4.1/CreateCallContract_v1_4_1.ts b/packages/safe-core-sdk-types/src/contracts/CreateCall/v1.4.1/CreateCallContract_v1_4_1.ts new file mode 100644 index 000000000..aeb26a160 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/CreateCall/v1.4.1/CreateCallContract_v1_4_1.ts @@ -0,0 +1,21 @@ +import { narrow } from 'abitype' +import createCall_1_4_1_ContractArtifacts from '../../assets/CreateCall/v1.4.1/create_call' +import CreateCallBaseContract from '../CreateCallBaseContract' + +const createCallContract_v1_4_1_AbiTypes = narrow(createCall_1_4_1_ContractArtifacts.abi) + +/** + * Represents the ABI of the CreateCall contract version 1.4.1. + * + * @type {CreateCallContract_v1_4_1_Abi} + */ +export type CreateCallContract_v1_4_1_Abi = typeof createCallContract_v1_4_1_AbiTypes + +/** + * Represents the contract type for a CreateCall contract version 1.4.1 defining read and write methods. + * Utilizes the generic CreateCallBaseContract with the ABI specific to version 1.4.1. + * + * @type {CreateCallContract_v1_4_1_Contract} + */ +export type CreateCallContract_v1_4_1_Contract = + CreateCallBaseContract diff --git a/packages/safe-core-sdk-types/src/contracts/CreateCallContract.ts b/packages/safe-core-sdk-types/src/contracts/CreateCallContract.ts deleted file mode 100644 index 9cd07612e..000000000 --- a/packages/safe-core-sdk-types/src/contracts/CreateCallContract.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { TransactionOptions, TransactionResult } from '@safe-global/safe-core-sdk-types/types' - -export interface CreateCallContract { - getAddress(): Promise - performCreate2( - value: string, - deploymentData: string, - salt: string, - options?: TransactionOptions - ): Promise - performCreate( - value: string, - deploymentData: string, - options?: TransactionOptions - ): Promise - encode(methodName: any, params: any): string - estimateGas(methodName: string, params: any[], options: TransactionOptions): Promise -} diff --git a/packages/safe-core-sdk-types/src/contracts/MultiSend/MultiSendBaseContract.ts b/packages/safe-core-sdk-types/src/contracts/MultiSend/MultiSendBaseContract.ts new file mode 100644 index 000000000..a29d42e29 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/MultiSend/MultiSendBaseContract.ts @@ -0,0 +1,15 @@ +import { Abi } from 'abitype' +import BaseContract from '../common/BaseContract' + +/** + * Represents the base contract type for a MultiSend contract. + * + * @template MultiSendContractAbi - The ABI of the MultiSend contract. + * @type {MultiSendBaseContract} + */ +type MultiSendBaseContract = BaseContract< + MultiSendContractAbi, + never +> + +export default MultiSendBaseContract diff --git a/packages/safe-core-sdk-types/src/contracts/MultiSend/MultiSendCallOnlyBaseContract.ts b/packages/safe-core-sdk-types/src/contracts/MultiSend/MultiSendCallOnlyBaseContract.ts new file mode 100644 index 000000000..35c9b544e --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/MultiSend/MultiSendCallOnlyBaseContract.ts @@ -0,0 +1,15 @@ +import { Abi } from 'abitype' +import BaseContract from '../common/BaseContract' + +/** + * Represents the base contract type for a MultiSendCallOnly contract. + * + * @template MultiSendCallOnlyContractAbi - The ABI of the MultiSendCallOnly contract. + * @type {MultiSendCallOnlyBaseContract} + */ +type MultiSendCallOnlyBaseContract = BaseContract< + MultiSendCallOnlyContractAbi, + never +> + +export default MultiSendCallOnlyBaseContract diff --git a/packages/safe-core-sdk-types/src/contracts/MultiSend/index.ts b/packages/safe-core-sdk-types/src/contracts/MultiSend/index.ts new file mode 100644 index 000000000..84ac0e125 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/MultiSend/index.ts @@ -0,0 +1,21 @@ +import { MultiSendContract_v1_1_1_Contract } from './v1.1.1/MultiSendContract_v1_1_1' +import { MultiSendCallOnlyContract_v1_3_0_Contract } from './v1.3.0/MultiSendCallOnlyContract_v1_3_0' +import { MultiSendContract_v1_3_0_Contract } from './v1.3.0/MultiSendContract_v1_3_0' +import { MultiSendCallOnlyContract_v1_4_1_Contract } from './v1.4.1/MultiSendCallOnlyContract_v1_4_1' +import { MultiSendContract_v1_4_1_Contract } from './v1.4.1/MultiSendContract_v1_4_1' + +export * from './v1.1.1/MultiSendContract_v1_1_1' +export * from './v1.3.0/MultiSendContract_v1_3_0' +export * from './v1.4.1/MultiSendContract_v1_4_1' + +export * from './v1.3.0/MultiSendCallOnlyContract_v1_3_0' +export * from './v1.4.1/MultiSendCallOnlyContract_v1_4_1' + +export type MultiSendContractType = + | MultiSendContract_v1_1_1_Contract + | MultiSendContract_v1_3_0_Contract + | MultiSendContract_v1_4_1_Contract + +export type MultiSendCallOnlyContractType = + | MultiSendCallOnlyContract_v1_3_0_Contract + | MultiSendCallOnlyContract_v1_4_1_Contract diff --git a/packages/safe-core-sdk-types/src/contracts/MultiSend/v1.1.1/MultiSendContract_v1_1_1.ts b/packages/safe-core-sdk-types/src/contracts/MultiSend/v1.1.1/MultiSendContract_v1_1_1.ts new file mode 100644 index 000000000..8c56cdda7 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/MultiSend/v1.1.1/MultiSendContract_v1_1_1.ts @@ -0,0 +1,20 @@ +import { narrow } from 'abitype' +import multiSend_1_1_1_ContractArtifacts from '../../assets/MultiSend/v1.1.1/multi_send' +import MultiSendBaseContract from '../MultiSendBaseContract' + +const multiSendContract_v1_1_1_AbiTypes = narrow(multiSend_1_1_1_ContractArtifacts.abi) + +/** + * Represents the ABI of the MultiSend contract version 1.1.1. + * + * @type {MultiSendContract_v1_1_1_Abi} + */ +export type MultiSendContract_v1_1_1_Abi = typeof multiSendContract_v1_1_1_AbiTypes + +/** + * Represents the contract type for a MultiSend contract version 1.1.1 defining read and write methods. + * Utilizes the generic MultiSendBaseContract with the ABI specific to version 1.1.1. + * + * @type {MultiSendContract_v1_1_1_Contract} + */ +export type MultiSendContract_v1_1_1_Contract = MultiSendBaseContract diff --git a/packages/safe-core-sdk-types/src/contracts/MultiSend/v1.3.0/MultiSendCallOnlyContract_v1_3_0.ts b/packages/safe-core-sdk-types/src/contracts/MultiSend/v1.3.0/MultiSendCallOnlyContract_v1_3_0.ts new file mode 100644 index 000000000..453885c29 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/MultiSend/v1.3.0/MultiSendCallOnlyContract_v1_3_0.ts @@ -0,0 +1,23 @@ +import { narrow } from 'abitype' +import multiSendCallOnly_1_3_0_ContractArtifacts from '../../assets/MultiSend/v1.3.0/multi_send_call_only' +import MultiSendCallOnlyBaseContract from '../MultiSendCallOnlyBaseContract' + +const multiSendCallOnlyContract_v1_3_0_AbiTypes = narrow( + multiSendCallOnly_1_3_0_ContractArtifacts.abi +) + +/** + * Represents the ABI of the MultiSendCallOnly contract version 1.3.0. + * + * @type {MultiSendCallOnlyContract_v1_3_0_Abi} + */ +export type MultiSendCallOnlyContract_v1_3_0_Abi = typeof multiSendCallOnlyContract_v1_3_0_AbiTypes + +/** + * Represents the contract type for a MultiSendCallOnly contract version 1.3.0 defining read and write methods. + * Utilizes the generic MultiSendBaseContract with the ABI specific to version 1.3.0. + * + * @type {MultiSendCallOnlyContract_v1_3_0_Contract} + */ +export type MultiSendCallOnlyContract_v1_3_0_Contract = + MultiSendCallOnlyBaseContract diff --git a/packages/safe-core-sdk-types/src/contracts/MultiSend/v1.3.0/MultiSendContract_v1_3_0.ts b/packages/safe-core-sdk-types/src/contracts/MultiSend/v1.3.0/MultiSendContract_v1_3_0.ts new file mode 100644 index 000000000..470ea93a8 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/MultiSend/v1.3.0/MultiSendContract_v1_3_0.ts @@ -0,0 +1,20 @@ +import { narrow } from 'abitype' +import multiSend_1_3_0_ContractArtifacts from '../../assets/MultiSend/v1.3.0/multi_send' +import MultiSendBaseContract from '../MultiSendBaseContract' + +const multiSendContract_v1_3_0_AbiTypes = narrow(multiSend_1_3_0_ContractArtifacts.abi) + +/** + * Represents the ABI of the MultiSend contract version 1.3.0. + * + * @type {MultiSendContract_v1_3_0_Abi} + */ +export type MultiSendContract_v1_3_0_Abi = typeof multiSendContract_v1_3_0_AbiTypes + +/** + * Represents the contract type for a MultiSend contract version 1.3.0 defining read and write methods. + * Utilizes the generic MultiSendBaseContract with the ABI specific to version 1.3.0. + * + * @type {MultiSendContract_v1_3_0_Contract} + */ +export type MultiSendContract_v1_3_0_Contract = MultiSendBaseContract diff --git a/packages/safe-core-sdk-types/src/contracts/MultiSend/v1.4.1/MultiSendCallOnlyContract_v1_4_1.ts b/packages/safe-core-sdk-types/src/contracts/MultiSend/v1.4.1/MultiSendCallOnlyContract_v1_4_1.ts new file mode 100644 index 000000000..ab8a377b2 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/MultiSend/v1.4.1/MultiSendCallOnlyContract_v1_4_1.ts @@ -0,0 +1,23 @@ +import { narrow } from 'abitype' +import multiSendCallOnly_1_4_1_ContractArtifacts from '../../assets/MultiSend/v1.4.1/multi_send_call_only' +import MultiSendCallOnlyBaseContract from '../MultiSendCallOnlyBaseContract' + +const multiSendCallOnlyContract_v1_4_1_AbiTypes = narrow( + multiSendCallOnly_1_4_1_ContractArtifacts.abi +) + +/** + * Represents the ABI of the MultiSendCallOnly contract version 1.4.1. + * + * @type {MultiSendCallOnlyContract_v1_4_1_Abi} + */ +export type MultiSendCallOnlyContract_v1_4_1_Abi = typeof multiSendCallOnlyContract_v1_4_1_AbiTypes + +/** + * Represents the contract type for a MultiSendCallOnly contract version 1.4.1 defining read and write methods. + * Utilizes the generic MultiSendBaseContract with the ABI specific to version 1.4.1. + * + * @type {MultiSendCallOnlyContract_v1_4_1_Contract} + */ +export type MultiSendCallOnlyContract_v1_4_1_Contract = + MultiSendCallOnlyBaseContract diff --git a/packages/safe-core-sdk-types/src/contracts/MultiSend/v1.4.1/MultiSendContract_v1_4_1.ts b/packages/safe-core-sdk-types/src/contracts/MultiSend/v1.4.1/MultiSendContract_v1_4_1.ts new file mode 100644 index 000000000..797842be2 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/MultiSend/v1.4.1/MultiSendContract_v1_4_1.ts @@ -0,0 +1,20 @@ +import { narrow } from 'abitype' +import multiSend_1_4_1_ContractArtifacts from '../../assets/MultiSend/v1.4.1/multi_send' +import MultiSendBaseContract from '../MultiSendBaseContract' + +const multiSendContract_v1_4_1_AbiTypes = narrow(multiSend_1_4_1_ContractArtifacts.abi) + +/** + * Represents the ABI of the MultiSend contract version 1.4.1. + * + * @type {MultiSendContract_v1_4_1_Abi} + */ +export type MultiSendContract_v1_4_1_Abi = typeof multiSendContract_v1_4_1_AbiTypes + +/** + * Represents the contract type for a MultiSend contract version 1.4.1 defining read and write methods. + * Utilizes the generic MultiSendBaseContract with the ABI specific to version 1.4.1. + * + * @type {MultiSendContract_v1_4_1_Contract} + */ +export type MultiSendContract_v1_4_1_Contract = MultiSendBaseContract diff --git a/packages/safe-core-sdk-types/src/contracts/MultiSendCallOnlyContract.ts b/packages/safe-core-sdk-types/src/contracts/MultiSendCallOnlyContract.ts deleted file mode 100644 index 160a662c7..000000000 --- a/packages/safe-core-sdk-types/src/contracts/MultiSendCallOnlyContract.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface MultiSendCallOnlyContract { - getAddress(): Promise - encode(methodName: any, params: any): string -} diff --git a/packages/safe-core-sdk-types/src/contracts/MultiSendContract.ts b/packages/safe-core-sdk-types/src/contracts/MultiSendContract.ts deleted file mode 100644 index 57ef0c8a9..000000000 --- a/packages/safe-core-sdk-types/src/contracts/MultiSendContract.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface MultiSendContract { - getAddress(): Promise - encode(methodName: any, params: any): string -} diff --git a/packages/safe-core-sdk-types/src/contracts/Safe/SafeBaseContract.ts b/packages/safe-core-sdk-types/src/contracts/Safe/SafeBaseContract.ts new file mode 100644 index 000000000..efa231530 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/Safe/SafeBaseContract.ts @@ -0,0 +1,20 @@ +import { Abi } from 'abitype' +import BaseContract, { + ContractReadFunctionNames, + EstimateGasFunction +} from '../common/BaseContract' + +/** + * Represents the base contract type for a Safe contract, defining read methods and utility functions like encode and estimateGas. + * + * @template SafeContractAbi - The ABI of the Safe contract. + * @type {SafeBaseContract} + */ +type SafeBaseContract = BaseContract< + SafeContractAbi, + ContractReadFunctionNames +> & { + estimateGas: EstimateGasFunction +} + +export default SafeBaseContract diff --git a/packages/safe-core-sdk-types/src/contracts/Safe/index.ts b/packages/safe-core-sdk-types/src/contracts/Safe/index.ts new file mode 100644 index 000000000..2c52c890c --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/Safe/index.ts @@ -0,0 +1,5 @@ +export * from './v1.0.0/SafeContract_v1_0_0' +export * from './v1.1.1/SafeContract_v1_1_1' +export * from './v1.2.0/SafeContract_v1_2_0' +export * from './v1.3.0/SafeContract_v1_3_0' +export * from './v1.4.1/SafeContract_v1_4_1' diff --git a/packages/safe-core-sdk-types/src/contracts/Safe/v1.0.0/SafeContract_v1_0_0.ts b/packages/safe-core-sdk-types/src/contracts/Safe/v1.0.0/SafeContract_v1_0_0.ts new file mode 100644 index 000000000..43b746844 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/Safe/v1.0.0/SafeContract_v1_0_0.ts @@ -0,0 +1,31 @@ +import { narrow, ExtractAbiFunctionNames } from 'abitype' +import safe_1_0_0_ContractArtifacts from '../../assets/Safe/v1.0.0/gnosis_safe' +import SafeBaseContract from '../SafeBaseContract' +import { ContractFunction } from '../../common/BaseContract' + +const safeContract_v1_0_0_AbiTypes = narrow(safe_1_0_0_ContractArtifacts.abi) + +/** + * Represents the ABI of the Safe contract version 1.0.0. + * + * @type {SafeContract_v1_0_0_Abi} + */ +export type SafeContract_v1_0_0_Abi = typeof safeContract_v1_0_0_AbiTypes + +/** + * Represents the function type derived by the given function name from the Safe contract version 1.0.0 ABI. + * + * @template ContractFunctionName - The function name, derived from the ABI. + * @type {SafeContract_v1_0_0_Function} + */ +export type SafeContract_v1_0_0_Function< + ContractFunctionName extends ExtractAbiFunctionNames +> = ContractFunction + +/** + * Represents the contract type for a Safe contract version 1.0.0, defining read and write methods. + * Utilizes the generic SafeBaseContract with the ABI specific to version 1.0.0. + * + * @type {SafeContract_v1_0_0_Contract} + */ +export type SafeContract_v1_0_0_Contract = SafeBaseContract diff --git a/packages/safe-core-sdk-types/src/contracts/Safe/v1.1.1/SafeContract_v1_1_1.ts b/packages/safe-core-sdk-types/src/contracts/Safe/v1.1.1/SafeContract_v1_1_1.ts new file mode 100644 index 000000000..20f6d82db --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/Safe/v1.1.1/SafeContract_v1_1_1.ts @@ -0,0 +1,31 @@ +import { ExtractAbiFunctionNames, narrow } from 'abitype' +import safe_1_1_1_ContractArtifacts from '../../assets/Safe/v1.1.1/gnosis_safe' +import SafeBaseContract from '../SafeBaseContract' +import { ContractFunction } from '../../common/BaseContract' + +const safeContract_v1_1_1_AbiTypes = narrow(safe_1_1_1_ContractArtifacts.abi) + +/** + * Represents the ABI of the Safe contract version 1.1.1. + * + * @type {SafeContract_v1_1_1_Abi} + */ +export type SafeContract_v1_1_1_Abi = typeof safeContract_v1_1_1_AbiTypes + +/** + * Represents the function type derived by the given function name from the Safe contract version 1.1.1 ABI. + * + * @template ContractFunctionName - The function name, derived from the ABI. + * @type {SafeContract_v1_1_1_Function} + */ +export type SafeContract_v1_1_1_Function< + ContractFunctionName extends ExtractAbiFunctionNames +> = ContractFunction + +/** + * Represents the contract type for a Safe contract version 1.1.1, defining read and write methods. + * Utilizes the generic SafeBaseContract with the ABI specific to version 1.1.1. + * + * @type {SafeContract_v1_1_1_Contract} + */ +export type SafeContract_v1_1_1_Contract = SafeBaseContract diff --git a/packages/safe-core-sdk-types/src/contracts/Safe/v1.2.0/SafeContract_v1_2_0.ts b/packages/safe-core-sdk-types/src/contracts/Safe/v1.2.0/SafeContract_v1_2_0.ts new file mode 100644 index 000000000..b83d80afd --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/Safe/v1.2.0/SafeContract_v1_2_0.ts @@ -0,0 +1,31 @@ +import { ExtractAbiFunctionNames, narrow } from 'abitype' +import safe_1_2_0_ContractArtifacts from '../../assets/Safe/v1.2.0/gnosis_safe' +import SafeBaseContract from '../SafeBaseContract' +import { ContractFunction } from '../../common/BaseContract' + +const safeContract_v1_2_0_AbiTypes = narrow(safe_1_2_0_ContractArtifacts.abi) + +/** + * Represents the ABI of the Safe contract version 1.2.0. + * + * @type {SafeContract_v1_2_0_Abi} + */ +export type SafeContract_v1_2_0_Abi = typeof safeContract_v1_2_0_AbiTypes + +/** + * Represents the function type derived by the given function name from the Safe contract version 1.2.0 ABI. + * + * @template ContractFunctionName - The function name, derived from the ABI. + * @type {SafeContract_v1_2_0_Function} + */ +export type SafeContract_v1_2_0_Function< + ContractFunctionName extends ExtractAbiFunctionNames +> = ContractFunction + +/** + * Represents the contract type for a Safe contract version 1.2.0, defining read and write methods. + * Utilizes the generic SafeBaseContract with the ABI specific to version 1.2.0. + * + * @type {SafeContract_v1_2_0_Contract} + */ +export type SafeContract_v1_2_0_Contract = SafeBaseContract diff --git a/packages/safe-core-sdk-types/src/contracts/Safe/v1.3.0/SafeContract_v1_3_0.ts b/packages/safe-core-sdk-types/src/contracts/Safe/v1.3.0/SafeContract_v1_3_0.ts new file mode 100644 index 000000000..eafa91b8b --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/Safe/v1.3.0/SafeContract_v1_3_0.ts @@ -0,0 +1,31 @@ +import { ExtractAbiFunctionNames, narrow } from 'abitype' +import safe_1_3_0_ContractArtifacts from '../../assets/Safe/v1.3.0/gnosis_safe_l2' +import SafeBaseContract from '../SafeBaseContract' +import { ContractFunction } from '../../common/BaseContract' + +const safeContract_v1_3_0_AbiTypes = narrow(safe_1_3_0_ContractArtifacts.abi) + +/** + * Represents the ABI of the Safe contract version 1.3.0. + * + * @type {SafeContract_v1_3_0_Abi} + */ +export type SafeContract_v1_3_0_Abi = typeof safeContract_v1_3_0_AbiTypes + +/** + * Represents the function type derived by the given function name from the Safe contract version 1.3.0 ABI. + * + * @template ContractFunctionName - The function name, derived from the ABI. + * @type {SafeContract_v1_3_0_Function} + */ +export type SafeContract_v1_3_0_Function< + ContractFunctionName extends ExtractAbiFunctionNames +> = ContractFunction + +/** + * Represents the contract type for a Safe contract version 1.3.0, defining read and write methods. + * Utilizes the generic SafeBaseContract with the ABI specific to version 1.3.0. + * + * @type {SafeContract_v1_3_0_Contract} + */ +export type SafeContract_v1_3_0_Contract = SafeBaseContract diff --git a/packages/safe-core-sdk-types/src/contracts/Safe/v1.4.1/SafeContract_v1_4_1.ts b/packages/safe-core-sdk-types/src/contracts/Safe/v1.4.1/SafeContract_v1_4_1.ts new file mode 100644 index 000000000..6386680eb --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/Safe/v1.4.1/SafeContract_v1_4_1.ts @@ -0,0 +1,31 @@ +import { ExtractAbiFunctionNames, narrow } from 'abitype' +import safe_1_4_1_ContractArtifacts from '../../assets/Safe/v1.4.1/safe_l2' +import SafeBaseContract from '../SafeBaseContract' +import { ContractFunction } from '../../common/BaseContract' + +const safeContract_v1_4_1_AbiTypes = narrow(safe_1_4_1_ContractArtifacts.abi) + +/** + * Represents the ABI of the Safe contract version 1.4.1. + * + * @type {SafeContract_v1_4_1_Abi} + */ +export type SafeContract_v1_4_1_Abi = typeof safeContract_v1_4_1_AbiTypes + +/** + * Represents the function type derived by the given function name from the Safe contract version 1.4.1 ABI. + * + * @template ContractFunctionName - The function name, derived from the ABI. + * @type {SafeContract_v1_4_1_Function} + */ +export type SafeContract_v1_4_1_Function< + ContractFunctionName extends ExtractAbiFunctionNames +> = ContractFunction + +/** + * Represents the contract type for a Safe contract version 1.4.1, defining read and write methods. + * Utilizes the generic SafeBaseContract with the ABI specific to version 1.4.1. + * + * @type {SafeContract_v1_4_1_Contract} + */ +export type SafeContract_v1_4_1_Contract = SafeBaseContract diff --git a/packages/safe-core-sdk-types/src/contracts/SafeContract.ts b/packages/safe-core-sdk-types/src/contracts/SafeContract.ts deleted file mode 100644 index b63338802..000000000 --- a/packages/safe-core-sdk-types/src/contracts/SafeContract.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { - SafeSetupConfig, - SafeTransaction, - SafeTransactionData, - SafeVersion, - TransactionOptions, - TransactionResult -} from '@safe-global/safe-core-sdk-types/types' - -export interface SafeContract { - setup(setupConfig: SafeSetupConfig, options?: TransactionOptions): Promise - getVersion(): Promise - getAddress(): Promise - getNonce(): Promise - getThreshold(): Promise - getOwners(): Promise - isOwner(address: string): Promise - getTransactionHash(safeTransactionData: SafeTransactionData): Promise - approvedHashes(ownerAddress: string, hash: string): Promise - approveHash(hash: string, options?: TransactionOptions): Promise - getModules(): Promise - getModulesPaginated(start: string, pageSize: number): Promise - isModuleEnabled(moduleAddress: string): Promise - isValidTransaction( - safeTransaction: SafeTransaction, - options?: TransactionOptions - ): Promise - execTransaction( - safeTransaction: SafeTransaction, - options?: TransactionOptions - ): Promise - encode(methodName: string, params: any): string - estimateGas(methodName: string, params: any[], options: TransactionOptions): Promise -} diff --git a/packages/safe-core-sdk-types/src/contracts/SafeProxyFactory/SafeProxyFactoryBaseContract.ts b/packages/safe-core-sdk-types/src/contracts/SafeProxyFactory/SafeProxyFactoryBaseContract.ts new file mode 100644 index 000000000..386f54cd2 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/SafeProxyFactory/SafeProxyFactoryBaseContract.ts @@ -0,0 +1,15 @@ +import { Abi } from 'abitype' +import BaseContract, { EstimateGasFunction } from '../common/BaseContract' + +/** + * Represents the base contract type for a Safe Proxy Factory contract. + * + * @template SafeProxyFactoryContractAbi - The ABI of the Safe Proxy factory contract. + * @type {SafeProxyFactoryBaseContract} + */ +export type SafeProxyFactoryBaseContract = + BaseContract & { + estimateGas: EstimateGasFunction + } + +export default SafeProxyFactoryBaseContract diff --git a/packages/safe-core-sdk-types/src/contracts/SafeProxyFactory/index.ts b/packages/safe-core-sdk-types/src/contracts/SafeProxyFactory/index.ts new file mode 100644 index 000000000..8d062c6af --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/SafeProxyFactory/index.ts @@ -0,0 +1,15 @@ +import { SafeProxyFactoryContract_v1_0_0_Contract } from './v1.0.0/SafeProxyFactoryContract_v1_0_0' +import { SafeProxyFactoryContract_v1_1_1_Contract } from './v1.1.1/SafeProxyFactoryContract_v1_1_1' +import { SafeProxyFactoryContract_v1_3_0_Contract } from './v1.3.0/SafeProxyFactoryContract_v1_3_0' +import { SafeProxyFactoryContract_v1_4_1_Contract } from './v1.4.1/SafeProxyFactoryContract_v1_4_1' + +export * from './v1.0.0/SafeProxyFactoryContract_v1_0_0' +export * from './v1.1.1/SafeProxyFactoryContract_v1_1_1' +export * from './v1.3.0/SafeProxyFactoryContract_v1_3_0' +export * from './v1.4.1/SafeProxyFactoryContract_v1_4_1' + +export type SafeProxyFactoryContractType = + | SafeProxyFactoryContract_v1_0_0_Contract + | SafeProxyFactoryContract_v1_1_1_Contract + | SafeProxyFactoryContract_v1_3_0_Contract + | SafeProxyFactoryContract_v1_4_1_Contract diff --git a/packages/safe-core-sdk-types/src/contracts/SafeProxyFactory/v1.0.0/SafeProxyFactoryContract_v1_0_0.ts b/packages/safe-core-sdk-types/src/contracts/SafeProxyFactory/v1.0.0/SafeProxyFactoryContract_v1_0_0.ts new file mode 100644 index 000000000..f16bae599 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/SafeProxyFactory/v1.0.0/SafeProxyFactoryContract_v1_0_0.ts @@ -0,0 +1,34 @@ +import { ExtractAbiFunctionNames, narrow } from 'abitype' +import safeProxyFactory_1_0_0_ContractArtifacts from '../../assets/SafeProxyFactory/v1.0.0/proxy_factory' +import SafeProxyFactoryBaseContract from '../SafeProxyFactoryBaseContract' +import { ContractFunction } from '../../common/BaseContract' + +const safeProxyFactoryContract_v1_0_0_AbiTypes = narrow( + safeProxyFactory_1_0_0_ContractArtifacts.abi +) + +/** + * Represents the ABI of the Safe Proxy Factory contract version 1.0.0. + * + * @type {SafeProxyFactoryContract_v1_0_0_Abi} + */ +export type SafeProxyFactoryContract_v1_0_0_Abi = typeof safeProxyFactoryContract_v1_0_0_AbiTypes + +/** + * Represents the function type derived by the given function name from the SafeProxyFactory contract version 1.0.0 ABI. + * + * @template ContractFunctionName - The function name, derived from the ABI. + * @type {SafeProxyFactoryContract_v1_0_0_Function} + */ +export type SafeProxyFactoryContract_v1_0_0_Function< + ContractFunctionName extends ExtractAbiFunctionNames +> = ContractFunction + +/** + * Represents the contract type for a Safe Proxy Factory contract version 1.0.0, defining read and write methods. + * Utilizes the generic SafeProxyFactoryBaseContract with the ABI specific to version 1.0.0. + * + * @type {SafeProxyFactoryContract_v1_0_0_Contract} + */ +export type SafeProxyFactoryContract_v1_0_0_Contract = + SafeProxyFactoryBaseContract diff --git a/packages/safe-core-sdk-types/src/contracts/SafeProxyFactory/v1.1.1/SafeProxyFactoryContract_v1_1_1.ts b/packages/safe-core-sdk-types/src/contracts/SafeProxyFactory/v1.1.1/SafeProxyFactoryContract_v1_1_1.ts new file mode 100644 index 000000000..8085d65d1 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/SafeProxyFactory/v1.1.1/SafeProxyFactoryContract_v1_1_1.ts @@ -0,0 +1,34 @@ +import { ExtractAbiFunctionNames, narrow } from 'abitype' +import safeProxyFactory_1_1_1_ContractArtifacts from '../../assets/SafeProxyFactory/v1.1.1/proxy_factory' +import SafeProxyFactoryBaseContract from '../SafeProxyFactoryBaseContract' +import { ContractFunction } from '../../common/BaseContract' + +const safeProxyFactoryContract_v1_1_1_AbiTypes = narrow( + safeProxyFactory_1_1_1_ContractArtifacts.abi +) + +/** + * Represents the ABI of the Safe Proxy Factory contract version 1.1.1. + * + * @type {SafeProxyFactoryContract_v1_1_1_Abi} + */ +export type SafeProxyFactoryContract_v1_1_1_Abi = typeof safeProxyFactoryContract_v1_1_1_AbiTypes + +/** + * Represents the function type derived by the given function name from the SafeProxyFactory contract version 1.1.1 ABI. + * + * @template ContractFunctionName - The function name, derived from the ABI. + * @type {SafeProxyFactoryContract_v1_1_1_Function} + */ +export type SafeProxyFactoryContract_v1_1_1_Function< + ContractFunctionName extends ExtractAbiFunctionNames +> = ContractFunction + +/** + * Represents the contract type for a Safe Proxy Factory contract version 1.1.1, defining read and write methods. + * Utilizes the generic SafeProxyFactoryBaseContract with the ABI specific to version 1.1.1. + * + * @type {SafeProxyFactoryContract_v1_1_1_Contract} + */ +export type SafeProxyFactoryContract_v1_1_1_Contract = + SafeProxyFactoryBaseContract diff --git a/packages/safe-core-sdk-types/src/contracts/SafeProxyFactory/v1.3.0/SafeProxyFactoryContract_v1_3_0.ts b/packages/safe-core-sdk-types/src/contracts/SafeProxyFactory/v1.3.0/SafeProxyFactoryContract_v1_3_0.ts new file mode 100644 index 000000000..f9cfb7619 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/SafeProxyFactory/v1.3.0/SafeProxyFactoryContract_v1_3_0.ts @@ -0,0 +1,34 @@ +import { ExtractAbiFunctionNames, narrow } from 'abitype' +import safeProxyFactory_1_3_0_ContractArtifacts from '../../assets/SafeProxyFactory/v1.3.0/proxy_factory' +import SafeProxyFactoryBaseContract from '../SafeProxyFactoryBaseContract' +import { ContractFunction } from '../../common/BaseContract' + +const safeProxyFactoryContract_v1_3_0_AbiTypes = narrow( + safeProxyFactory_1_3_0_ContractArtifacts.abi +) + +/** + * Represents the ABI of the Safe Proxy Factory contract version 1.3.0. + * + * @type {SafeProxyFactoryContract_v1_3_0_Abi} + */ +export type SafeProxyFactoryContract_v1_3_0_Abi = typeof safeProxyFactoryContract_v1_3_0_AbiTypes + +/** + * Represents the function type derived by the given function name from the SafeProxyFactory contract version 1.3.0 ABI. + * + * @template ContractFunctionName - The function name, derived from the ABI. + * @type {SafeProxyFactoryContract_v1_3_0_Function} + */ +export type SafeProxyFactoryContract_v1_3_0_Function< + ContractFunctionName extends ExtractAbiFunctionNames +> = ContractFunction + +/** + * Represents the contract type for a Safe Proxy Factory contract version 1.3.0, defining read and write methods. + * Utilizes the generic SafeProxyFactoryBaseContract with the ABI specific to version 1.3.0. + * + * @type {SafeProxyFactoryContract_v1_3_0_Contract} + */ +export type SafeProxyFactoryContract_v1_3_0_Contract = + SafeProxyFactoryBaseContract diff --git a/packages/safe-core-sdk-types/src/contracts/SafeProxyFactory/v1.4.1/SafeProxyFactoryContract_v1_4_1.ts b/packages/safe-core-sdk-types/src/contracts/SafeProxyFactory/v1.4.1/SafeProxyFactoryContract_v1_4_1.ts new file mode 100644 index 000000000..64efa05be --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/SafeProxyFactory/v1.4.1/SafeProxyFactoryContract_v1_4_1.ts @@ -0,0 +1,34 @@ +import { ExtractAbiFunctionNames, narrow } from 'abitype' +import safeProxyFactory_1_4_1_ContractArtifacts from '../../assets/SafeProxyFactory/v1.4.1/safe_proxy_factory' +import SafeProxyFactoryBaseContract from '../SafeProxyFactoryBaseContract' +import { ContractFunction } from '../../common/BaseContract' + +const safeProxyFactoryContract_v1_4_1_AbiTypes = narrow( + safeProxyFactory_1_4_1_ContractArtifacts.abi +) + +/** + * Represents the ABI of the Safe Proxy Factory contract version 1.4.1. + * + * @type {SafeProxyFactoryContract_v1_4_1_Abi} + */ +export type SafeProxyFactoryContract_v1_4_1_Abi = typeof safeProxyFactoryContract_v1_4_1_AbiTypes + +/** + * Represents the function type derived by the given function name from the SafeProxyFactory contract version 1.4.1 ABI. + * + * @template ContractFunctionName - The function name, derived from the ABI. + * @type {SafeProxyFactoryContract_v1_4_1_Function} + */ +export type SafeProxyFactoryContract_v1_4_1_Function< + ContractFunctionName extends ExtractAbiFunctionNames +> = ContractFunction + +/** + * Represents the contract type for a Safe Proxy Factory contract version 1.4.1, defining read and write methods. + * Utilizes the generic SafeProxyFactoryBaseContract with the ABI specific to version 1.4.1. + * + * @type {SafeProxyFactoryContract_v1_4_1_Contract} + */ +export type SafeProxyFactoryContract_v1_4_1_Contract = + SafeProxyFactoryBaseContract diff --git a/packages/safe-core-sdk-types/src/contracts/SafeProxyFactoryContract.ts b/packages/safe-core-sdk-types/src/contracts/SafeProxyFactoryContract.ts deleted file mode 100644 index 1f4dcb0c7..000000000 --- a/packages/safe-core-sdk-types/src/contracts/SafeProxyFactoryContract.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { TransactionOptions } from '@safe-global/safe-core-sdk-types/types' - -export interface CreateProxyProps { - safeSingletonAddress: string - initializer: string - saltNonce: string - options?: TransactionOptions - callback?: (txHash: string) => void -} - -export interface SafeProxyFactoryContract { - getAddress(): Promise - proxyCreationCode(): Promise - createProxy(options: CreateProxyProps): Promise - encode(methodName: string, params: any[]): string - estimateGas(methodName: string, params: any[], options: TransactionOptions): Promise -} diff --git a/packages/safe-core-sdk-types/src/contracts/SignMessageLib/SignMessageLibBaseContract.ts b/packages/safe-core-sdk-types/src/contracts/SignMessageLib/SignMessageLibBaseContract.ts new file mode 100644 index 000000000..de869c05a --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/SignMessageLib/SignMessageLibBaseContract.ts @@ -0,0 +1,22 @@ +import { Abi } from 'abitype' +import BaseContract, { + SafeContractFunction, + ContractReadFunctionNames, + EstimateGasFunction +} from '../common/BaseContract' + +/** + * Represents the base contract type for a SignMessageLib contract. + * + * @template SignMessageLibContractAbi - The ABI of the SignMessageLib contract. + * @type {SignMessageLibBaseContract} + */ +type SignMessageLibBaseContract = BaseContract< + SignMessageLibContractAbi, + ContractReadFunctionNames +> & { + estimateGas: EstimateGasFunction + signMessage: SafeContractFunction +} + +export default SignMessageLibBaseContract diff --git a/packages/safe-core-sdk-types/src/contracts/SignMessageLib/index.ts b/packages/safe-core-sdk-types/src/contracts/SignMessageLib/index.ts new file mode 100644 index 000000000..98f9a3694 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/SignMessageLib/index.ts @@ -0,0 +1,9 @@ +import { SignMessageLibContract_v1_3_0_Contract } from './v1.3.0/SignMessageLibContract_v1_3_0' +import { SignMessageLibContract_v1_4_1_Contract } from './v1.4.1/SignMessageLibContract_v1_4_1' + +export * from './v1.3.0/SignMessageLibContract_v1_3_0' +export * from './v1.4.1/SignMessageLibContract_v1_4_1' + +export type SignMessageLibContractType = + | SignMessageLibContract_v1_3_0_Contract + | SignMessageLibContract_v1_4_1_Contract diff --git a/packages/safe-core-sdk-types/src/contracts/SignMessageLib/v1.3.0/SignMessageLibContract_v1_3_0.ts b/packages/safe-core-sdk-types/src/contracts/SignMessageLib/v1.3.0/SignMessageLibContract_v1_3_0.ts new file mode 100644 index 000000000..a9d90eedd --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/SignMessageLib/v1.3.0/SignMessageLibContract_v1_3_0.ts @@ -0,0 +1,32 @@ +import { ExtractAbiFunctionNames, narrow } from 'abitype' +import signMessageLib_1_3_0_ContractArtifacts from '../../assets/SignMessageLib/v1.3.0/sign_message_lib' +import SignMessageLibBaseContract from '../SignMessageLibBaseContract' +import { ContractFunction } from '../../common/BaseContract' + +const signMessageLibContract_v1_3_0_AbiTypes = narrow(signMessageLib_1_3_0_ContractArtifacts.abi) + +/** + * Represents the ABI of the SignMessageLib contract version 1.3.0. + * + * @type {SignMessageLibContract_v1_3_0_Abi} + */ +export type SignMessageLibContract_v1_3_0_Abi = typeof signMessageLibContract_v1_3_0_AbiTypes + +/** + * Represents the function type derived by the given function name from the SignMessageLib contract version 1.3.0 ABI. + * + * @template ContractFunctionName - The function name, derived from the ABI. + * @type {SignMessageLibContract_v1_3_0_Function} + */ +export type SignMessageLibContract_v1_3_0_Function< + ContractFunctionName extends ExtractAbiFunctionNames +> = ContractFunction + +/** + * Represents the contract type for a SignMessageLib contract version 1.3.0 defining read and write methods. + * Utilizes the generic SignMessageLibBaseContract with the ABI specific to version 1.3.0. + * + * @type {SignMessageLibContract_v1_3_0_Contract} + */ +export type SignMessageLibContract_v1_3_0_Contract = + SignMessageLibBaseContract diff --git a/packages/safe-core-sdk-types/src/contracts/SignMessageLib/v1.4.1/SignMessageLibContract_v1_4_1.ts b/packages/safe-core-sdk-types/src/contracts/SignMessageLib/v1.4.1/SignMessageLibContract_v1_4_1.ts new file mode 100644 index 000000000..2d04261ef --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/SignMessageLib/v1.4.1/SignMessageLibContract_v1_4_1.ts @@ -0,0 +1,32 @@ +import { ExtractAbiFunctionNames, narrow } from 'abitype' +import signMessageLib_1_4_1_ContractArtifacts from '../../assets/SignMessageLib/v1.4.1/sign_message_lib' +import SignMessageLibBaseContract from '../SignMessageLibBaseContract' +import { ContractFunction } from '../../common/BaseContract' + +const signMessageLibContract_v1_4_1_AbiTypes = narrow(signMessageLib_1_4_1_ContractArtifacts.abi) + +/** + * Represents the ABI of the SignMessageLib contract version 1.4.1. + * + * @type {SignMessageLibContract_v1_4_1_Abi} + */ +export type SignMessageLibContract_v1_4_1_Abi = typeof signMessageLibContract_v1_4_1_AbiTypes + +/** + * Represents the function type derived by the given function name from the SignMessageLib contract version 1.4.1 ABI. + * + * @template ContractFunctionName - The function name, derived from the ABI. + * @type {SignMessageLibContract_v1_4_1_Function} + */ +export type SignMessageLibContract_v1_4_1_Function< + ContractFunctionName extends ExtractAbiFunctionNames +> = ContractFunction + +/** + * Represents the contract type for a SignMessageLib contract version 1.4.1 defining read and write methods. + * Utilizes the generic SignMessageLibBaseContract with the ABI specific to version 1.4.1. + * + * @type {SignMessageLibContract_v1_4_1_Contract} + */ +export type SignMessageLibContract_v1_4_1_Contract = + SignMessageLibBaseContract diff --git a/packages/safe-core-sdk-types/src/contracts/SignMessageLibContract.ts b/packages/safe-core-sdk-types/src/contracts/SignMessageLibContract.ts deleted file mode 100644 index d0585b24d..000000000 --- a/packages/safe-core-sdk-types/src/contracts/SignMessageLibContract.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { TransactionOptions, TransactionResult } from '@safe-global/safe-core-sdk-types/types' - -export interface SignMessageLibContract { - getAddress(): Promise - signMessage(data: string, options?: TransactionOptions): Promise - getMessageHash(message: string): Promise - encode(methodName: any, params: any): string - estimateGas(methodName: string, params: any[], options: TransactionOptions): Promise -} diff --git a/packages/safe-core-sdk-types/src/contracts/SimulateTxAccessor/SimulateTxAccessorBaseContract.ts b/packages/safe-core-sdk-types/src/contracts/SimulateTxAccessor/SimulateTxAccessorBaseContract.ts new file mode 100644 index 000000000..64d1854b8 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/SimulateTxAccessor/SimulateTxAccessorBaseContract.ts @@ -0,0 +1,13 @@ +import { Abi } from 'abitype' +import BaseContract from '../common/BaseContract' + +/** + * Represents the base contract type for a SimulateTxAccessor contract. + * + * @template SimulateTxAccessorContractAbi - The ABI of the SimulateTxAccessor contract. + * @type {SimulateTxAccessorBaseContract} + */ +type SimulateTxAccessorBaseContract = + BaseContract + +export default SimulateTxAccessorBaseContract diff --git a/packages/safe-core-sdk-types/src/contracts/SimulateTxAccessor/index.ts b/packages/safe-core-sdk-types/src/contracts/SimulateTxAccessor/index.ts new file mode 100644 index 000000000..c8e7256b2 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/SimulateTxAccessor/index.ts @@ -0,0 +1,9 @@ +import { SimulateTxAccessorContract_v1_3_0_Contract } from './v1.3.0/SimulateTxAccessorContract_v1_3_0' +import { SimulateTxAccessorContract_v1_4_1_Contract } from './v1.4.1/SimulateTxAccessorContract_v1_4_1' + +export * from './v1.3.0/SimulateTxAccessorContract_v1_3_0' +export * from './v1.4.1/SimulateTxAccessorContract_v1_4_1' + +export type SimulateTxAccessorContractType = + | SimulateTxAccessorContract_v1_3_0_Contract + | SimulateTxAccessorContract_v1_4_1_Contract diff --git a/packages/safe-core-sdk-types/src/contracts/SimulateTxAccessor/v1.3.0/SimulateTxAccessorContract_v1_3_0.ts b/packages/safe-core-sdk-types/src/contracts/SimulateTxAccessor/v1.3.0/SimulateTxAccessorContract_v1_3_0.ts new file mode 100644 index 000000000..e9fce679f --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/SimulateTxAccessor/v1.3.0/SimulateTxAccessorContract_v1_3_0.ts @@ -0,0 +1,35 @@ +import { ExtractAbiFunctionNames, narrow } from 'abitype' +import simulateTxAccessor_1_3_0_ContractArtifacts from '../../assets/SimulateTxAccessor/v1.3.0/simulate_tx_accessor' +import SimulateTxAccessorBaseContract from '../SimulateTxAccessorBaseContract' +import { ContractFunction } from '../../common/BaseContract' + +const simulateTxAccessorContract_v1_3_0_AbiTypes = narrow( + simulateTxAccessor_1_3_0_ContractArtifacts.abi +) + +/** + * Represents the ABI of the SimulateTxAccessor contract version 1.3.0. + * + * @type {SimulateTxAccessorContract_v1_3_0_Abi} + */ +export type SimulateTxAccessorContract_v1_3_0_Abi = + typeof simulateTxAccessorContract_v1_3_0_AbiTypes + +/** + * Represents the function type derived by the given function name from the SimulateTxAccessor contract version 1.3.0 ABI. + * + * @template ContractFunctionName - The function name, derived from the ABI. + * @type {SimulateTxAccessorContract_v1_3_0_Function} + */ +export type SimulateTxAccessorContract_v1_3_0_Function< + ContractFunctionName extends ExtractAbiFunctionNames +> = ContractFunction + +/** + * Represents the contract type for a SimulateTxAccessor contract version 1.3.0 defining read and write methods. + * Utilizes the generic SimulateTxAccessorBaseContract with the ABI specific to version 1.3.0. + * + * @type {SimulateTxAccessorContract_v1_3_0_Contract} + */ +export type SimulateTxAccessorContract_v1_3_0_Contract = + SimulateTxAccessorBaseContract diff --git a/packages/safe-core-sdk-types/src/contracts/SimulateTxAccessor/v1.4.1/SimulateTxAccessorContract_v1_4_1.ts b/packages/safe-core-sdk-types/src/contracts/SimulateTxAccessor/v1.4.1/SimulateTxAccessorContract_v1_4_1.ts new file mode 100644 index 000000000..18b17cbad --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/SimulateTxAccessor/v1.4.1/SimulateTxAccessorContract_v1_4_1.ts @@ -0,0 +1,35 @@ +import { ExtractAbiFunctionNames, narrow } from 'abitype' +import simulateTxAccessor_1_4_1_ContractArtifacts from '../../assets/SimulateTxAccessor/v1.4.1/simulate_tx_accessor' +import SimulateTxAccessorBaseContract from '../SimulateTxAccessorBaseContract' +import { ContractFunction } from '../../common/BaseContract' + +const simulateTxAccessorContract_v1_4_1_AbiTypes = narrow( + simulateTxAccessor_1_4_1_ContractArtifacts.abi +) + +/** + * Represents the ABI of the SimulateTxAccessor contract version 1.4.1. + * + * @type {SimulateTxAccessorContract_v1_4_1_Abi} + */ +export type SimulateTxAccessorContract_v1_4_1_Abi = + typeof simulateTxAccessorContract_v1_4_1_AbiTypes + +/** + * Represents the function type derived by the given function name from the SimulateTxAccessor contract version 1.4.1 ABI. + * + * @template ContractFunctionName - The function name, derived from the ABI. + * @type {SimulateTxAccessorContract_v1_4_1_Function} + */ +export type SimulateTxAccessorContract_v1_4_1_Function< + ContractFunctionName extends ExtractAbiFunctionNames +> = ContractFunction + +/** + * Represents the contract type for a SimulateTxAccessor contract version 1.4.1 defining read and write methods. + * Utilizes the generic SimulateTxAccessorBaseContract with the ABI specific to version 1.4.1. + * + * @type {SimulateTxAccessorContract_v1_4_1_Contract} + */ +export type SimulateTxAccessorContract_v1_4_1_Contract = + SimulateTxAccessorBaseContract diff --git a/packages/safe-core-sdk-types/src/contracts/SimulateTxAccessorContract.ts b/packages/safe-core-sdk-types/src/contracts/SimulateTxAccessorContract.ts deleted file mode 100644 index 33a5c2867..000000000 --- a/packages/safe-core-sdk-types/src/contracts/SimulateTxAccessorContract.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface SimulateTxAccessorContract { - getAddress(): Promise - encode(methodName: any, params: any): string -} diff --git a/packages/safe-core-sdk-types/src/contracts/assets/CompatibilityFallbackHandler/v1.3.0/compatibility_fallback_handler.ts b/packages/safe-core-sdk-types/src/contracts/assets/CompatibilityFallbackHandler/v1.3.0/compatibility_fallback_handler.ts new file mode 100644 index 000000000..d87b23875 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/assets/CompatibilityFallbackHandler/v1.3.0/compatibility_fallback_handler.ts @@ -0,0 +1,330 @@ +// Source: https://github.com/safe-global/safe-deployments/blob/main/src/assets/v1.3.0/compatibility_fallback_handler.json +export default { + contractName: 'CompatibilityFallbackHandler', + version: '1.3.0', + abi: [ + { + inputs: [], + name: 'NAME', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'VERSION', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes', + name: 'message', + type: 'bytes' + } + ], + name: 'getMessageHash', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'contract GnosisSafe', + name: 'safe', + type: 'address' + }, + { + internalType: 'bytes', + name: 'message', + type: 'bytes' + } + ], + name: 'getMessageHashForSafe', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'getModules', + outputs: [ + { + internalType: 'address[]', + name: '', + type: 'address[]' + } + ], + 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: 'bytes', + name: '_data', + type: 'bytes' + }, + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'isValidSignature', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]' + }, + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]' + }, + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + name: 'onERC1155BatchReceived', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'pure', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'uint256', + name: '', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '', + type: 'uint256' + }, + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + name: 'onERC1155Received', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'pure', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'uint256', + name: '', + type: 'uint256' + }, + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + name: 'onERC721Received', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'pure', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'targetContract', + type: 'address' + }, + { + internalType: 'bytes', + name: 'calldataPayload', + type: 'bytes' + } + ], + name: 'simulate', + outputs: [ + { + internalType: 'bytes', + name: 'response', + type: 'bytes' + } + ], + 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: '', + type: 'address' + }, + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'uint256', + name: '', + type: 'uint256' + }, + { + internalType: 'bytes', + name: '', + type: 'bytes' + }, + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + name: 'tokensReceived', + outputs: [], + stateMutability: 'pure', + type: 'function' + } + ] +} as const diff --git a/packages/safe-core-sdk-types/src/contracts/assets/CompatibilityFallbackHandler/v1.4.1/compatibility_fallback_handler.ts b/packages/safe-core-sdk-types/src/contracts/assets/CompatibilityFallbackHandler/v1.4.1/compatibility_fallback_handler.ts new file mode 100644 index 000000000..4c694b390 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/assets/CompatibilityFallbackHandler/v1.4.1/compatibility_fallback_handler.ts @@ -0,0 +1,328 @@ +// Source: https://github.com/safe-global/safe-deployments/blob/main/src/assets/v1.4.1/compatibility_fallback_handler.json +export default { + contractName: 'CompatibilityFallbackHandler', + version: '1.4.1', + abi: [ + { + inputs: [ + { + internalType: 'contract Safe', + name: 'safe', + type: 'address' + }, + { + internalType: 'bytes', + name: 'message', + type: 'bytes' + } + ], + name: 'encodeMessageDataForSafe', + outputs: [ + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes', + name: 'message', + type: 'bytes' + } + ], + name: 'getMessageHash', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'contract Safe', + name: 'safe', + type: 'address' + }, + { + internalType: 'bytes', + name: 'message', + type: 'bytes' + } + ], + name: 'getMessageHashForSafe', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'getModules', + outputs: [ + { + internalType: 'address[]', + name: '', + type: 'address[]' + } + ], + 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: 'bytes', + name: '_data', + type: 'bytes' + }, + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'isValidSignature', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]' + }, + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]' + }, + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + name: 'onERC1155BatchReceived', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'pure', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'uint256', + name: '', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '', + type: 'uint256' + }, + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + name: 'onERC1155Received', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'pure', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'uint256', + name: '', + type: 'uint256' + }, + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + name: 'onERC721Received', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'pure', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'targetContract', + type: 'address' + }, + { + internalType: 'bytes', + name: 'calldataPayload', + type: 'bytes' + } + ], + name: 'simulate', + outputs: [ + { + internalType: 'bytes', + name: 'response', + type: 'bytes' + } + ], + 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: '', + type: 'address' + }, + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'uint256', + name: '', + type: 'uint256' + }, + { + internalType: 'bytes', + name: '', + type: 'bytes' + }, + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + name: 'tokensReceived', + outputs: [], + stateMutability: 'pure', + type: 'function' + } + ] +} as const diff --git a/packages/safe-core-sdk-types/src/contracts/assets/CreateCall/v1.3.0/create_call.ts b/packages/safe-core-sdk-types/src/contracts/assets/CreateCall/v1.3.0/create_call.ts new file mode 100644 index 000000000..1aae081d5 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/assets/CreateCall/v1.3.0/create_call.ts @@ -0,0 +1,73 @@ +// Source: https://github.com/safe-global/safe-deployments/blob/main/src/assets/v1.3.0/create_call.json +export default { + contractName: 'CreateCall', + version: '1.3.0', + abi: [ + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'newContract', + type: 'address' + } + ], + name: 'ContractCreation', + type: 'event' + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'value', + type: 'uint256' + }, + { + internalType: 'bytes', + name: 'deploymentData', + type: 'bytes' + } + ], + name: 'performCreate', + outputs: [ + { + internalType: 'address', + name: 'newContract', + type: 'address' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'value', + type: 'uint256' + }, + { + internalType: 'bytes', + name: 'deploymentData', + type: 'bytes' + }, + { + internalType: 'bytes32', + name: 'salt', + type: 'bytes32' + } + ], + name: 'performCreate2', + outputs: [ + { + internalType: 'address', + name: 'newContract', + type: 'address' + } + ], + stateMutability: 'nonpayable', + type: 'function' + } + ] +} as const diff --git a/packages/safe-core-sdk-types/src/contracts/assets/CreateCall/v1.4.1/create_call.ts b/packages/safe-core-sdk-types/src/contracts/assets/CreateCall/v1.4.1/create_call.ts new file mode 100644 index 000000000..c965733c8 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/assets/CreateCall/v1.4.1/create_call.ts @@ -0,0 +1,73 @@ +// Source: https://github.com/safe-global/safe-deployments/blob/main/src/assets/v1.4.1/create_call.json +export default { + contractName: 'CreateCall', + version: '1.4.1', + abi: [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'newContract', + type: 'address' + } + ], + name: 'ContractCreation', + type: 'event' + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'value', + type: 'uint256' + }, + { + internalType: 'bytes', + name: 'deploymentData', + type: 'bytes' + } + ], + name: 'performCreate', + outputs: [ + { + internalType: 'address', + name: 'newContract', + type: 'address' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'value', + type: 'uint256' + }, + { + internalType: 'bytes', + name: 'deploymentData', + type: 'bytes' + }, + { + internalType: 'bytes32', + name: 'salt', + type: 'bytes32' + } + ], + name: 'performCreate2', + outputs: [ + { + internalType: 'address', + name: 'newContract', + type: 'address' + } + ], + stateMutability: 'nonpayable', + type: 'function' + } + ] +} as const diff --git a/packages/safe-core-sdk-types/src/contracts/assets/MultiSend/v1.1.1/multi_send.ts b/packages/safe-core-sdk-types/src/contracts/assets/MultiSend/v1.1.1/multi_send.ts new file mode 100644 index 000000000..1a56fcca3 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/assets/MultiSend/v1.1.1/multi_send.ts @@ -0,0 +1,28 @@ +// Source: https://github.com/safe-global/safe-deployments/blob/main/src/assets/v1.1.1/multi_send.json +export default { + contractName: 'MultiSend', + version: '1.1.1', + abi: [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor' + }, + { + constant: false, + inputs: [ + { + internalType: 'bytes', + name: 'transactions', + type: 'bytes' + } + ], + name: 'multiSend', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + } + ] +} as const diff --git a/packages/safe-core-sdk-types/src/contracts/assets/MultiSend/v1.3.0/multi_send.ts b/packages/safe-core-sdk-types/src/contracts/assets/MultiSend/v1.3.0/multi_send.ts new file mode 100644 index 000000000..a001d64e5 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/assets/MultiSend/v1.3.0/multi_send.ts @@ -0,0 +1,25 @@ +// Source: https://github.com/safe-global/safe-deployments/blob/main/src/assets/v1.3.0/multi_send.json +export default { + contractName: 'MultiSend', + version: '1.3.0', + abi: [ + { + inputs: [], + stateMutability: 'nonpayable', + type: 'constructor' + }, + { + inputs: [ + { + internalType: 'bytes', + name: 'transactions', + type: 'bytes' + } + ], + name: 'multiSend', + outputs: [], + stateMutability: 'payable', + type: 'function' + } + ] +} as const diff --git a/packages/safe-core-sdk-types/src/contracts/assets/MultiSend/v1.3.0/multi_send_call_only.ts b/packages/safe-core-sdk-types/src/contracts/assets/MultiSend/v1.3.0/multi_send_call_only.ts new file mode 100644 index 000000000..ddc3b1950 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/assets/MultiSend/v1.3.0/multi_send_call_only.ts @@ -0,0 +1,20 @@ +// Source: https://github.com/safe-global/safe-deployments/blob/main/src/assets/v1.3.0/multi_send_call_only.json +export default { + contractName: 'MultiSendCallOnly', + version: '1.3.0', + abi: [ + { + inputs: [ + { + internalType: 'bytes', + name: 'transactions', + type: 'bytes' + } + ], + name: 'multiSend', + outputs: [], + stateMutability: 'payable', + type: 'function' + } + ] +} as const diff --git a/packages/safe-core-sdk-types/src/contracts/assets/MultiSend/v1.4.1/multi_send.ts b/packages/safe-core-sdk-types/src/contracts/assets/MultiSend/v1.4.1/multi_send.ts new file mode 100644 index 000000000..e31f239a4 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/assets/MultiSend/v1.4.1/multi_send.ts @@ -0,0 +1,25 @@ +// Source: https://github.com/safe-global/safe-deployments/blob/main/src/assets/v1.4.1/multi_send.json +export default { + contractName: 'MultiSend', + version: '1.4.1', + abi: [ + { + inputs: [], + stateMutability: 'nonpayable', + type: 'constructor' + }, + { + inputs: [ + { + internalType: 'bytes', + name: 'transactions', + type: 'bytes' + } + ], + name: 'multiSend', + outputs: [], + stateMutability: 'payable', + type: 'function' + } + ] +} as const diff --git a/packages/safe-core-sdk-types/src/contracts/assets/MultiSend/v1.4.1/multi_send_call_only.ts b/packages/safe-core-sdk-types/src/contracts/assets/MultiSend/v1.4.1/multi_send_call_only.ts new file mode 100644 index 000000000..b7f864145 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/assets/MultiSend/v1.4.1/multi_send_call_only.ts @@ -0,0 +1,20 @@ +// Source: https://github.com/safe-global/safe-deployments/blob/main/src/assets/v1.4.1/multi_send_call_only.json +export default { + contractName: 'MultiSendCallOnly', + version: '1.4.1', + abi: [ + { + inputs: [ + { + internalType: 'bytes', + name: 'transactions', + type: 'bytes' + } + ], + name: 'multiSend', + outputs: [], + stateMutability: 'payable', + type: 'function' + } + ] +} as const diff --git a/packages/safe-core-sdk-types/src/contracts/assets/Safe/v1.0.0/gnosis_safe.ts b/packages/safe-core-sdk-types/src/contracts/assets/Safe/v1.0.0/gnosis_safe.ts new file mode 100644 index 000000000..e2aca06fa --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/assets/Safe/v1.0.0/gnosis_safe.ts @@ -0,0 +1,409 @@ +// Source: https://github.com/safe-global/safe-deployments/blob/main/src/assets/v1.0.0/gnosis_safe.json +export default { + contractName: 'GnosisSafe', + version: '1.0.0', + abi: [ + { + constant: false, + inputs: [ + { name: 'owner', type: 'address' }, + { name: '_threshold', type: 'uint256' } + ], + name: 'addOwnerWithThreshold', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'DOMAIN_SEPARATOR_TYPEHASH', + outputs: [{ name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [{ name: 'owner', type: 'address' }], + name: 'isOwner', + outputs: [{ name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { name: 'to', type: 'address' }, + { name: 'value', type: 'uint256' }, + { name: 'data', type: 'bytes' }, + { name: 'operation', type: 'uint8' } + ], + name: 'execTransactionFromModule', + outputs: [{ name: 'success', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [{ name: '', type: 'bytes32' }], + name: 'signedMessages', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [{ name: 'module', type: 'address' }], + name: 'enableModule', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [{ name: '_threshold', type: 'uint256' }], + name: 'changeThreshold', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [ + { name: '', type: 'address' }, + { name: '', type: 'bytes32' } + ], + name: 'approvedHashes', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [{ name: '_masterCopy', type: 'address' }], + name: 'changeMasterCopy', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'SENTINEL_MODULES', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'SENTINEL_OWNERS', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'getOwners', + outputs: [{ name: '', type: 'address[]' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'NAME', + outputs: [{ name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'nonce', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'getModules', + outputs: [{ name: '', type: 'address[]' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'SAFE_MSG_TYPEHASH', + outputs: [{ name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'SAFE_TX_TYPEHASH', + outputs: [{ name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { name: 'prevModule', type: 'address' }, + { name: 'module', type: 'address' } + ], + name: 'disableModule', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [ + { name: 'prevOwner', type: 'address' }, + { name: 'oldOwner', type: 'address' }, + { name: 'newOwner', type: 'address' } + ], + name: 'swapOwner', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'getThreshold', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'domainSeparator', + outputs: [{ name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { name: 'prevOwner', type: 'address' }, + { name: 'owner', type: 'address' }, + { name: '_threshold', type: 'uint256' } + ], + name: 'removeOwner', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'VERSION', + outputs: [{ name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { payable: true, stateMutability: 'payable', type: 'fallback' }, + { + anonymous: false, + inputs: [{ indexed: false, name: 'txHash', type: 'bytes32' }], + name: 'ExecutionFailed', + type: 'event' + }, + { + anonymous: false, + inputs: [{ indexed: false, name: 'owner', type: 'address' }], + name: 'AddedOwner', + type: 'event' + }, + { + anonymous: false, + inputs: [{ indexed: false, name: 'owner', type: 'address' }], + name: 'RemovedOwner', + type: 'event' + }, + { + anonymous: false, + inputs: [{ indexed: false, name: 'threshold', type: 'uint256' }], + name: 'ChangedThreshold', + type: 'event' + }, + { + anonymous: false, + inputs: [{ indexed: false, name: 'module', type: 'address' }], + name: 'EnabledModule', + type: 'event' + }, + { + anonymous: false, + inputs: [{ indexed: false, name: 'module', type: 'address' }], + name: 'DisabledModule', + type: 'event' + }, + { + anonymous: false, + inputs: [{ indexed: false, name: 'newContract', type: 'address' }], + name: 'ContractCreation', + type: 'event' + }, + { + constant: false, + inputs: [ + { name: '_owners', type: 'address[]' }, + { name: '_threshold', type: 'uint256' }, + { name: 'to', type: 'address' }, + { name: 'data', type: 'bytes' }, + { name: 'paymentToken', type: 'address' }, + { name: 'payment', type: 'uint256' }, + { name: 'paymentReceiver', type: 'address' } + ], + name: 'setup', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [ + { name: 'to', type: 'address' }, + { name: 'value', type: 'uint256' }, + { name: 'data', type: 'bytes' }, + { name: 'operation', type: 'uint8' }, + { name: 'safeTxGas', type: 'uint256' }, + { name: 'baseGas', type: 'uint256' }, + { name: 'gasPrice', type: 'uint256' }, + { name: 'gasToken', type: 'address' }, + { name: 'refundReceiver', type: 'address' }, + { name: 'signatures', type: 'bytes' } + ], + name: 'execTransaction', + outputs: [{ name: 'success', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [ + { name: 'to', type: 'address' }, + { name: 'value', type: 'uint256' }, + { name: 'data', type: 'bytes' }, + { name: 'operation', type: 'uint8' } + ], + name: 'requiredTxGas', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [{ name: 'hashToApprove', type: 'bytes32' }], + name: 'approveHash', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [{ name: '_data', type: 'bytes' }], + name: 'signMessage', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [ + { name: '_data', type: 'bytes' }, + { name: '_signature', type: 'bytes' } + ], + name: 'isValidSignature', + outputs: [{ name: '', type: 'bytes4' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [{ name: 'message', type: 'bytes' }], + name: 'getMessageHash', + outputs: [{ name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [ + { name: 'to', type: 'address' }, + { name: 'value', type: 'uint256' }, + { name: 'data', type: 'bytes' }, + { name: 'operation', type: 'uint8' }, + { name: 'safeTxGas', type: 'uint256' }, + { name: 'baseGas', type: 'uint256' }, + { name: 'gasPrice', type: 'uint256' }, + { name: 'gasToken', type: 'address' }, + { name: 'refundReceiver', type: 'address' }, + { name: '_nonce', type: 'uint256' } + ], + name: 'encodeTransactionData', + outputs: [{ name: '', type: 'bytes' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [ + { name: 'to', type: 'address' }, + { name: 'value', type: 'uint256' }, + { name: 'data', type: 'bytes' }, + { name: 'operation', type: 'uint8' }, + { name: 'safeTxGas', type: 'uint256' }, + { name: 'baseGas', type: 'uint256' }, + { name: 'gasPrice', type: 'uint256' }, + { name: 'gasToken', type: 'address' }, + { name: 'refundReceiver', type: 'address' }, + { name: '_nonce', type: 'uint256' } + ], + name: 'getTransactionHash', + outputs: [{ name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function' + } + ] +} as const diff --git a/packages/safe-core-sdk-types/src/contracts/assets/Safe/v1.1.1/gnosis_safe.ts b/packages/safe-core-sdk-types/src/contracts/assets/Safe/v1.1.1/gnosis_safe.ts new file mode 100644 index 000000000..3f5ed8862 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/assets/Safe/v1.1.1/gnosis_safe.ts @@ -0,0 +1,984 @@ +// Source: https://github.com/safe-global/safe-deployments/blob/main/src/assets/v1.1.1/gnosis_safe.json +export default { + contractName: 'GnosisSafe', + version: '1.1.1', + abi: [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'owner', + type: 'address' + } + ], + name: 'AddedOwner', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: 'approvedHash', + type: 'bytes32' + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address' + } + ], + name: 'ApproveHash', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'masterCopy', + type: 'address' + } + ], + name: 'ChangedMasterCopy', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'threshold', + type: 'uint256' + } + ], + name: 'ChangedThreshold', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract Module', + name: 'module', + type: 'address' + } + ], + name: 'DisabledModule', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract Module', + name: 'module', + type: 'address' + } + ], + name: 'EnabledModule', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bytes32', + name: 'txHash', + type: 'bytes32' + }, + { + indexed: false, + internalType: 'uint256', + name: 'payment', + 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: false, + internalType: 'bytes32', + name: 'txHash', + type: 'bytes32' + }, + { + indexed: false, + internalType: 'uint256', + name: 'payment', + type: 'uint256' + } + ], + name: 'ExecutionSuccess', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'owner', + type: 'address' + } + ], + name: 'RemovedOwner', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: 'msgHash', + type: 'bytes32' + } + ], + name: 'SignMsg', + type: 'event' + }, + { + payable: true, + stateMutability: 'payable', + type: 'fallback' + }, + { + constant: true, + inputs: [], + name: 'NAME', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'VERSION', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address' + }, + { + internalType: 'uint256', + name: '_threshold', + type: 'uint256' + } + ], + name: 'addOwnerWithThreshold', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + name: 'approvedHashes', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: '_masterCopy', + type: 'address' + } + ], + name: 'changeMasterCopy', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: '_threshold', + type: 'uint256' + } + ], + name: 'changeThreshold', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [ + { + internalType: 'contract Module', + name: 'prevModule', + type: 'address' + }, + { + internalType: 'contract Module', + name: 'module', + type: 'address' + } + ], + name: 'disableModule', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'domainSeparator', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { + internalType: 'contract Module', + name: 'module', + type: 'address' + } + ], + name: 'enableModule', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + 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: 'success', + type: 'bool' + } + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + 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' + } + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'getModules', + outputs: [ + { + internalType: 'address[]', + name: '', + type: 'address[]' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + 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' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'getOwners', + outputs: [ + { + internalType: 'address[]', + name: '', + type: 'address[]' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'getThreshold', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address' + } + ], + name: 'isOwner', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'nonce', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'prevOwner', + type: 'address' + }, + { + internalType: 'address', + name: 'owner', + type: 'address' + }, + { + internalType: 'uint256', + name: '_threshold', + type: 'uint256' + } + ], + name: 'removeOwner', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'handler', + type: 'address' + } + ], + name: 'setFallbackHandler', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + name: 'signedMessages', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'prevOwner', + type: 'address' + }, + { + internalType: 'address', + name: 'oldOwner', + type: 'address' + }, + { + internalType: 'address', + name: 'newOwner', + type: 'address' + } + ], + name: 'swapOwner', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [ + { + internalType: 'address[]', + name: '_owners', + type: 'address[]' + }, + { + internalType: 'uint256', + name: '_threshold', + type: 'uint256' + }, + { + internalType: 'address', + name: 'to', + type: 'address' + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes' + }, + { + internalType: 'address', + name: 'fallbackHandler', + type: 'address' + }, + { + internalType: 'address', + name: 'paymentToken', + type: 'address' + }, + { + internalType: 'uint256', + name: 'payment', + type: 'uint256' + }, + { + internalType: 'address payable', + name: 'paymentReceiver', + type: 'address' + } + ], + name: 'setup', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + 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: 'safeTxGas', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'baseGas', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'gasPrice', + type: 'uint256' + }, + { + internalType: 'address', + name: 'gasToken', + type: 'address' + }, + { + internalType: 'address payable', + name: 'refundReceiver', + type: 'address' + }, + { + internalType: 'bytes', + name: 'signatures', + type: 'bytes' + } + ], + name: 'execTransaction', + outputs: [ + { + internalType: 'bool', + name: 'success', + type: 'bool' + } + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + 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: 'requiredTxGas', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [ + { + internalType: 'bytes32', + name: 'hashToApprove', + type: 'bytes32' + } + ], + name: 'approveHash', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [ + { + internalType: 'bytes', + name: '_data', + type: 'bytes' + } + ], + name: 'signMessage', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [ + { + internalType: 'bytes', + name: '_data', + type: 'bytes' + }, + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'isValidSignature', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [ + { + internalType: 'bytes', + name: 'message', + type: 'bytes' + } + ], + name: 'getMessageHash', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + 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: 'safeTxGas', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'baseGas', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'gasPrice', + type: 'uint256' + }, + { + internalType: 'address', + name: 'gasToken', + type: 'address' + }, + { + internalType: 'address', + name: 'refundReceiver', + type: 'address' + }, + { + internalType: 'uint256', + name: '_nonce', + type: 'uint256' + } + ], + name: 'encodeTransactionData', + outputs: [ + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + 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: 'safeTxGas', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'baseGas', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'gasPrice', + type: 'uint256' + }, + { + internalType: 'address', + name: 'gasToken', + type: 'address' + }, + { + internalType: 'address', + name: 'refundReceiver', + type: 'address' + }, + { + internalType: 'uint256', + name: '_nonce', + type: 'uint256' + } + ], + name: 'getTransactionHash', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + } + ] +} as const diff --git a/packages/safe-core-sdk-types/src/contracts/assets/Safe/v1.2.0/gnosis_safe.ts b/packages/safe-core-sdk-types/src/contracts/assets/Safe/v1.2.0/gnosis_safe.ts new file mode 100644 index 000000000..84951a67a --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/assets/Safe/v1.2.0/gnosis_safe.ts @@ -0,0 +1,1005 @@ +// Source: https://github.com/safe-global/safe-deployments/blob/main/src/assets/v1.2.0/gnosis_safe.json +export default { + contractName: 'GnosisSafe', + version: '1.2.0', + abi: [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'owner', + type: 'address' + } + ], + name: 'AddedOwner', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: 'approvedHash', + type: 'bytes32' + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address' + } + ], + name: 'ApproveHash', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'masterCopy', + type: 'address' + } + ], + name: 'ChangedMasterCopy', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'threshold', + type: 'uint256' + } + ], + name: 'ChangedThreshold', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract Module', + name: 'module', + type: 'address' + } + ], + name: 'DisabledModule', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract Module', + name: 'module', + type: 'address' + } + ], + name: 'EnabledModule', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bytes32', + name: 'txHash', + type: 'bytes32' + }, + { + indexed: false, + internalType: 'uint256', + name: 'payment', + 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: false, + internalType: 'bytes32', + name: 'txHash', + type: 'bytes32' + }, + { + indexed: false, + internalType: 'uint256', + name: 'payment', + type: 'uint256' + } + ], + name: 'ExecutionSuccess', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'owner', + type: 'address' + } + ], + name: 'RemovedOwner', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: 'msgHash', + type: 'bytes32' + } + ], + name: 'SignMsg', + type: 'event' + }, + { + payable: true, + stateMutability: 'payable', + type: 'fallback' + }, + { + constant: true, + inputs: [], + name: 'NAME', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'VERSION', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address' + }, + { + internalType: 'uint256', + name: '_threshold', + type: 'uint256' + } + ], + name: 'addOwnerWithThreshold', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + name: 'approvedHashes', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: '_masterCopy', + type: 'address' + } + ], + name: 'changeMasterCopy', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: '_threshold', + type: 'uint256' + } + ], + name: 'changeThreshold', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [ + { + internalType: 'contract Module', + name: 'prevModule', + type: 'address' + }, + { + internalType: 'contract Module', + name: 'module', + type: 'address' + } + ], + name: 'disableModule', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'domainSeparator', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { + internalType: 'contract Module', + name: 'module', + type: 'address' + } + ], + name: 'enableModule', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + 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: 'success', + type: 'bool' + } + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + 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' + } + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'getModules', + outputs: [ + { + internalType: 'address[]', + name: '', + type: 'address[]' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + 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' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'getOwners', + outputs: [ + { + internalType: 'address[]', + name: '', + type: 'address[]' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'getThreshold', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [ + { + internalType: 'contract Module', + name: 'module', + type: 'address' + } + ], + name: 'isModuleEnabled', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address' + } + ], + name: 'isOwner', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'nonce', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'prevOwner', + type: 'address' + }, + { + internalType: 'address', + name: 'owner', + type: 'address' + }, + { + internalType: 'uint256', + name: '_threshold', + type: 'uint256' + } + ], + name: 'removeOwner', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'handler', + type: 'address' + } + ], + name: 'setFallbackHandler', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + name: 'signedMessages', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'prevOwner', + type: 'address' + }, + { + internalType: 'address', + name: 'oldOwner', + type: 'address' + }, + { + internalType: 'address', + name: 'newOwner', + type: 'address' + } + ], + name: 'swapOwner', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [ + { + internalType: 'address[]', + name: '_owners', + type: 'address[]' + }, + { + internalType: 'uint256', + name: '_threshold', + type: 'uint256' + }, + { + internalType: 'address', + name: 'to', + type: 'address' + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes' + }, + { + internalType: 'address', + name: 'fallbackHandler', + type: 'address' + }, + { + internalType: 'address', + name: 'paymentToken', + type: 'address' + }, + { + internalType: 'uint256', + name: 'payment', + type: 'uint256' + }, + { + internalType: 'address payable', + name: 'paymentReceiver', + type: 'address' + } + ], + name: 'setup', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + 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: 'safeTxGas', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'baseGas', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'gasPrice', + type: 'uint256' + }, + { + internalType: 'address', + name: 'gasToken', + type: 'address' + }, + { + internalType: 'address payable', + name: 'refundReceiver', + type: 'address' + }, + { + internalType: 'bytes', + name: 'signatures', + type: 'bytes' + } + ], + name: 'execTransaction', + outputs: [ + { + internalType: 'bool', + name: 'success', + type: 'bool' + } + ], + payable: true, + stateMutability: 'payable', + type: 'function' + }, + { + constant: false, + 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: 'requiredTxGas', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [ + { + internalType: 'bytes32', + name: 'hashToApprove', + type: 'bytes32' + } + ], + name: 'approveHash', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [ + { + internalType: 'bytes', + name: '_data', + type: 'bytes' + } + ], + name: 'signMessage', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [ + { + internalType: 'bytes', + name: '_data', + type: 'bytes' + }, + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'isValidSignature', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [ + { + internalType: 'bytes', + name: 'message', + type: 'bytes' + } + ], + name: 'getMessageHash', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + 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: 'safeTxGas', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'baseGas', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'gasPrice', + type: 'uint256' + }, + { + internalType: 'address', + name: 'gasToken', + type: 'address' + }, + { + internalType: 'address', + name: 'refundReceiver', + type: 'address' + }, + { + internalType: 'uint256', + name: '_nonce', + type: 'uint256' + } + ], + name: 'encodeTransactionData', + outputs: [ + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + 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: 'safeTxGas', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'baseGas', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'gasPrice', + type: 'uint256' + }, + { + internalType: 'address', + name: 'gasToken', + type: 'address' + }, + { + internalType: 'address', + name: 'refundReceiver', + type: 'address' + }, + { + internalType: 'uint256', + name: '_nonce', + type: 'uint256' + } + ], + name: 'getTransactionHash', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + } + ] +} as const diff --git a/packages/safe-core-sdk-types/src/contracts/assets/Safe/v1.3.0/gnosis_safe_l2.ts b/packages/safe-core-sdk-types/src/contracts/assets/Safe/v1.3.0/gnosis_safe_l2.ts new file mode 100644 index 000000000..eb4f84d08 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/assets/Safe/v1.3.0/gnosis_safe_l2.ts @@ -0,0 +1,1142 @@ +export default { + contractName: 'GnosisSafeL2', + version: '1.3.0', + abi: [ + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'owner', + type: 'address' + } + ], + name: 'AddedOwner', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: 'approvedHash', + type: 'bytes32' + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address' + } + ], + name: 'ApproveHash', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'handler', + type: 'address' + } + ], + name: 'ChangedFallbackHandler', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'guard', + type: 'address' + } + ], + name: 'ChangedGuard', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'threshold', + type: 'uint256' + } + ], + name: 'ChangedThreshold', + 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: false, + internalType: 'bytes32', + name: 'txHash', + type: 'bytes32' + }, + { + indexed: false, + internalType: 'uint256', + name: 'payment', + 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: false, + internalType: 'bytes32', + name: 'txHash', + type: 'bytes32' + }, + { + indexed: false, + internalType: 'uint256', + name: 'payment', + type: 'uint256' + } + ], + name: 'ExecutionSuccess', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'owner', + type: 'address' + } + ], + name: 'RemovedOwner', + 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: 'SafeModuleTransaction', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + 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' + }, + { + indexed: false, + internalType: 'uint256', + name: 'safeTxGas', + type: 'uint256' + }, + { + indexed: false, + internalType: 'uint256', + name: 'baseGas', + type: 'uint256' + }, + { + indexed: false, + internalType: 'uint256', + name: 'gasPrice', + type: 'uint256' + }, + { + indexed: false, + internalType: 'address', + name: 'gasToken', + type: 'address' + }, + { + indexed: false, + internalType: 'address payable', + name: 'refundReceiver', + type: 'address' + }, + { + indexed: false, + internalType: 'bytes', + name: 'signatures', + type: 'bytes' + }, + { + indexed: false, + internalType: 'bytes', + name: 'additionalInfo', + type: 'bytes' + } + ], + name: 'SafeMultiSigTransaction', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address' + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256' + } + ], + name: 'SafeReceived', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'initiator', + type: 'address' + }, + { + indexed: false, + internalType: 'address[]', + name: 'owners', + type: 'address[]' + }, + { + indexed: false, + internalType: 'uint256', + name: 'threshold', + type: 'uint256' + }, + { + indexed: false, + internalType: 'address', + name: 'initializer', + type: 'address' + }, + { + indexed: false, + internalType: 'address', + name: 'fallbackHandler', + type: 'address' + } + ], + name: 'SafeSetup', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: 'msgHash', + type: 'bytes32' + } + ], + name: 'SignMsg', + type: 'event' + }, + { + stateMutability: 'nonpayable', + type: 'fallback' + }, + { + inputs: [], + name: 'VERSION', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address' + }, + { + internalType: 'uint256', + name: '_threshold', + type: 'uint256' + } + ], + name: 'addOwnerWithThreshold', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'hashToApprove', + type: 'bytes32' + } + ], + name: 'approveHash', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + name: 'approvedHashes', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_threshold', + type: 'uint256' + } + ], + name: 'changeThreshold', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'dataHash', + type: 'bytes32' + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes' + }, + { + internalType: 'bytes', + name: 'signatures', + type: 'bytes' + }, + { + internalType: 'uint256', + name: 'requiredSignatures', + type: 'uint256' + } + ], + name: 'checkNSignatures', + outputs: [], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'dataHash', + type: 'bytes32' + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes' + }, + { + internalType: 'bytes', + name: 'signatures', + type: 'bytes' + } + ], + name: 'checkSignatures', + outputs: [], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'prevModule', + type: 'address' + }, + { + internalType: 'address', + name: 'module', + type: 'address' + } + ], + name: 'disableModule', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [], + name: 'domainSeparator', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'module', + type: 'address' + } + ], + name: 'enableModule', + outputs: [], + 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: 'safeTxGas', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'baseGas', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'gasPrice', + type: 'uint256' + }, + { + internalType: 'address', + name: 'gasToken', + type: 'address' + }, + { + internalType: 'address', + name: 'refundReceiver', + type: 'address' + }, + { + internalType: 'uint256', + name: '_nonce', + type: 'uint256' + } + ], + name: 'encodeTransactionData', + outputs: [ + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + 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: 'operation', + type: 'uint8' + }, + { + internalType: 'uint256', + name: 'safeTxGas', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'baseGas', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'gasPrice', + type: 'uint256' + }, + { + internalType: 'address', + name: 'gasToken', + type: 'address' + }, + { + internalType: 'address payable', + name: 'refundReceiver', + type: 'address' + }, + { + internalType: 'bytes', + name: 'signatures', + type: 'bytes' + } + ], + name: 'execTransaction', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool' + } + ], + stateMutability: 'payable', + 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: '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: 'execTransactionFromModuleReturnData', + outputs: [ + { + internalType: 'bool', + name: 'success', + type: 'bool' + }, + { + internalType: 'bytes', + name: 'returnData', + type: 'bytes' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [], + name: 'getChainId', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + 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: [], + name: 'getOwners', + outputs: [ + { + internalType: 'address[]', + name: '', + type: 'address[]' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'offset', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'length', + type: 'uint256' + } + ], + name: 'getStorageAt', + outputs: [ + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'getThreshold', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + 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: 'operation', + type: 'uint8' + }, + { + internalType: 'uint256', + name: 'safeTxGas', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'baseGas', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'gasPrice', + type: 'uint256' + }, + { + internalType: 'address', + name: 'gasToken', + type: 'address' + }, + { + internalType: 'address', + name: 'refundReceiver', + type: 'address' + }, + { + internalType: 'uint256', + name: '_nonce', + type: 'uint256' + } + ], + name: 'getTransactionHash', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'module', + type: 'address' + } + ], + name: 'isModuleEnabled', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address' + } + ], + name: 'isOwner', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'nonce', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'prevOwner', + type: 'address' + }, + { + internalType: 'address', + name: 'owner', + type: 'address' + }, + { + internalType: 'uint256', + name: '_threshold', + type: 'uint256' + } + ], + name: 'removeOwner', + outputs: [], + 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: 'requiredTxGas', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'handler', + type: 'address' + } + ], + name: 'setFallbackHandler', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'guard', + type: 'address' + } + ], + name: 'setGuard', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address[]', + name: '_owners', + type: 'address[]' + }, + { + internalType: 'uint256', + name: '_threshold', + type: 'uint256' + }, + { + internalType: 'address', + name: 'to', + type: 'address' + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes' + }, + { + internalType: 'address', + name: 'fallbackHandler', + type: 'address' + }, + { + internalType: 'address', + name: 'paymentToken', + type: 'address' + }, + { + internalType: 'uint256', + name: 'payment', + type: 'uint256' + }, + { + internalType: 'address payable', + name: 'paymentReceiver', + type: 'address' + } + ], + name: 'setup', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + name: 'signedMessages', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'targetContract', + type: 'address' + }, + { + internalType: 'bytes', + name: 'calldataPayload', + type: 'bytes' + } + ], + name: 'simulateAndRevert', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'prevOwner', + type: 'address' + }, + { + internalType: 'address', + name: 'oldOwner', + type: 'address' + }, + { + internalType: 'address', + name: 'newOwner', + type: 'address' + } + ], + name: 'swapOwner', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + stateMutability: 'payable', + type: 'receive' + } + ] +} as const diff --git a/packages/safe-core-sdk-types/src/contracts/assets/Safe/v1.4.1/safe_l2.ts b/packages/safe-core-sdk-types/src/contracts/assets/Safe/v1.4.1/safe_l2.ts new file mode 100644 index 000000000..737cd021f --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/assets/Safe/v1.4.1/safe_l2.ts @@ -0,0 +1,1109 @@ +// Source: https://github.com/safe-global/safe-deployments/blob/main/src/assets/v1.4.1/safe_l2.json +export default { + contractName: 'SafeL2', + version: '1.4.1', + abi: [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address' + } + ], + name: 'AddedOwner', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: 'approvedHash', + type: 'bytes32' + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address' + } + ], + name: 'ApproveHash', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'handler', + type: 'address' + } + ], + name: 'ChangedFallbackHandler', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'guard', + type: 'address' + } + ], + name: 'ChangedGuard', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'threshold', + type: 'uint256' + } + ], + name: 'ChangedThreshold', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'module', + type: 'address' + } + ], + name: 'DisabledModule', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'module', + type: 'address' + } + ], + name: 'EnabledModule', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: 'txHash', + type: 'bytes32' + }, + { + indexed: false, + internalType: 'uint256', + name: 'payment', + 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: 'bytes32', + name: 'txHash', + type: 'bytes32' + }, + { + indexed: false, + internalType: 'uint256', + name: 'payment', + type: 'uint256' + } + ], + name: 'ExecutionSuccess', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address' + } + ], + name: 'RemovedOwner', + 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: 'SafeModuleTransaction', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + 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' + }, + { + indexed: false, + internalType: 'uint256', + name: 'safeTxGas', + type: 'uint256' + }, + { + indexed: false, + internalType: 'uint256', + name: 'baseGas', + type: 'uint256' + }, + { + indexed: false, + internalType: 'uint256', + name: 'gasPrice', + type: 'uint256' + }, + { + indexed: false, + internalType: 'address', + name: 'gasToken', + type: 'address' + }, + { + indexed: false, + internalType: 'address payable', + name: 'refundReceiver', + type: 'address' + }, + { + indexed: false, + internalType: 'bytes', + name: 'signatures', + type: 'bytes' + }, + { + indexed: false, + internalType: 'bytes', + name: 'additionalInfo', + type: 'bytes' + } + ], + name: 'SafeMultiSigTransaction', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address' + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256' + } + ], + name: 'SafeReceived', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'initiator', + type: 'address' + }, + { + indexed: false, + internalType: 'address[]', + name: 'owners', + type: 'address[]' + }, + { + indexed: false, + internalType: 'uint256', + name: 'threshold', + type: 'uint256' + }, + { + indexed: false, + internalType: 'address', + name: 'initializer', + type: 'address' + }, + { + indexed: false, + internalType: 'address', + name: 'fallbackHandler', + type: 'address' + } + ], + name: 'SafeSetup', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: 'msgHash', + type: 'bytes32' + } + ], + name: 'SignMsg', + type: 'event' + }, + { + stateMutability: 'nonpayable', + type: 'fallback' + }, + { + inputs: [], + name: 'VERSION', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address' + }, + { + internalType: 'uint256', + name: '_threshold', + type: 'uint256' + } + ], + name: 'addOwnerWithThreshold', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'hashToApprove', + type: 'bytes32' + } + ], + name: 'approveHash', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + name: 'approvedHashes', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_threshold', + type: 'uint256' + } + ], + name: 'changeThreshold', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'dataHash', + type: 'bytes32' + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes' + }, + { + internalType: 'bytes', + name: 'signatures', + type: 'bytes' + }, + { + internalType: 'uint256', + name: 'requiredSignatures', + type: 'uint256' + } + ], + name: 'checkNSignatures', + outputs: [], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'dataHash', + type: 'bytes32' + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes' + }, + { + internalType: 'bytes', + name: 'signatures', + type: 'bytes' + } + ], + name: 'checkSignatures', + outputs: [], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'prevModule', + type: 'address' + }, + { + internalType: 'address', + name: 'module', + type: 'address' + } + ], + name: 'disableModule', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [], + name: 'domainSeparator', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'module', + type: 'address' + } + ], + name: 'enableModule', + outputs: [], + 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: 'safeTxGas', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'baseGas', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'gasPrice', + type: 'uint256' + }, + { + internalType: 'address', + name: 'gasToken', + type: 'address' + }, + { + internalType: 'address', + name: 'refundReceiver', + type: 'address' + }, + { + internalType: 'uint256', + name: '_nonce', + type: 'uint256' + } + ], + name: 'encodeTransactionData', + outputs: [ + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + 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: 'operation', + type: 'uint8' + }, + { + internalType: 'uint256', + name: 'safeTxGas', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'baseGas', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'gasPrice', + type: 'uint256' + }, + { + internalType: 'address', + name: 'gasToken', + type: 'address' + }, + { + internalType: 'address payable', + name: 'refundReceiver', + type: 'address' + }, + { + internalType: 'bytes', + name: 'signatures', + type: 'bytes' + } + ], + name: 'execTransaction', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool' + } + ], + stateMutability: 'payable', + 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: '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: 'execTransactionFromModuleReturnData', + outputs: [ + { + internalType: 'bool', + name: 'success', + type: 'bool' + }, + { + internalType: 'bytes', + name: 'returnData', + type: 'bytes' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [], + name: 'getChainId', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + 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: [], + name: 'getOwners', + outputs: [ + { + internalType: 'address[]', + name: '', + type: 'address[]' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'offset', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'length', + type: 'uint256' + } + ], + name: 'getStorageAt', + outputs: [ + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'getThreshold', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + 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: 'operation', + type: 'uint8' + }, + { + internalType: 'uint256', + name: 'safeTxGas', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'baseGas', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'gasPrice', + type: 'uint256' + }, + { + internalType: 'address', + name: 'gasToken', + type: 'address' + }, + { + internalType: 'address', + name: 'refundReceiver', + type: 'address' + }, + { + internalType: 'uint256', + name: '_nonce', + type: 'uint256' + } + ], + name: 'getTransactionHash', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'module', + type: 'address' + } + ], + name: 'isModuleEnabled', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address' + } + ], + name: 'isOwner', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'nonce', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'prevOwner', + type: 'address' + }, + { + internalType: 'address', + name: 'owner', + type: 'address' + }, + { + internalType: 'uint256', + name: '_threshold', + type: 'uint256' + } + ], + name: 'removeOwner', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'handler', + type: 'address' + } + ], + name: 'setFallbackHandler', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'guard', + type: 'address' + } + ], + name: 'setGuard', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address[]', + name: '_owners', + type: 'address[]' + }, + { + internalType: 'uint256', + name: '_threshold', + type: 'uint256' + }, + { + internalType: 'address', + name: 'to', + type: 'address' + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes' + }, + { + internalType: 'address', + name: 'fallbackHandler', + type: 'address' + }, + { + internalType: 'address', + name: 'paymentToken', + type: 'address' + }, + { + internalType: 'uint256', + name: 'payment', + type: 'uint256' + }, + { + internalType: 'address payable', + name: 'paymentReceiver', + type: 'address' + } + ], + name: 'setup', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + name: 'signedMessages', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'targetContract', + type: 'address' + }, + { + internalType: 'bytes', + name: 'calldataPayload', + type: 'bytes' + } + ], + name: 'simulateAndRevert', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'prevOwner', + type: 'address' + }, + { + internalType: 'address', + name: 'oldOwner', + type: 'address' + }, + { + internalType: 'address', + name: 'newOwner', + type: 'address' + } + ], + name: 'swapOwner', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + stateMutability: 'payable', + type: 'receive' + } + ] +} as const diff --git a/packages/safe-core-sdk-types/src/contracts/assets/SafeProxyFactory/v1.0.0/proxy_factory.ts b/packages/safe-core-sdk-types/src/contracts/assets/SafeProxyFactory/v1.0.0/proxy_factory.ts new file mode 100644 index 000000000..de95560e9 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/assets/SafeProxyFactory/v1.0.0/proxy_factory.ts @@ -0,0 +1,96 @@ +export default { + contractName: 'ProxyFactory', + version: '1.0.0', + abi: [ + { + constant: false, + inputs: [ + { + name: '_mastercopy', + type: 'address' + }, + { + name: 'initializer', + type: 'bytes' + }, + { + name: 'saltNonce', + type: 'uint256' + } + ], + name: 'createProxyWithNonce', + outputs: [ + { + name: 'proxy', + type: 'address' + } + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'proxyCreationCode', + outputs: [ + { + name: '', + type: 'bytes' + } + ], + payable: false, + stateMutability: 'pure', + type: 'function' + }, + { + constant: false, + inputs: [ + { + name: 'masterCopy', + type: 'address' + }, + { + name: 'data', + type: 'bytes' + } + ], + name: 'createProxy', + outputs: [ + { + name: 'proxy', + type: 'address' + } + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'proxyRuntimeCode', + outputs: [ + { + name: '', + type: 'bytes' + } + ], + payable: false, + stateMutability: 'pure', + type: 'function' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + name: 'proxy', + type: 'address' + } + ], + name: 'ProxyCreation', + type: 'event' + } + ] +} as const diff --git a/packages/safe-core-sdk-types/src/contracts/assets/SafeProxyFactory/v1.1.1/proxy_factory.ts b/packages/safe-core-sdk-types/src/contracts/assets/SafeProxyFactory/v1.1.1/proxy_factory.ts new file mode 100644 index 000000000..f522fb746 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/assets/SafeProxyFactory/v1.1.1/proxy_factory.ts @@ -0,0 +1,173 @@ +export default { + contractName: 'ProxyFactory', + version: '1.1.1', + abi: [ + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract GnosisSafeProxy', + name: 'proxy', + type: 'address' + } + ], + name: 'ProxyCreation', + type: 'event' + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'masterCopy', + type: 'address' + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes' + } + ], + name: 'createProxy', + outputs: [ + { + internalType: 'contract GnosisSafeProxy', + name: 'proxy', + type: 'address' + } + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'proxyRuntimeCode', + outputs: [ + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + payable: false, + stateMutability: 'pure', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'proxyCreationCode', + outputs: [ + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + payable: false, + stateMutability: 'pure', + type: 'function' + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: '_mastercopy', + type: 'address' + }, + { + internalType: 'bytes', + name: 'initializer', + type: 'bytes' + }, + { + internalType: 'uint256', + name: 'saltNonce', + type: 'uint256' + } + ], + name: 'createProxyWithNonce', + outputs: [ + { + internalType: 'contract GnosisSafeProxy', + name: 'proxy', + type: 'address' + } + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: '_mastercopy', + type: 'address' + }, + { + internalType: 'bytes', + name: 'initializer', + type: 'bytes' + }, + { + internalType: 'uint256', + name: 'saltNonce', + type: 'uint256' + }, + { + internalType: 'contract IProxyCreationCallback', + name: 'callback', + type: 'address' + } + ], + name: 'createProxyWithCallback', + outputs: [ + { + internalType: 'contract GnosisSafeProxy', + name: 'proxy', + type: 'address' + } + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: '_mastercopy', + type: 'address' + }, + { + internalType: 'bytes', + name: 'initializer', + type: 'bytes' + }, + { + internalType: 'uint256', + name: 'saltNonce', + type: 'uint256' + } + ], + name: 'calculateCreateProxyWithNonceAddress', + outputs: [ + { + internalType: 'contract GnosisSafeProxy', + name: 'proxy', + type: 'address' + } + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + } + ] +} as const diff --git a/packages/safe-core-sdk-types/src/contracts/assets/SafeProxyFactory/v1.3.0/proxy_factory.ts b/packages/safe-core-sdk-types/src/contracts/assets/SafeProxyFactory/v1.3.0/proxy_factory.ts new file mode 100644 index 000000000..270f7d79b --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/assets/SafeProxyFactory/v1.3.0/proxy_factory.ts @@ -0,0 +1,167 @@ +export default { + contractName: 'GnosisSafeProxyFactory', + version: '1.3.0', + abi: [ + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract GnosisSafeProxy', + name: 'proxy', + type: 'address' + }, + { + indexed: false, + internalType: 'address', + name: 'singleton', + type: 'address' + } + ], + name: 'ProxyCreation', + type: 'event' + }, + { + inputs: [ + { + internalType: 'address', + name: '_singleton', + type: 'address' + }, + { + internalType: 'bytes', + name: 'initializer', + type: 'bytes' + }, + { + internalType: 'uint256', + name: 'saltNonce', + type: 'uint256' + } + ], + name: 'calculateCreateProxyWithNonceAddress', + outputs: [ + { + internalType: 'contract GnosisSafeProxy', + name: 'proxy', + type: 'address' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'singleton', + type: 'address' + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes' + } + ], + name: 'createProxy', + outputs: [ + { + internalType: 'contract GnosisSafeProxy', + name: 'proxy', + type: 'address' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '_singleton', + type: 'address' + }, + { + internalType: 'bytes', + name: 'initializer', + type: 'bytes' + }, + { + internalType: 'uint256', + name: 'saltNonce', + type: 'uint256' + }, + { + internalType: 'contract IProxyCreationCallback', + name: 'callback', + type: 'address' + } + ], + name: 'createProxyWithCallback', + outputs: [ + { + internalType: 'contract GnosisSafeProxy', + name: 'proxy', + type: 'address' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '_singleton', + type: 'address' + }, + { + internalType: 'bytes', + name: 'initializer', + type: 'bytes' + }, + { + internalType: 'uint256', + name: 'saltNonce', + type: 'uint256' + } + ], + name: 'createProxyWithNonce', + outputs: [ + { + internalType: 'contract GnosisSafeProxy', + name: 'proxy', + type: 'address' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [], + name: 'proxyCreationCode', + outputs: [ + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + stateMutability: 'pure', + type: 'function' + }, + { + inputs: [], + name: 'proxyRuntimeCode', + outputs: [ + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + stateMutability: 'pure', + type: 'function' + } + ] +} as const diff --git a/packages/safe-core-sdk-types/src/contracts/assets/SafeProxyFactory/v1.4.1/safe_proxy_factory.ts b/packages/safe-core-sdk-types/src/contracts/assets/SafeProxyFactory/v1.4.1/safe_proxy_factory.ts new file mode 100644 index 000000000..86816ec22 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/assets/SafeProxyFactory/v1.4.1/safe_proxy_factory.ts @@ -0,0 +1,143 @@ +export default { + contractName: 'SafeProxyFactory', + version: '1.4.1', + abi: [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract SafeProxy', + name: 'proxy', + type: 'address' + }, + { + indexed: false, + internalType: 'address', + name: 'singleton', + type: 'address' + } + ], + name: 'ProxyCreation', + type: 'event' + }, + { + inputs: [ + { + internalType: 'address', + name: '_singleton', + type: 'address' + }, + { + internalType: 'bytes', + name: 'initializer', + type: 'bytes' + }, + { + internalType: 'uint256', + name: 'saltNonce', + type: 'uint256' + } + ], + name: 'createChainSpecificProxyWithNonce', + outputs: [ + { + internalType: 'contract SafeProxy', + name: 'proxy', + type: 'address' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '_singleton', + type: 'address' + }, + { + internalType: 'bytes', + name: 'initializer', + type: 'bytes' + }, + { + internalType: 'uint256', + name: 'saltNonce', + type: 'uint256' + }, + { + internalType: 'contract IProxyCreationCallback', + name: 'callback', + type: 'address' + } + ], + name: 'createProxyWithCallback', + outputs: [ + { + internalType: 'contract SafeProxy', + name: 'proxy', + type: 'address' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '_singleton', + type: 'address' + }, + { + internalType: 'bytes', + name: 'initializer', + type: 'bytes' + }, + { + internalType: 'uint256', + name: 'saltNonce', + type: 'uint256' + } + ], + name: 'createProxyWithNonce', + outputs: [ + { + internalType: 'contract SafeProxy', + name: 'proxy', + type: 'address' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [], + name: 'getChainId', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'proxyCreationCode', + outputs: [ + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + stateMutability: 'pure', + type: 'function' + } + ] +} as const diff --git a/packages/safe-core-sdk-types/src/contracts/assets/SignMessageLib/v1.3.0/sign_message_lib.ts b/packages/safe-core-sdk-types/src/contracts/assets/SignMessageLib/v1.3.0/sign_message_lib.ts new file mode 100644 index 000000000..4ecbaf916 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/assets/SignMessageLib/v1.3.0/sign_message_lib.ts @@ -0,0 +1,52 @@ +// Source: https://github.com/safe-global/safe-deployments/blob/main/src/assets/v1.3.0/sign_message_lib.json +export default { + contractName: 'SignMessageLib', + version: '1.3.0', + abi: [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: 'msgHash', + type: 'bytes32' + } + ], + name: 'SignMsg', + type: 'event' + }, + { + inputs: [ + { + internalType: 'bytes', + name: 'message', + type: 'bytes' + } + ], + name: 'getMessageHash', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_data', + type: 'bytes' + } + ], + name: 'signMessage', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + } + ] +} as const diff --git a/packages/safe-core-sdk-types/src/contracts/assets/SignMessageLib/v1.4.1/sign_message_lib.ts b/packages/safe-core-sdk-types/src/contracts/assets/SignMessageLib/v1.4.1/sign_message_lib.ts new file mode 100644 index 000000000..50ed37ae0 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/assets/SignMessageLib/v1.4.1/sign_message_lib.ts @@ -0,0 +1,52 @@ +// Source: https://github.com/safe-global/safe-deployments/blob/main/src/assets/v1.4.1/sign_message_lib.json +export default { + contractName: 'SignMessageLib', + version: '1.4.1', + abi: [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: 'msgHash', + type: 'bytes32' + } + ], + name: 'SignMsg', + type: 'event' + }, + { + inputs: [ + { + internalType: 'bytes', + name: 'message', + type: 'bytes' + } + ], + name: 'getMessageHash', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_data', + type: 'bytes' + } + ], + name: 'signMessage', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + } + ] +} as const diff --git a/packages/safe-core-sdk-types/src/contracts/assets/SimulateTxAccessor/v1.3.0/simulate_tx_accessor.ts b/packages/safe-core-sdk-types/src/contracts/assets/SimulateTxAccessor/v1.3.0/simulate_tx_accessor.ts new file mode 100644 index 000000000..c779e9c12 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/assets/SimulateTxAccessor/v1.3.0/simulate_tx_accessor.ts @@ -0,0 +1,56 @@ +// Source: https://github.com/safe-global/safe-deployments/blob/main/src/assets/v1.3.0/simulate_tx_accessor.json +export default { + contractName: 'SimulateTxAccessor', + version: '1.3.0', + abi: [ + { + inputs: [], + stateMutability: 'nonpayable', + type: 'constructor' + }, + { + 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: 'simulate', + outputs: [ + { + internalType: 'uint256', + name: 'estimate', + type: 'uint256' + }, + { + internalType: 'bool', + name: 'success', + type: 'bool' + }, + { + internalType: 'bytes', + name: 'returnData', + type: 'bytes' + } + ], + stateMutability: 'nonpayable', + type: 'function' + } + ] +} as const diff --git a/packages/safe-core-sdk-types/src/contracts/assets/SimulateTxAccessor/v1.4.1/simulate_tx_accessor.ts b/packages/safe-core-sdk-types/src/contracts/assets/SimulateTxAccessor/v1.4.1/simulate_tx_accessor.ts new file mode 100644 index 000000000..ce2d2c4d7 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/assets/SimulateTxAccessor/v1.4.1/simulate_tx_accessor.ts @@ -0,0 +1,56 @@ +// Source: https://github.com/safe-global/safe-deployments/blob/main/src/assets/v1.4.1/simulate_tx_accessor.json +export default { + contractName: 'SimulateTxAccessor', + version: '1.4.1', + abi: [ + { + inputs: [], + stateMutability: 'nonpayable', + type: 'constructor' + }, + { + 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: 'simulate', + outputs: [ + { + internalType: 'uint256', + name: 'estimate', + type: 'uint256' + }, + { + internalType: 'bool', + name: 'success', + type: 'bool' + }, + { + internalType: 'bytes', + name: 'returnData', + type: 'bytes' + } + ], + stateMutability: 'nonpayable', + type: 'function' + } + ] +} as const diff --git a/packages/safe-core-sdk-types/src/contracts/assets/index.ts b/packages/safe-core-sdk-types/src/contracts/assets/index.ts new file mode 100644 index 000000000..0f9a997e0 --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/assets/index.ts @@ -0,0 +1,54 @@ +import compatibilityFallbackHandler_1_3_0_ContractArtifacts from './CompatibilityFallbackHandler/v1.3.0/compatibility_fallback_handler' +import compatibilityFallbackHandler_1_4_1_ContractArtifacts from './CompatibilityFallbackHandler/v1.4.1/compatibility_fallback_handler' + +import createCall_1_3_0_ContractArtifacts from './CreateCall/v1.3.0/create_call' +import createCall_1_4_1_ContractArtifacts from './CreateCall/v1.4.1/create_call' + +import multisend_1_1_1_ContractArtifacts from './MultiSend/v1.1.1/multi_send' +import multisend_1_3_0_ContractArtifacts from './MultiSend/v1.3.0/multi_send' +import multisend_1_4_1_ContractArtifacts from './MultiSend/v1.4.1/multi_send' + +import multiSendCallOnly_1_3_0_ContractArtifacts from './MultiSend/v1.3.0/multi_send_call_only' +import multiSendCallOnly_1_4_1_ContractArtifacts from './MultiSend/v1.4.1/multi_send_call_only' + +import safe_1_0_0_ContractArtifacts from './Safe/v1.0.0/gnosis_safe' +import safe_1_1_1_ContractArtifacts from './Safe/v1.1.1/gnosis_safe' +import safe_1_2_0_ContractArtifacts from './Safe/v1.2.0/gnosis_safe' +import safe_1_3_0_ContractArtifacts from './Safe/v1.3.0/gnosis_safe_l2' +import safe_1_4_1_ContractArtifacts from './Safe/v1.4.1/safe_l2' + +import safeProxyFactory_1_0_0_ContractArtifacts from './SafeProxyFactory/v1.0.0/proxy_factory' +import safeProxyFactory_1_1_1_ContractArtifacts from './SafeProxyFactory/v1.1.1/proxy_factory' +import safeProxyFactory_1_3_0_ContractArtifacts from './SafeProxyFactory/v1.3.0/proxy_factory' +import safeProxyFactory_1_4_1_ContractArtifacts from './SafeProxyFactory/v1.4.1/safe_proxy_factory' + +import signMessageLib_1_3_0_ContractArtifacts from './SignMessageLib/v1.3.0/sign_message_lib' +import signMessageLib_1_4_1_ContractArtifacts from './SignMessageLib/v1.4.1/sign_message_lib' + +import simulateTxAccessor_1_3_0_ContractArtifacts from './SimulateTxAccessor/v1.3.0/simulate_tx_accessor' +import simulateTxAccessor_1_4_1_ContractArtifacts from './SimulateTxAccessor/v1.4.1/simulate_tx_accessor' + +export { + compatibilityFallbackHandler_1_3_0_ContractArtifacts, + compatibilityFallbackHandler_1_4_1_ContractArtifacts, + createCall_1_3_0_ContractArtifacts, + createCall_1_4_1_ContractArtifacts, + multisend_1_1_1_ContractArtifacts, + multisend_1_3_0_ContractArtifacts, + multiSendCallOnly_1_3_0_ContractArtifacts, + multisend_1_4_1_ContractArtifacts, + multiSendCallOnly_1_4_1_ContractArtifacts, + safe_1_0_0_ContractArtifacts, + safe_1_1_1_ContractArtifacts, + safe_1_2_0_ContractArtifacts, + safe_1_3_0_ContractArtifacts, + safe_1_4_1_ContractArtifacts, + safeProxyFactory_1_0_0_ContractArtifacts, + safeProxyFactory_1_1_1_ContractArtifacts, + safeProxyFactory_1_3_0_ContractArtifacts, + safeProxyFactory_1_4_1_ContractArtifacts, + signMessageLib_1_3_0_ContractArtifacts, + signMessageLib_1_4_1_ContractArtifacts, + simulateTxAccessor_1_3_0_ContractArtifacts, + simulateTxAccessor_1_4_1_ContractArtifacts +} diff --git a/packages/safe-core-sdk-types/src/contracts/common/BaseContract.ts b/packages/safe-core-sdk-types/src/contracts/common/BaseContract.ts new file mode 100644 index 000000000..a71fdb40b --- /dev/null +++ b/packages/safe-core-sdk-types/src/contracts/common/BaseContract.ts @@ -0,0 +1,141 @@ +import { + Abi, + AbiParametersToPrimitiveTypes, + ExtractAbiFunction, + ExtractAbiFunctionNames +} from 'abitype' +import { + SafeVersion, + TransactionOptions, + TransactionResult +} from '@safe-global/safe-core-sdk-types/types' + +/** + * Extracts the names of read-only functions (view or pure) from a given contract ABI. + * + * @template ContractAbi - The ABI of the contract. + * @type {ContractReadFunctionNames} + */ +export type ContractReadFunctionNames = ExtractAbiFunctionNames< + ContractAbi, + 'view' | 'pure' +> + +/** + * Extracts the names of write functions (nonpayable or payable) from a given contract ABI. + * + * @template ContractAbi - The ABI of the contract. + * @type {ContractWriteFunctionNames} + */ +export type ContractWriteFunctionNames = ExtractAbiFunctionNames< + ContractAbi, + 'nonpayable' | 'payable' +> + +/** + * Extracts the function arguments from a given contract ABI and function name. + * + * @template ContractAbi - The ABI of the contract. + * @template ContractFunctionName - The function name to extract arguments from, derived from the ABI. + * @template ArgType - The type of arguments to extract, either 'inputs' or 'outputs'. (default: 'inputs') + * @type {ExtractFunctionArgs} + */ +type ExtractFunctionArgs< + ContractAbi extends Abi, + ContractFunctionName extends + ExtractAbiFunctionNames = ExtractAbiFunctionNames, + ArgType extends 'inputs' | 'outputs' = 'inputs' +> = AbiParametersToPrimitiveTypes< + ExtractAbiFunction[ArgType], + ArgType +> + +/** + * Encodes a function call for a contract. + * + * @template ContractAbi - The ABI of the contract. + * @template ContractFunctionName - The function name to encode, derived from the ABI. + */ +export type EncodeFunction< + ContractAbi extends Abi, + ContractFunctionName extends + ExtractAbiFunctionNames = ExtractAbiFunctionNames +> = ( + functionToEncode: ContractFunctionName, + args: ExtractFunctionArgs +) => string + +/** + * Estimates the gas required for a function call on a contract. + * + * @template ContractAbi - The ABI of the contract. + * @template ContractFunctionName - The function for which gas is being estimated, derived from the ABI. + */ +export type EstimateGasFunction< + ContractAbi extends Abi, + ContractFunctionName extends + ExtractAbiFunctionNames = ExtractAbiFunctionNames +> = ( + functionToEncode: ContractFunctionName, + args: ExtractFunctionArgs, + options?: TransactionOptions +) => Promise + +export type GetAddressFunction = () => Promise + +/** + * Defines a function type for a contract, derived by the given function name from a given contract ABI. + * + * @template ContractAbi - The ABI of the contract. + * @template ContractFunctionName - The function name, derived from the ABI. + */ +export type ContractFunction< + ContractAbi extends Abi, + ContractFunctionName extends + ExtractAbiFunctionNames = ExtractAbiFunctionNames +> = ( + // input parameters (only if function has inputs, otherwise no parameters) + ...args: ExtractFunctionArgs['length'] extends 0 + ? [] + : [ExtractFunctionArgs] + // returned values as a Promise +) => Promise> + +/** + * Defines an adapter-specific function type for a contract, derived by the given function name from a given contract ABI. + * + * @template ContractAbi - The ABI of the contract. + * @template ContractFunctionName - The function name, derived from the ABI. + */ +export type SafeContractFunction< + ContractAbi extends Abi, + ContractFunctionName extends + ExtractAbiFunctionNames = ExtractAbiFunctionNames +> = ( + args: AbiParametersToPrimitiveTypes< + ExtractAbiFunction['inputs'] + >, + options?: TransactionOptions +) => Promise + +/** + * Represents the base contract type for a contract. + * + * @template ContractAbi - The ABI of the contract. + * @template ContractFunctionNames - The function names, derived from the ABI. + * @type {BaseContract} + */ +type BaseContract< + ContractAbi extends Abi, + ContractFunctionNames extends ExtractAbiFunctionNames = + | ContractReadFunctionNames + | ContractWriteFunctionNames +> = { + [FunctionName in ContractFunctionNames]: ContractFunction +} & { + safeVersion: SafeVersion + encode: EncodeFunction + getAddress: GetAddressFunction +} + +export default BaseContract diff --git a/packages/safe-core-sdk-types/src/ethereumLibs/EthAdapter.ts b/packages/safe-core-sdk-types/src/ethereumLibs/EthAdapter.ts deleted file mode 100644 index 92f6d19e5..000000000 --- a/packages/safe-core-sdk-types/src/ethereumLibs/EthAdapter.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { CompatibilityFallbackHandlerContract } from '@safe-global/safe-core-sdk-types/contracts/CompatibilityFallbackHandlerContract' -import { CreateCallContract } from '@safe-global/safe-core-sdk-types/contracts/CreateCallContract' -import { MultiSendCallOnlyContract } from '@safe-global/safe-core-sdk-types/contracts/MultiSendCallOnlyContract' -import { MultiSendContract } from '@safe-global/safe-core-sdk-types/contracts/MultiSendContract' -import { SafeContract } from '@safe-global/safe-core-sdk-types/contracts/SafeContract' -import { SafeProxyFactoryContract } from '@safe-global/safe-core-sdk-types/contracts/SafeProxyFactoryContract' -import { SignMessageLibContract } from '@safe-global/safe-core-sdk-types/contracts/SignMessageLibContract' -import { SimulateTxAccessorContract } from '@safe-global/safe-core-sdk-types/contracts/SimulateTxAccessorContract' -import { Eip3770Address, SafeEIP712Args, SafeVersion } from '@safe-global/safe-core-sdk-types/types' -import { SingletonDeployment } from '@safe-global/safe-deployments' -import { AbiItem } from 'web3-utils' - -export interface EthAdapterTransaction { - to: string - from: string - data: string - value?: string - gasPrice?: number | string - gasLimit?: number | string - maxFeePerGas?: number | string - maxPriorityFeePerGas?: number | string -} - -export interface GetContractProps { - safeVersion: SafeVersion - singletonDeployment?: SingletonDeployment - customContractAddress?: string - customContractAbi?: AbiItem | AbiItem[] -} - -export interface EthAdapter { - isAddress(address: string): boolean - getEip3770Address(fullAddress: string): Promise - getBalance(address: string, defaultBlock?: string | number): Promise - getNonce(address: string, defaultBlock?: string | number): Promise - getChainId(): Promise - getChecksummedAddress(address: string): string - getSafeContract({ - safeVersion, - singletonDeployment, - customContractAddress, - customContractAbi - }: GetContractProps): Promise - getMultiSendContract({ - safeVersion, - singletonDeployment, - customContractAddress, - customContractAbi - }: GetContractProps): Promise - getMultiSendCallOnlyContract({ - safeVersion, - singletonDeployment, - customContractAddress, - customContractAbi - }: GetContractProps): Promise - getCompatibilityFallbackHandlerContract({ - safeVersion, - singletonDeployment, - customContractAddress, - customContractAbi - }: GetContractProps): Promise - getSafeProxyFactoryContract({ - safeVersion, - singletonDeployment, - customContractAddress, - customContractAbi - }: GetContractProps): Promise - getSignMessageLibContract({ - safeVersion, - singletonDeployment, - customContractAddress, - customContractAbi - }: GetContractProps): Promise - getCreateCallContract({ - safeVersion, - singletonDeployment, - customContractAddress, - customContractAbi - }: GetContractProps): Promise - getSimulateTxAccessorContract({ - safeVersion, - singletonDeployment, - customContractAddress, - customContractAbi - }: GetContractProps): Promise - getContractCode(address: string, defaultBlock?: string | number): Promise - isContractDeployed(address: string, defaultBlock?: string | number): Promise - getStorageAt(address: string, position: string): Promise - getTransaction(transactionHash: string): Promise - getSignerAddress(): Promise - signMessage(message: string): Promise - signTypedData(safeEIP712Args: SafeEIP712Args, signTypedDataVersion?: string): Promise - estimateGas( - transaction: EthAdapterTransaction, - callback?: (error: Error, gas: number) => void - ): Promise - call(transaction: EthAdapterTransaction, defaultBlock?: string | number): Promise - encodeParameters(types: string[], values: any[]): string - decodeParameters(types: any[], values: string): { [key: string]: any } -} diff --git a/packages/safe-core-sdk-types/src/index.ts b/packages/safe-core-sdk-types/src/index.ts index 119efb939..ef9abd2ee 100644 --- a/packages/safe-core-sdk-types/src/index.ts +++ b/packages/safe-core-sdk-types/src/index.ts @@ -1,10 +1,26 @@ -export * from './contracts/CompatibilityFallbackHandlerContract' -export * from './contracts/CreateCallContract' -export * from './contracts/MultiSendCallOnlyContract' -export * from './contracts/MultiSendContract' -export * from './contracts/SafeContract' -export * from './contracts/SafeProxyFactoryContract' -export * from './contracts/SignMessageLibContract' -export * from './contracts/SimulateTxAccessorContract' -export * from './ethereumLibs/EthAdapter' +export * from './contracts/CompatibilityFallbackHandler' +export * from './contracts/MultiSend' +export * from './contracts/CreateCall' +export * from './contracts/Safe' +export * from './contracts/SafeProxyFactory' +export * from './contracts/SignMessageLib' +export * from './contracts/SimulateTxAccessor' +export * from './contracts/common/BaseContract' +export * from './contracts/assets' export * from './types' + +// see docs: https://abitype.dev/config +declare module 'abitype' { + export interface Register { + // AddressType: `0x${string}` + // BytesType: { + // inputs: `0x${string}` | Uint8Array + // outputs: `0x${string}` + // } + AddressType: string + BytesType: { + inputs: string + outputs: string + } + } +} diff --git a/packages/safe-core-sdk-types/src/types.ts b/packages/safe-core-sdk-types/src/types.ts index 30eb4e7e8..62634abf5 100644 --- a/packages/safe-core-sdk-types/src/types.ts +++ b/packages/safe-core-sdk-types/src/types.ts @@ -1,6 +1,3 @@ -import { ContractTransactionResponse } from 'ethers' -import { PromiEvent, TransactionReceipt } from 'web3-core/types' - export type SafeVersion = '1.4.1' | '1.3.0' | '1.2.0' | '1.1.1' | '1.0.0' export enum OperationType { @@ -8,6 +5,14 @@ export enum OperationType { DelegateCall // 1 } +export interface CreateProxyProps { + safeSingletonAddress: string + initializer: string + saltNonce: string + options?: TransactionOptions + callback?: (txHash: string) => void +} + export interface SafeSetupConfig { owners: string[] threshold: number @@ -78,7 +83,6 @@ interface TransactionBase { export interface TransactionOptions { from?: string - gas?: number | string gasLimit?: number | string gasPrice?: number | string maxFeePerGas?: number | string @@ -91,8 +95,7 @@ export interface BaseTransactionResult { } export interface TransactionResult extends BaseTransactionResult { - promiEvent?: PromiEvent - transactionResponse?: ContractTransactionResponse + transactionResponse: unknown options?: TransactionOptions } diff --git a/playground/README.md b/playground/README.md index c8d8a2a18..8558750a2 100644 --- a/playground/README.md +++ b/playground/README.md @@ -2,7 +2,7 @@ This playground contains several scripts that can be used as a starting point to use the Safe{Core} SDK. These scripts do not cover all the functionality exposed by the SDK but showcase some steps of the Safe transaction flow. -Before starting, make sure to install and build the Safe{Core} SDK monorepo. +Before starting, make sure to install and build the Safe{Core} SDK monorepo. From the project root, run: ```bash yarn install diff --git a/playground/api-kit/confirm-transaction.ts b/playground/api-kit/confirm-transaction.ts index 8e4b0ccaf..14a4fead3 100644 --- a/playground/api-kit/confirm-transaction.ts +++ b/playground/api-kit/confirm-transaction.ts @@ -1,6 +1,5 @@ +import Safe from '@safe-global/protocol-kit' import SafeApiKit from '@safe-global/api-kit' -import Safe, { EthersAdapter } from '@safe-global/protocol-kit' -import { ethers } from 'ethers' // This file can be used to play around with the Safe Core SDK @@ -14,48 +13,34 @@ interface Config { const config: Config = { CHAIN_ID: 11155111n, - RPC_URL: 'https://rpc.ankr.com/eth_sepolia', + RPC_URL: 'https://sepolia.gateway.tenderly.co', SIGNER_ADDRESS_PRIVATE_KEY: '', SAFE_ADDRESS: '', SAFE_TX_HASH: '' } async function main() { - const provider = new ethers.JsonRpcProvider(config.RPC_URL) - const signer = new ethers.Wallet(config.SIGNER_ADDRESS_PRIVATE_KEY, provider) - - // Create EthAdapter instance - const ethAdapter = new EthersAdapter({ - ethers, - signerOrProvider: signer - }) - // Create Safe instance - const safe = await Safe.create({ - ethAdapter, + const protocolKit = await Safe.init({ + provider: config.RPC_URL, + signer: config.SIGNER_ADDRESS_PRIVATE_KEY, safeAddress: config.SAFE_ADDRESS }) // Create Safe API Kit instance - const service = new SafeApiKit({ + const apiKit = new SafeApiKit({ chainId: config.CHAIN_ID }) // Get the transaction - const transaction = await service.getTransaction(config.SAFE_TX_HASH) - // const transactions = await service.getPendingTransactions() - // const transactions = await service.getIncomingTransactions() - // const transactions = await service.getMultisigTransactions() - // const transactions = await service.getModuleTransactions() - // const transactions = await service.getAllTransactions() - - const safeTxHash = transaction.transactionHash - const signature = await safe.signHash(safeTxHash) + const safeTransaction = await apiKit.getTransaction(config.SAFE_TX_HASH) + const safeTxHash = safeTransaction.safeTxHash + const signature = await protocolKit.signHash(safeTxHash) // Confirm the Safe transaction - const signatureResponse = await service.confirmTransaction(safeTxHash, signature.data) + const signatureResponse = await apiKit.confirmTransaction(safeTxHash, signature.data) - const signerAddress = await signer.getAddress() + const signerAddress = await protocolKit.getSafeProvider().getSignerAddress() console.log('Added a new signature to transaction with safeTxGas:', config.SAFE_TX_HASH) console.log('- Signer:', signerAddress) console.log('- Signer signature:', signatureResponse.signature) diff --git a/playground/api-kit/execute-transaction.ts b/playground/api-kit/execute-transaction.ts index 039b2b807..f6ec77c57 100644 --- a/playground/api-kit/execute-transaction.ts +++ b/playground/api-kit/execute-transaction.ts @@ -1,6 +1,5 @@ +import Safe from '@safe-global/protocol-kit' import SafeApiKit from '@safe-global/api-kit' -import Safe, { EthersAdapter } from '@safe-global/protocol-kit' -import { ethers } from 'ethers' // This file can be used to play around with the Safe Core SDK @@ -14,45 +13,36 @@ interface Config { const config: Config = { CHAIN_ID: 11155111n, - RPC_URL: 'https://rpc.ankr.com/eth_sepolia', + RPC_URL: 'https://sepolia.gateway.tenderly.co', SIGNER_ADDRESS_PRIVATE_KEY: '', SAFE_ADDRESS: '', SAFE_TX_HASH: '' } async function main() { - const provider = new ethers.JsonRpcProvider(config.RPC_URL) - const signer = new ethers.Wallet(config.SIGNER_ADDRESS_PRIVATE_KEY, provider) - - // Create EthAdapter instance - const ethAdapter = new EthersAdapter({ - ethers, - signerOrProvider: signer - }) - // Create Safe instance - const safe = await Safe.create({ - ethAdapter, + const protocolKit = await Safe.init({ + provider: config.RPC_URL, + signer: config.SIGNER_ADDRESS_PRIVATE_KEY, safeAddress: config.SAFE_ADDRESS }) // Create Safe API Kit instance - const service = new SafeApiKit({ + const apiKit = new SafeApiKit({ chainId: config.CHAIN_ID }) // Get the transaction - const safeTransaction = await service.getTransaction(config.SAFE_TX_HASH) - - const isTxExecutable = await safe.isValidTransaction(safeTransaction) + const safeTransaction = await apiKit.getTransaction(config.SAFE_TX_HASH) + const isTxExecutable = await protocolKit.isValidTransaction(safeTransaction) if (isTxExecutable) { // Execute the transaction - const txResponse = await safe.executeTransaction(safeTransaction) + const txResponse = await protocolKit.executeTransaction(safeTransaction) const contractReceipt = await txResponse.transactionResponse?.wait() console.log('Transaction executed.') - console.log('- Transaction hash:', contractReceipt?.transactionHash) + console.log('- Transaction hash:', contractReceipt?.hash) } else { console.log('Transaction invalid. Transaction was not executed.') } diff --git a/playground/api-kit/propose-transaction.ts b/playground/api-kit/propose-transaction.ts index 279584f41..f2f3ca7c5 100644 --- a/playground/api-kit/propose-transaction.ts +++ b/playground/api-kit/propose-transaction.ts @@ -1,7 +1,6 @@ +import Safe from '@safe-global/protocol-kit' import SafeApiKit from '@safe-global/api-kit' -import Safe, { EthersAdapter } from '@safe-global/protocol-kit' import { OperationType, SafeTransactionDataPartial } from '@safe-global/safe-core-sdk-types' -import { ethers } from 'ethers' // This file can be used to play around with the Safe Core SDK @@ -14,57 +13,51 @@ interface Config { const config: Config = { CHAIN_ID: 11155111n, - RPC_URL: 'https://rpc.ankr.com/eth_sepolia', + RPC_URL: 'https://sepolia.gateway.tenderly.co', SIGNER_ADDRESS_PRIVATE_KEY: '', SAFE_ADDRESS: '' } async function main() { - const provider = new ethers.JsonRpcProvider(config.RPC_URL) - const signer = new ethers.Wallet(config.SIGNER_ADDRESS_PRIVATE_KEY, provider) - - // Create EthAdapter instance - const ethAdapter = new EthersAdapter({ - ethers, - signerOrProvider: signer - }) - // Create Safe instance - const safe = await Safe.create({ - ethAdapter, + const protocolKit = await Safe.init({ + provider: config.RPC_URL, + signer: config.SIGNER_ADDRESS_PRIVATE_KEY, safeAddress: config.SAFE_ADDRESS }) // Create Safe API Kit instance - const service = new SafeApiKit({ + const apiKit = new SafeApiKit({ chainId: config.CHAIN_ID }) // Create transaction const safeTransactionData: SafeTransactionDataPartial = { - to: '0x', + to: config.SAFE_ADDRESS, value: '1', // 1 wei data: '0x', operation: OperationType.Call } - const safeTransaction = await safe.createTransaction({ transactions: [safeTransactionData] }) + const safeTransaction = await protocolKit.createTransaction({ + transactions: [safeTransactionData] + }) - const senderAddress = await signer.getAddress() - const safeTxHash = await safe.getTransactionHash(safeTransaction) - const signature = await safe.signHash(safeTxHash) + const signerAddress = (await protocolKit.getSafeProvider().getSignerAddress()) || '0x' + const safeTxHash = await protocolKit.getTransactionHash(safeTransaction) + const signature = await protocolKit.signHash(safeTxHash) // Propose transaction to the service - await service.proposeTransaction({ + await apiKit.proposeTransaction({ safeAddress: config.SAFE_ADDRESS, safeTransactionData: safeTransaction.data, safeTxHash, - senderAddress, + senderAddress: signerAddress, senderSignature: signature.data }) console.log('Proposed a transaction with Safe:', config.SAFE_ADDRESS) console.log('- safeTxHash:', safeTxHash) - console.log('- Sender:', senderAddress) + console.log('- Sender:', signerAddress) console.log('- Sender signature:', signature.data) } diff --git a/playground/config/run.ts b/playground/config/run.ts index 726c12ebd..d295ee942 100644 --- a/playground/config/run.ts +++ b/playground/config/run.ts @@ -8,7 +8,7 @@ const playgroundProtocolKitPaths = { 'create-execute-transaction': 'protocol-kit/create-execute-transaction', 'deploy-safe': 'protocol-kit/deploy-safe', 'generate-safe-address': 'protocol-kit/generate-safe-address', - eip1271: 'protocol-kit/eip1271' + 'validate-signatures': 'protocol-kit/validate-signatures' } const playgroundApiKitPaths = { 'propose-transaction': 'api-kit/propose-transaction', diff --git a/playground/protocol-kit/create-execute-transaction.ts b/playground/protocol-kit/create-execute-transaction.ts index 90e1ceb79..cc5fc7aa1 100644 --- a/playground/protocol-kit/create-execute-transaction.ts +++ b/playground/protocol-kit/create-execute-transaction.ts @@ -1,6 +1,5 @@ -import { ethers } from 'ethers' import * as dotenv from 'dotenv' -import Safe, { EthersAdapter, SigningMethod } from '@safe-global/protocol-kit' +import Safe, { SigningMethod } from '@safe-global/protocol-kit' import { OperationType, SafeTransactionDataPartial } from '@safe-global/safe-core-sdk-types' dotenv.config() @@ -19,24 +18,16 @@ interface Config { } const config: Config = { - RPC_URL: 'https://rpc.ankr.com/eth_sepolia', + RPC_URL: 'https://sepolia.gateway.tenderly.co', SIGNER_ADDRESS_PRIVATE_KEY: SIGNER_ADDRESS_PRIVATE_KEY!, SAFE_ADDRESS: '' } async function main() { - const provider = new ethers.JsonRpcProvider(config.RPC_URL) - const signer = new ethers.Wallet(config.SIGNER_ADDRESS_PRIVATE_KEY, provider) - - // Create EthAdapter instance - const ethAdapter = new EthersAdapter({ - ethers, - signerOrProvider: signer - }) - // Create Safe instance - const safe = await Safe.create({ - ethAdapter, + const safe = await Safe.init({ + provider: config.RPC_URL, + signer: config.SIGNER_ADDRESS_PRIVATE_KEY, safeAddress: config.SAFE_ADDRESS }) diff --git a/playground/protocol-kit/deploy-safe.ts b/playground/protocol-kit/deploy-safe.ts index 3ce239bee..867bebf29 100644 --- a/playground/protocol-kit/deploy-safe.ts +++ b/playground/protocol-kit/deploy-safe.ts @@ -1,7 +1,5 @@ import { SafeAccountConfig, SafeFactory } from '@safe-global/protocol-kit' -import { EthersAdapter } from '@safe-global/protocol-kit' import { SafeVersion } from '@safe-global/safe-core-sdk-types' -import { ethers } from 'ethers' // This file can be used to play around with the Safe Core SDK @@ -17,7 +15,7 @@ interface Config { } const config: Config = { - RPC_URL: 'https://rpc.ankr.com/eth_sepolia', + RPC_URL: 'https://sepolia.gateway.tenderly.co', DEPLOYER_ADDRESS_PRIVATE_KEY: '', DEPLOY_SAFE: { OWNERS: ['OWNER_ADDRESS'], @@ -28,21 +26,16 @@ const config: Config = { } async function main() { - const provider = new ethers.JsonRpcProvider(config.RPC_URL) - const deployerSigner = new ethers.Wallet(config.DEPLOYER_ADDRESS_PRIVATE_KEY, provider) - - // Create EthAdapter instance - const ethAdapter = new EthersAdapter({ - ethers, - signerOrProvider: deployerSigner - }) - const safeVersion = config.DEPLOY_SAFE.SAFE_VERSION as SafeVersion console.log('safe config: ', config.DEPLOY_SAFE) // Create SafeFactory instance - const safeFactory = await SafeFactory.create({ ethAdapter, safeVersion }) + const safeFactory = await SafeFactory.init({ + provider: config.RPC_URL, + signer: config.DEPLOYER_ADDRESS_PRIVATE_KEY, + safeVersion + }) // Config of the deployed Safe const safeAccountConfig: SafeAccountConfig = { diff --git a/playground/protocol-kit/eip1271.ts b/playground/protocol-kit/eip1271.ts deleted file mode 100644 index 10129eea3..000000000 --- a/playground/protocol-kit/eip1271.ts +++ /dev/null @@ -1,65 +0,0 @@ -import Safe from '@safe-global/protocol-kit' -import { EthersAdapter, hashSafeMessage } from '@safe-global/protocol-kit' -import { ethers, JsonRpcProvider } from 'ethers' - -// This file can be used to play around with the Safe Core SDK - -interface Config { - RPC_URL: string - OWNER1_PRIVATE_KEY: string - OWNER2_PRIVATE_KEY: string - OWNER3_PRIVATE_KEY: string - SAFE_2_3_ADDRESS: string -} - -const config: Config = { - RPC_URL: '', - // Create a Safe 2/3 with 3 owners and fill this info - OWNER1_PRIVATE_KEY: '', - OWNER2_PRIVATE_KEY: '', - OWNER3_PRIVATE_KEY: '', - SAFE_2_3_ADDRESS: '' -} - -async function main() { - const provider = new JsonRpcProvider(config.RPC_URL) - const signer1 = new ethers.Wallet(config.OWNER1_PRIVATE_KEY, provider) - const signer2 = new ethers.Wallet(config.OWNER2_PRIVATE_KEY, provider) - - // Create safeSdk instances - const safeSdk1 = await Safe.create({ - ethAdapter: new EthersAdapter({ - ethers, - signerOrProvider: signer1 - }), - safeAddress: config.SAFE_2_3_ADDRESS - }) - - const safeSdk2 = await Safe.create({ - ethAdapter: new EthersAdapter({ - ethers, - signerOrProvider: signer2 - }), - safeAddress: config.SAFE_2_3_ADDRESS - }) - - const MESSAGE_TO_SIGN = 'I am the owner of this Safe account' - - const messageHash = hashSafeMessage(MESSAGE_TO_SIGN) - const safeMessageHash = await safeSdk1.getSafeMessageHash(messageHash) - - const ethSignSig = await safeSdk1.signHash(safeMessageHash) - const typedDataSig = await safeSdk2.signTypedData(safeSdk2.createMessage(MESSAGE_TO_SIGN), 'v4') - - // Validate the signature sending the Safe message hash and the concatenated signatures - const isValid = await safeSdk1.isValidSignature(messageHash, [typedDataSig, ethSignSig]) - - console.log('Message: ', MESSAGE_TO_SIGN) - console.log('Message Hash: ', messageHash) - console.log('Safe Message Hash: ', safeMessageHash) - console.log('Signatures: ', ethSignSig, typedDataSig) - - console.log(`The signature is ${isValid ? 'valid' : 'invalid'}`) -} - -main() diff --git a/playground/protocol-kit/generate-safe-address.ts b/playground/protocol-kit/generate-safe-address.ts index b71ba39da..af403ea84 100644 --- a/playground/protocol-kit/generate-safe-address.ts +++ b/playground/protocol-kit/generate-safe-address.ts @@ -1,18 +1,17 @@ import { - EthersAdapter, + SafeProvider, SafeAccountConfig, SafeDeploymentConfig, predictSafeAddress } from '@safe-global/protocol-kit' import { SafeVersion } from '@safe-global/safe-core-sdk-types' -import { ethers } from 'ethers' // This script can be used to generate a custom Safe address const config: Config = { // REQUIRED PARAMETERS owners: ['0x680cde08860141F9D223cE4E620B10Cd6741037E'], - rpcUrl: 'https://goerli.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161', + rpcUrl: 'https://sepolia.gateway.tenderly.co', // OPTIONAL PARAMETERS pattern: '0x5afe', safeVersion: '1.3.0', @@ -29,7 +28,7 @@ async function generateSafeAddresses() { threshold: config.threshold } - const chainId = await ethAdapter.getChainId() + const chainId = await safeProvider.getChainId() // infinite loop to search a valid Safe addresses for (saltNonce; true; saltNonce++ && iteractions++) { @@ -41,7 +40,7 @@ async function generateSafeAddresses() { // we predict the Safe address using the current saltNonce const predictedSafeAddress = await predictSafeAddress({ - ethAdapter, + safeProvider, chainId, safeAccountConfig, safeDeploymentConfig @@ -60,11 +59,8 @@ async function generateSafeAddresses() { } } -const provider = new ethers.JsonRpcProvider(config.rpcUrl) - -const ethAdapter = new EthersAdapter({ - ethers, - signerOrProvider: provider +const safeProvider = new SafeProvider({ + provider: config.rpcUrl }) const start = Date.now() diff --git a/playground/protocol-kit/validate-signatures.ts b/playground/protocol-kit/validate-signatures.ts new file mode 100644 index 000000000..5bb0ae896 --- /dev/null +++ b/playground/protocol-kit/validate-signatures.ts @@ -0,0 +1,86 @@ +import Safe, { SigningMethod, buildContractSignature } from '@safe-global/protocol-kit' +import { hashSafeMessage } from '@safe-global/protocol-kit' + +// This file can be used to play around with the Safe Core SDK + +interface Config { + RPC_URL: string + OWNER1_PRIVATE_KEY: string + OWNER2_PRIVATE_KEY: string + SAFE_3_3_ADDRESS: string + SIGNER_SAFE_ADDRESS: string +} + +// To run this script, you need a Safe with the following configuration +// - 3/3 Safe with 3 owners and threshold 3 +// - Owner 1: public address from OWNER1_PRIVATE_KEY +// - Owner 2: public address from OWNER2_PRIVATE_KEY +// - Owner 3: SIGNER_SAFE_ADDRESS (1/1 with OWNER1_PRIVATE_KEY public address as owner) +const config: Config = { + RPC_URL: 'https://sepolia.gateway.tenderly.co', + OWNER1_PRIVATE_KEY: '', + OWNER2_PRIVATE_KEY: '', + SIGNER_SAFE_ADDRESS: '', + SAFE_3_3_ADDRESS: '' +} + +async function main() { + // Create safeSdk instances + let protocolKit = await Safe.init({ + provider: config.RPC_URL, + signer: config.OWNER1_PRIVATE_KEY, + safeAddress: config.SAFE_3_3_ADDRESS + }) + + const MESSAGE = 'I am the owner of this Safe account' + + let message = protocolKit.createMessage(MESSAGE) + + message = await protocolKit.signMessage(message) // Owner 1 signature + + protocolKit = await protocolKit.connect({ + signer: config.OWNER2_PRIVATE_KEY, + safeAddress: config.SAFE_3_3_ADDRESS + }) // Connect another owner + + message = await protocolKit.signMessage(message, SigningMethod.ETH_SIGN_TYPED_DATA_V4) // Owner 2 signature + + protocolKit = await protocolKit.connect({ + signer: config.OWNER1_PRIVATE_KEY, + safeAddress: config.SIGNER_SAFE_ADDRESS + }) + + let signerSafeMessage = protocolKit.createMessage(MESSAGE) + signerSafeMessage = await protocolKit.signMessage( + signerSafeMessage, + SigningMethod.SAFE_SIGNATURE, + config.SAFE_3_3_ADDRESS + ) + + message.addSignature( + await buildContractSignature( + Array.from(signerSafeMessage.signatures.values()), + config.SIGNER_SAFE_ADDRESS + ) + ) + + protocolKit = await protocolKit.connect({ + signer: config.OWNER1_PRIVATE_KEY, + safeAddress: config.SAFE_3_3_ADDRESS + }) + + // Validate the signature sending the Safe message hash and the concatenated signatures + const messageHash = hashSafeMessage(MESSAGE) + const safeMessageHash = await protocolKit.getSafeMessageHash(messageHash) + + const isValid = await protocolKit.isValidSignature(messageHash, message.encodedSignatures()) + + console.log('Message: ', MESSAGE) + console.log('Message Hash: ', messageHash) + console.log('Safe Message Hash: ', safeMessageHash) + console.log('Signatures: ', message.signatures.values()) + + console.log(`The signature is ${isValid ? 'valid' : 'invalid'}`) +} + +main() diff --git a/playground/relay-kit/paid-transaction.ts b/playground/relay-kit/paid-transaction.ts index 47b5b6aa2..45ca4ce3d 100644 --- a/playground/relay-kit/paid-transaction.ts +++ b/playground/relay-kit/paid-transaction.ts @@ -6,19 +6,19 @@ import { OperationType } from '@safe-global/safe-core-sdk-types' import { ethers } from 'ethers' -import { EthersAdapter } from '@safe-global/protocol-kit' // Check the status of a transaction after it is relayed: // https://relay.gelato.digital/tasks/status/ // Check the status of a transaction after it is executed: -// https://goerli.etherscan.io/tx/ +// https://sepolia.etherscan.io/tx/ const config = { - SAFE_SIGNER_PRIVATE_KEY: '', - RPC_URL: 'https://goerli.infura.io/v3/' + SAFE_SIGNER_PRIVATE_KEY: '' } +const RPC_URL = 'https://sepolia.gateway.tenderly.co' + const mockOnRampConfig = { ADDRESS: '
', PRIVATE_KEY: '' @@ -30,7 +30,7 @@ const txConfig = { VALUE: '', // Options: GAS_LIMIT: '', - GAS_TOKEN: ethers.ZeroAddress + GAS_TOKEN: '0x0000000000000000000000000000000000000000' } async function main() { @@ -38,15 +38,10 @@ async function main() { // SDK Initialization - const provider = new ethers.JsonRpcProvider(config.RPC_URL) - const signer = new ethers.Wallet(config.SAFE_SIGNER_PRIVATE_KEY, provider) - - const safeAccountAbstraction = new AccountAbstraction( - new EthersAdapter({ - ethers, - signerOrProvider: signer - }) - ) + const safeAccountAbstraction = new AccountAbstraction({ + provider: RPC_URL, + signer: config.SAFE_SIGNER_PRIVATE_KEY + }) await safeAccountAbstraction.init() @@ -62,18 +57,20 @@ async function main() { const isSafeDeployed = await safeAccountAbstraction.protocolKit.isSafeDeployed() console.log({ isSafeDeployed }) + const ethersProvider = safeAccountAbstraction.protocolKit.getSafeProvider().getExternalProvider() + // Fake on-ramp to transfer enough funds to the Safe address - const chainId = (await provider.getNetwork()).chainId + const chainId = (await ethersProvider.getNetwork()).chainId const relayFee = BigInt( await relayPack.getEstimateFee(chainId, txConfig.GAS_LIMIT, txConfig.GAS_TOKEN) ) - const safeBalance = await provider.getBalance(predictedSafeAddress) + const safeBalance = await ethersProvider.getBalance(predictedSafeAddress) console.log({ minSafeBalance: ethers.formatEther(relayFee.toString()) }) console.log({ safeBalance: ethers.formatEther(safeBalance.toString()) }) if (safeBalance < relayFee) { - const fakeOnRampSigner = new ethers.Wallet(mockOnRampConfig.PRIVATE_KEY, provider) + const fakeOnRampSigner = new ethers.Wallet(mockOnRampConfig.PRIVATE_KEY, ethersProvider) const fundingAmount = safeBalance < relayFee ? relayFee - safeBalance : safeBalance - relayFee const onRampResponse = await fakeOnRampSigner.sendTransaction({ to: predictedSafeAddress, @@ -82,7 +79,7 @@ async function main() { console.log(`Funding the Safe with ${ethers.formatEther(fundingAmount.toString())} ETH`) await onRampResponse.wait() - const safeBalanceAfter = await provider.getBalance(predictedSafeAddress) + const safeBalanceAfter = await ethersProvider.getBalance(predictedSafeAddress) console.log({ safeBalance: ethers.formatEther(safeBalanceAfter.toString()) }) } diff --git a/playground/relay-kit/sponsored-transaction.ts b/playground/relay-kit/sponsored-transaction.ts index 08f11d553..d8c21b531 100644 --- a/playground/relay-kit/sponsored-transaction.ts +++ b/playground/relay-kit/sponsored-transaction.ts @@ -1,5 +1,4 @@ import AccountAbstraction from '@safe-global/account-abstraction-kit-poc' -import { EthersAdapter } from '@safe-global/protocol-kit' import { GelatoRelayPack } from '@safe-global/relay-kit' import { MetaTransactionData, @@ -15,14 +14,15 @@ import { ethers } from 'ethers' // https://relay.gelato.digital/tasks/status/ // Check the status of a transaction after it is executed: -// https://goerli.etherscan.io/tx/ +// https://sepolia.etherscan.io/tx/ const config = { SAFE_SIGNER_PRIVATE_KEY: '', - RPC_URL: 'https://goerli.infura.io/v3/', RELAY_API_KEY: '' } +const RPC_URL = 'https://sepolia.gateway.tenderly.co' + const mockOnRampConfig = { ADDRESS: '
', PRIVATE_KEY: '' @@ -39,15 +39,10 @@ async function main() { // SDK Initialization - const provider = new ethers.JsonRpcProvider(config.RPC_URL) - const signer = new ethers.Wallet(config.SAFE_SIGNER_PRIVATE_KEY, provider) - - const safeAccountAbstraction = new AccountAbstraction( - new EthersAdapter({ - ethers, - signerOrProvider: signer - }) - ) + const safeAccountAbstraction = new AccountAbstraction({ + provider: RPC_URL, + signer: config.SAFE_SIGNER_PRIVATE_KEY + }) await safeAccountAbstraction.init() @@ -68,10 +63,11 @@ async function main() { // Fake on-ramp to fund the Safe - const safeBalance = await provider.getBalance(predictedSafeAddress) + const ethersProvider = safeAccountAbstraction.protocolKit.getSafeProvider().getExternalProvider() + const safeBalance = await ethersProvider.getBalance(predictedSafeAddress) console.log({ safeBalance: ethers.formatEther(safeBalance.toString()) }) if (safeBalance < BigInt(txConfig.VALUE)) { - const fakeOnRampSigner = new ethers.Wallet(mockOnRampConfig.PRIVATE_KEY, provider) + const fakeOnRampSigner = new ethers.Wallet(mockOnRampConfig.PRIVATE_KEY, ethersProvider) const onRampResponse = await fakeOnRampSigner.sendTransaction({ to: predictedSafeAddress, value: txConfig.VALUE @@ -79,7 +75,7 @@ async function main() { console.log(`Funding the Safe with ${ethers.formatEther(txConfig.VALUE.toString())} ETH`) await onRampResponse.wait() - const safeBalanceAfter = await provider.getBalance(predictedSafeAddress) + const safeBalanceAfter = await ethersProvider.getBalance(predictedSafeAddress) console.log({ safeBalance: ethers.formatEther(safeBalanceAfter.toString()) }) } diff --git a/playground/relay-kit/usdc-transfer-4337-counterfactual.ts b/playground/relay-kit/usdc-transfer-4337-counterfactual.ts index 637e3d3e7..2885078d3 100644 --- a/playground/relay-kit/usdc-transfer-4337-counterfactual.ts +++ b/playground/relay-kit/usdc-transfer-4337-counterfactual.ts @@ -1,5 +1,4 @@ -import { EthersAdapter } from '@safe-global/protocol-kit' -import { ethers } from 'ethers' +import { ethers, AbstractSigner } from 'ethers' import { Safe4337Pack } from '@safe-global/relay-kit' // Safe owner PK @@ -7,8 +6,11 @@ const PRIVATE_KEY = '' const PIMLICO_API_KEY = '' +// Safe owner address +const OWNER_ADDRESS = '' + // RPC URL -const RPC_URL = 'https://rpc.ankr.com/eth_sepolia' // SEPOLIA +const RPC_URL = 'https://sepolia.gateway.tenderly.co' // SEPOLIA // const RPC_URL = 'https://rpc.gnosischain.com/' // GNOSIS // CHAIN @@ -24,21 +26,14 @@ const usdcTokenAddress = '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238' // SEPOLIA // const usdcTokenAddress = '0xddafbb505ad214d7b80b1f830fccc89b60fb7a83' // GNOSIS async function main() { - // Instantiate EtherAdapter - const provider = new ethers.JsonRpcProvider(RPC_URL) - const signer = new ethers.Wallet(PRIVATE_KEY, provider) - const ethersAdapter = new EthersAdapter({ - ethers, - signerOrProvider: signer - }) - // 1) Initialize pack const safe4337Pack = await Safe4337Pack.init({ - ethersAdapter, + provider: RPC_URL, + signer: PRIVATE_KEY, rpcUrl: RPC_URL, bundlerUrl: BUNDLER_URL, options: { - owners: [await signer.getAddress()], + owners: [OWNER_ADDRESS], threshold: 1, saltNonce: '4337' + '1' // to update the address } @@ -65,9 +60,17 @@ async function main() { console.log(`sending ${nativeTokenAmount} ETH...`) - const transactionFundingResponse = await signer.sendTransaction(fundingSafe) + const ethersSigner = await safe4337Pack.protocolKit.getSafeProvider().getExternalSigner() + const signerAddress = await safe4337Pack.protocolKit.getSafeProvider().getSignerAddress() + const ethersProvider = safe4337Pack.protocolKit.getSafeProvider().getExternalProvider() + + if (!ethersSigner || !signerAddress) { + throw new Error('No signer found!') + } + + const transactionFundingResponse = await ethersSigner?.sendTransaction(fundingSafe) - await transactionFundingResponse.wait() + await transactionFundingResponse?.wait() // Create transaction batch with two 0.1 USDC transfers @@ -76,18 +79,18 @@ async function main() { console.log(`sending USDC...`) // send 0.2 USDC to the Safe - await transfer(signer, usdcTokenAddress, senderAddress, usdcAmount * 2n) + await transfer(ethersSigner, usdcTokenAddress, senderAddress, usdcAmount * 2n) console.log(`creating the Safe batch...`) const transferUSDC = { to: usdcTokenAddress, - data: generateTransferCallData(signer.address, usdcAmount), + data: generateTransferCallData(signerAddress, usdcAmount), value: '0' } const transactions = [transferUSDC, transferUSDC] - const timestamp = (await provider.getBlock('latest'))?.timestamp || 0 + const timestamp = (await ethersProvider.getBlock('latest'))?.timestamp || 0 // 2) Create transaction batch const safeOperation = await safe4337Pack.createTransaction({ @@ -127,7 +130,7 @@ async function main() { main() -async function transfer(signer: ethers.Wallet, tokenAddress: string, to: string, amount: bigint) { +async function transfer(signer: AbstractSigner, tokenAddress: string, to: string, amount: bigint) { const transferEC20 = { to: tokenAddress, data: generateTransferCallData(to, amount), diff --git a/playground/relay-kit/usdc-transfer-4337-erc20-counterfactual.ts b/playground/relay-kit/usdc-transfer-4337-erc20-counterfactual.ts index f8ec40b1c..4bcdf7911 100644 --- a/playground/relay-kit/usdc-transfer-4337-erc20-counterfactual.ts +++ b/playground/relay-kit/usdc-transfer-4337-erc20-counterfactual.ts @@ -1,4 +1,3 @@ -import { EthersAdapter } from '@safe-global/protocol-kit' import { ethers } from 'ethers' import { Safe4337Pack } from '@safe-global/relay-kit' @@ -7,12 +6,15 @@ const PRIVATE_KEY = '' const PIMLICO_API_KEY = '' +// Safe owner address +const OWNER_ADDRESS = '' + // CHAIN const CHAIN_NAME = 'sepolia' // const CHAIN_NAME = 'gnosis' // RPC URL -const RPC_URL = 'https://rpc.ankr.com/eth_sepolia' // SEPOLIA +const RPC_URL = 'https://sepolia.gateway.tenderly.co' // SEPOLIA // const RPC_URL = 'https://rpc.gnosischain.com/' // GNOSIS // Bundler URL @@ -28,17 +30,10 @@ const usdcTokenAddress = '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238' // SEPOLIA // const usdcTokenAddress = '0xddafbb505ad214d7b80b1f830fccc89b60fb7a83' // GNOSIS async function main() { - // Instantiate EtherAdapter - const provider = new ethers.JsonRpcProvider(RPC_URL) - const signer = new ethers.Wallet(PRIVATE_KEY, provider) - const ethersAdapter = new EthersAdapter({ - ethers, - signerOrProvider: signer - }) - // 1) Initialize pack with the paymaster data const safe4337Pack = await Safe4337Pack.init({ - ethersAdapter, + provider: RPC_URL, + signer: PRIVATE_KEY, rpcUrl: RPC_URL, bundlerUrl: BUNDLER_URL, paymasterOptions: { @@ -47,7 +42,7 @@ async function main() { // amountToApprove?: bigint // optional value to set the paymaster approve amount on the deployment }, options: { - owners: [await signer.getAddress()], + owners: [OWNER_ADDRESS], threshold: 1, saltNonce: '4337' + '1' // to update the address } @@ -68,8 +63,15 @@ async function main() { console.log(`sending USDC...`) + const ethersSigner = await safe4337Pack.protocolKit.getSafeProvider().getExternalSigner() + const ethersProvider = safe4337Pack.protocolKit.getSafeProvider().getExternalProvider() + + if (!ethersSigner) { + throw new Error('No signer found!') + } + // send 15 USDC to the Safe - await transfer(signer, usdcTokenAddress, senderAddress, usdcAmount * 150n) + await transfer(ethersSigner, usdcTokenAddress, senderAddress, usdcAmount * 150n) console.log(`creating the Safe batch...`) @@ -79,7 +81,7 @@ async function main() { value: '0' } const transactions = [transferUSDC, transferUSDC] - const timestamp = (await provider.getBlock('latest'))?.timestamp || 0 + const timestamp = (await ethersProvider.getBlock('latest'))?.timestamp || 0 // 2) Create transaction batch const safeOperation = await safe4337Pack.createTransaction({ @@ -126,7 +128,12 @@ const generateTransferCallData = (to: string, value: bigint) => { return iface.encodeFunctionData('transfer', [to, value]) } -async function transfer(signer: ethers.Wallet, tokenAddress: string, to: string, amount: bigint) { +async function transfer( + signer: ethers.AbstractSigner, + tokenAddress: string, + to: string, + amount: bigint +) { const transferEC20 = { to: tokenAddress, data: generateTransferCallData(to, amount), diff --git a/playground/relay-kit/usdc-transfer-4337-erc20.ts b/playground/relay-kit/usdc-transfer-4337-erc20.ts index 911a8b8e7..c1b9451a3 100644 --- a/playground/relay-kit/usdc-transfer-4337-erc20.ts +++ b/playground/relay-kit/usdc-transfer-4337-erc20.ts @@ -1,4 +1,3 @@ -import { EthersAdapter } from '@safe-global/protocol-kit' import { ethers } from 'ethers' import { Safe4337Pack } from '@safe-global/relay-kit' @@ -15,7 +14,7 @@ const CHAIN_NAME = 'sepolia' // const CHAIN_NAME = 'gnosis' // RPC URL -const RPC_URL = 'https://rpc.ankr.com/eth_sepolia' // SEPOLIA +const RPC_URL = 'https://sepolia.gateway.tenderly.co' // SEPOLIA // const RPC_URL = 'https://rpc.gnosischain.com/' // GNOSIS // Bundler URL @@ -31,17 +30,10 @@ const usdcTokenAddress = '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238' // SEPOLIA // const usdcTokenAddress = '0xddafbb505ad214d7b80b1f830fccc89b60fb7a83' // GNOSIS async function main() { - // Instantiate EtherAdapter - const provider = new ethers.JsonRpcProvider(RPC_URL) - const signer = new ethers.Wallet(PRIVATE_KEY, provider) - const ethersAdapter = new EthersAdapter({ - ethers, - signerOrProvider: signer - }) - // 1) Initialize pack with the paymaster data const safe4337Pack = await Safe4337Pack.init({ - ethersAdapter, + provider: RPC_URL, + signer: PRIVATE_KEY, rpcUrl: RPC_URL, bundlerUrl: BUNDLER_URL, paymasterOptions: { @@ -65,8 +57,15 @@ async function main() { console.log(`sending USDC...`) + const ethersSigner = await safe4337Pack.protocolKit.getSafeProvider().getExternalSigner() + const ethersProvider = safe4337Pack.protocolKit.getSafeProvider().getExternalProvider() + + if (!ethersSigner) { + throw new Error('No signer found!') + } + // send 5 USDC to the Safe - await transfer(signer, usdcTokenAddress, senderAddress, usdcAmount * 50n) + await transfer(ethersSigner, usdcTokenAddress, senderAddress, usdcAmount * 50n) console.log(`creating the Safe batch...`) @@ -76,7 +75,7 @@ async function main() { value: '0' } const transactions = [transferUSDC, transferUSDC] - const timestamp = (await provider.getBlock('latest'))?.timestamp || 0 + const timestamp = (await ethersProvider.getBlock('latest'))?.timestamp || 0 // 2) Create transaction batch const safeOperation = await safe4337Pack.createTransaction({ @@ -123,7 +122,12 @@ const generateTransferCallData = (to: string, value: bigint) => { return iface.encodeFunctionData('transfer', [to, value]) } -async function transfer(signer: ethers.Wallet, tokenAddress: string, to: string, amount: bigint) { +async function transfer( + signer: ethers.AbstractSigner, + tokenAddress: string, + to: string, + amount: bigint +) { const transferEC20 = { to: tokenAddress, data: generateTransferCallData(to, amount), diff --git a/playground/relay-kit/usdc-transfer-4337-sponsored-counterfactual.ts b/playground/relay-kit/usdc-transfer-4337-sponsored-counterfactual.ts index 218b12866..0c43fef1b 100644 --- a/playground/relay-kit/usdc-transfer-4337-sponsored-counterfactual.ts +++ b/playground/relay-kit/usdc-transfer-4337-sponsored-counterfactual.ts @@ -1,4 +1,3 @@ -import { EthersAdapter } from '@safe-global/protocol-kit' import { ethers } from 'ethers' import { Safe4337Pack } from '@safe-global/relay-kit' @@ -7,6 +6,9 @@ const PRIVATE_KEY = '' const PIMLICO_API_KEY = '' +// Safe owner address +const OWNER_ADDRESS = '' + // PolicyId is an optional parameter, you can create one here: https://dashboard.pimlico.io/sponsorship-policies const POLICY_ID = '' @@ -15,7 +17,7 @@ const CHAIN_NAME = 'sepolia' // const CHAIN_NAME = 'gnosis' // RPC URL -const RPC_URL = 'https://rpc.ankr.com/eth_sepolia' // SEPOLIA +const RPC_URL = 'https://sepolia.gateway.tenderly.co' // SEPOLIA // const RPC_URL = 'https://rpc.gnosischain.com/' // GNOSIS // Bundler URL @@ -34,17 +36,10 @@ const usdcTokenAddress = '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238' // SEPOLIA // const usdcTokenAddress = '0xddafbb505ad214d7b80b1f830fccc89b60fb7a83' // GNOSIS async function main() { - // Instantiate EtherAdapter - const provider = new ethers.JsonRpcProvider(RPC_URL) - const signer = new ethers.Wallet(PRIVATE_KEY, provider) - const ethersAdapter = new EthersAdapter({ - ethers, - signerOrProvider: signer - }) - // 1) Initialize pack with the paymaster data const safe4337Pack = await Safe4337Pack.init({ - ethersAdapter, + provider: RPC_URL, + signer: PRIVATE_KEY, rpcUrl: RPC_URL, bundlerUrl: BUNDLER_URL, paymasterOptions: { @@ -54,7 +49,7 @@ async function main() { paymasterUrl: PAYMASTER_URL }, options: { - owners: [await signer.getAddress()], + owners: [OWNER_ADDRESS], threshold: 1, saltNonce: '4337' + '1' // to update the address } @@ -75,8 +70,15 @@ async function main() { console.log(`sending USDC...`) + const ethersSigner = await safe4337Pack.protocolKit.getSafeProvider().getExternalSigner() + const ethersProvider = safe4337Pack.protocolKit.getSafeProvider().getExternalProvider() + + if (!ethersSigner) { + throw new Error('No signer found!') + } + // send 0.2 USDC to the Safe - await transfer(signer, usdcTokenAddress, senderAddress, usdcAmount * 2n) + await transfer(ethersSigner, usdcTokenAddress, senderAddress, usdcAmount * 2n) console.log(`creating the Safe batch...`) @@ -86,7 +88,7 @@ async function main() { value: '0' } const transactions = [transferUSDC, transferUSDC] - const timestamp = (await provider.getBlock('latest'))?.timestamp || 0 + const timestamp = (await ethersProvider.getBlock('latest'))?.timestamp || 0 // 2) Create transaction batch const safeOperation = await safe4337Pack.createTransaction({ @@ -133,7 +135,12 @@ const generateTransferCallData = (to: string, value: bigint) => { return iface.encodeFunctionData('transfer', [to, value]) } -async function transfer(signer: ethers.Wallet, tokenAddress: string, to: string, amount: bigint) { +async function transfer( + signer: ethers.AbstractSigner, + tokenAddress: string, + to: string, + amount: bigint +) { const transferEC20 = { to: tokenAddress, data: generateTransferCallData(to, amount), diff --git a/playground/relay-kit/usdc-transfer-4337-sponsored.ts b/playground/relay-kit/usdc-transfer-4337-sponsored.ts index 39af77cfd..23ff63917 100644 --- a/playground/relay-kit/usdc-transfer-4337-sponsored.ts +++ b/playground/relay-kit/usdc-transfer-4337-sponsored.ts @@ -1,4 +1,3 @@ -import { EthersAdapter } from '@safe-global/protocol-kit' import { ethers } from 'ethers' import { Safe4337Pack } from '@safe-global/relay-kit' @@ -18,7 +17,7 @@ const CHAIN_NAME = 'sepolia' // const CHAIN_NAME = 'gnosis' // RPC URL -const RPC_URL = 'https://rpc.ankr.com/eth_sepolia' // SEPOLIA +const RPC_URL = 'https://sepolia.gateway.tenderly.co' // SEPOLIA // const RPC_URL = 'https://rpc.gnosischain.com/' // GNOSIS // Bundler URL @@ -37,17 +36,10 @@ const usdcTokenAddress = '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238' // SEPOLIA // const usdcTokenAddress = '0xddafbb505ad214d7b80b1f830fccc89b60fb7a83' // GNOSIS async function main() { - // Instantiate EtherAdapter - const provider = new ethers.JsonRpcProvider(RPC_URL) - const signer = new ethers.Wallet(PRIVATE_KEY, provider) - const ethersAdapter = new EthersAdapter({ - ethers, - signerOrProvider: signer - }) - // 1) Initialize pack with the paymaster data const safe4337Pack = await Safe4337Pack.init({ - ethersAdapter, + provider: RPC_URL, + signer: PRIVATE_KEY, rpcUrl: RPC_URL, bundlerUrl: BUNDLER_URL, paymasterOptions: { @@ -76,7 +68,8 @@ async function main() { value: '0' } const transactions = [transferUSDC, transferUSDC] - const timestamp = (await provider.getBlock('latest'))?.timestamp || 0 + const ethersProvider = safe4337Pack.protocolKit.getSafeProvider().getExternalProvider() + const timestamp = (await ethersProvider.getBlock('latest'))?.timestamp || 0 // 2) Create transaction batch const safeOperation = await safe4337Pack.createTransaction({ diff --git a/playground/relay-kit/usdc-transfer-4337.ts b/playground/relay-kit/usdc-transfer-4337.ts index 048eb6ab0..3f25529ab 100644 --- a/playground/relay-kit/usdc-transfer-4337.ts +++ b/playground/relay-kit/usdc-transfer-4337.ts @@ -1,4 +1,3 @@ -import { EthersAdapter } from '@safe-global/protocol-kit' import { ethers } from 'ethers' import { Safe4337Pack } from '@safe-global/relay-kit' @@ -14,24 +13,17 @@ const SAFE_ADDRESS = '' const BUNDLER_URL = `https://api.pimlico.io/v1/sepolia/rpc?apikey=${PIMLICO_API_KEY}` // PIMLICO // RPC URL -const RPC_URL = 'https://rpc.ankr.com/eth_sepolia' +const RPC_URL = 'https://sepolia.gateway.tenderly.co' // USDC CONTRACT ADDRESS IN SEPOLIA // faucet: https://faucet.circle.com/ const usdcTokenAddress = '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238' async function main() { - // Instantiate EtherAdapter - const provider = new ethers.JsonRpcProvider(RPC_URL) - const signer = new ethers.Wallet(PRIVATE_KEY, provider) - const ethersAdapter = new EthersAdapter({ - ethers, - signerOrProvider: signer - }) - // 1) Initialize pack const safe4337Pack = await Safe4337Pack.init({ - ethersAdapter, + provider: RPC_URL, + signer: PRIVATE_KEY, rpcUrl: RPC_URL, bundlerUrl: BUNDLER_URL, options: { @@ -55,7 +47,8 @@ async function main() { value: '0' } const transactions = [transferUSDC, transferUSDC] - const timestamp = (await provider.getBlock('latest'))?.timestamp || 0 + const ethersProvider = safe4337Pack.protocolKit.getSafeProvider().getExternalProvider() + const timestamp = (await ethersProvider.getBlock('latest'))?.timestamp || 0 // 2) Create transaction batch const safeOperation = await safe4337Pack.createTransaction({ diff --git a/tsconfig.settings.json b/tsconfig.settings.json index ccb301b65..f9e3f947d 100644 --- a/tsconfig.settings.json +++ b/tsconfig.settings.json @@ -30,7 +30,6 @@ "@safe-global/auth-kit/*": ["./packages/auth-kit/src/*"], "@safe-global/onramp-kit/*": ["./packages/onramp-kit/src/*"], "@safe-global/protocol-kit/*": ["./packages/protocol-kit/src/*"], - "@safe-global/protocol-kit/typechain/*": ["./packages/protocol-kit/typechain/*"], "@safe-global/protocol-kit/hardhat/*": ["./packages/protocol-kit/hardhat/*"], "@safe-global/relay-kit/*": ["./packages/relay-kit/src/*"], "@safe-global/safe-core-sdk-types/*": ["./packages/safe-core-sdk-types/src/*"] diff --git a/yarn.lock b/yarn.lock index 0e49f45c5..723abeb82 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4,7 +4,7 @@ "@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" + resolved "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz" integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== "@adraffy/ens-normalize@1.10.0": @@ -12,6 +12,11 @@ resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz#d2a39395c587e092d77cbbc80acf956a54f38bf7" integrity sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q== +"@adraffy/ens-normalize@1.10.1", "@adraffy/ens-normalize@^1.8.8": + version "1.10.1" + resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz#63430d04bd8c5e74f8d7d049338f1cd9d4f02069" + integrity sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw== + "@adraffy/ens-normalize@1.9.2": version "1.9.2" resolved "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.9.2.tgz" @@ -34,9 +39,9 @@ chalk "^2.4.2" "@babel/compat-data@^7.21.4": - version "7.21.4" - resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.4.tgz" - integrity sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g== + version "7.23.3" + resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.3.tgz" + integrity sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ== "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.7.5": version "7.21.4" @@ -374,7 +379,7 @@ "@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" + resolved "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz" integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== "@eslint/eslintrc@^2.1.4": @@ -397,14 +402,6 @@ resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.56.0.tgz#ef20350fec605a7f7035a01764731b2de0f3782b" integrity sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A== -"@ethereumjs/common@2.6.5", "@ethereumjs/common@^2.6.4": - version "2.6.5" - resolved "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.5.tgz" - integrity sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA== - dependencies: - crc-32 "^1.2.0" - ethereumjs-util "^7.1.5" - "@ethereumjs/common@^3.2.0": version "3.2.0" resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-3.2.0.tgz#b71df25845caf5456449163012074a55f048e0a0" @@ -431,14 +428,6 @@ resolved "https://registry.yarnpkg.com/@ethereumjs/rlp/-/rlp-5.0.1.tgz#56c5433b9242f956e354fd7e4ce3523815e24854" integrity sha512-Ab/Hfzz+T9Zl+65Nkg+9xAmwKPLicsnQ4NW49pgvJp9ovefuic95cgOS9CbPc9izIEgsqm1UitV0uNveCvud9w== -"@ethereumjs/tx@3.5.2": - version "3.5.2" - resolved "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.5.2.tgz" - integrity sha512-gQDNJWKrSDGu2w7w0PzVXVBNMzb7wwdDOmOqczmhNjqFxFuIbhVJDwiGEnxFNC2/b8ifcZzY7MLcluizohRzNw== - dependencies: - "@ethereumjs/common" "^2.6.4" - ethereumjs-util "^7.1.5" - "@ethereumjs/tx@^4.2.0": version "4.2.0" resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-4.2.0.tgz#5988ae15daf5a3b3c815493bc6b495e76009e853" @@ -461,7 +450,7 @@ "@ethereumjs/util@^8.1.0": version "8.1.0" - resolved "https://registry.yarnpkg.com/@ethereumjs/util/-/util-8.1.0.tgz#299df97fb6b034e0577ce9f94c7d9d1004409ed4" + resolved "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz" integrity sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA== dependencies: "@ethereumjs/rlp" "^4.0.1" @@ -476,7 +465,7 @@ "@ethereumjs/rlp" "^5.0.1" ethereum-cryptography "^2.1.2" -"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.1.2", "@ethersproject/abi@^5.6.3", "@ethersproject/abi@^5.7.0": +"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.1.2", "@ethersproject/abi@^5.7.0": version "5.7.0" resolved "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz" integrity sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA== @@ -751,7 +740,7 @@ "@ethersproject/constants" "^5.7.0" "@ethersproject/logger" "^5.7.0" -"@ethersproject/transactions@5.7.0", "@ethersproject/transactions@^5.6.2", "@ethersproject/transactions@^5.7.0": +"@ethersproject/transactions@5.7.0", "@ethersproject/transactions@^5.7.0": version "5.7.0" resolved "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz" integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ== @@ -830,7 +819,7 @@ "@gelatonetwork/relay-sdk@^5.5.0": version "5.5.0" - resolved "https://registry.yarnpkg.com/@gelatonetwork/relay-sdk/-/relay-sdk-5.5.0.tgz#0f01ed5884b2d45c348022c0cd6072ee8ca991ae" + resolved "https://registry.npmjs.org/@gelatonetwork/relay-sdk/-/relay-sdk-5.5.0.tgz" integrity sha512-DR1ZojfK5P1inxU+nSx3GaXnsWO8qKGfuU6ouW3sVflF8J9IhV0VzaAB4rhdThnr+FgAxmtuDzQUW1NuPrC4Cg== dependencies: axios "0.27.2" @@ -845,7 +834,7 @@ "@humanwhocodes/config-array@^0.11.13": version "0.11.13" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.13.tgz#075dc9684f40a531d9b26b0822153c1e832ee297" + resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz" integrity sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ== dependencies: "@humanwhocodes/object-schema" "^2.0.1" @@ -859,7 +848,7 @@ "@humanwhocodes/object-schema@^2.0.1": version "2.0.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz#e5211452df060fa8522b55c7b3c0c4d1981cb044" + resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz" integrity sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw== "@hutson/parse-repository-url@^3.0.0": @@ -897,7 +886,7 @@ "@jest/console@^29.7.0": version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.7.0.tgz#cd4822dbdb84529265c5a2bdb529a3c9cc950ffc" + resolved "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz" integrity sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg== dependencies: "@jest/types" "^29.6.3" @@ -909,7 +898,7 @@ "@jest/core@^29.7.0": version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.7.0.tgz#b6cccc239f30ff36609658c5a5e2291757ce448f" + resolved "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz" integrity sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg== dependencies: "@jest/console" "^29.7.0" @@ -943,7 +932,7 @@ "@jest/environment@^29.7.0": version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.7.0.tgz#24d61f54ff1f786f3cd4073b4b94416383baf2a7" + resolved "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz" integrity sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw== dependencies: "@jest/fake-timers" "^29.7.0" @@ -953,14 +942,14 @@ "@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" + resolved "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz" 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" + resolved "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz" integrity sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ== dependencies: expect "^29.7.0" @@ -968,7 +957,7 @@ "@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" + resolved "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz" integrity sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ== dependencies: "@jest/types" "^29.6.3" @@ -980,7 +969,7 @@ "@jest/globals@^29.7.0": version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.7.0.tgz#8d9290f9ec47ff772607fa864ca1d5a2efae1d4d" + resolved "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz" integrity sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ== dependencies: "@jest/environment" "^29.7.0" @@ -990,7 +979,7 @@ "@jest/reporters@^29.7.0": version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.7.0.tgz#04b262ecb3b8faa83b0b3d321623972393e8f4c7" + resolved "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz" integrity sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg== dependencies: "@bcoe/v8-coverage" "^0.2.3" @@ -1020,14 +1009,14 @@ "@jest/schemas@^29.6.3": version "29.6.3" - resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" + resolved "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz" 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" + resolved "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz" integrity sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw== dependencies: "@jridgewell/trace-mapping" "^0.3.18" @@ -1036,7 +1025,7 @@ "@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" + resolved "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz" integrity sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA== dependencies: "@jest/console" "^29.7.0" @@ -1046,7 +1035,7 @@ "@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" + resolved "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz" integrity sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw== dependencies: "@jest/test-result" "^29.7.0" @@ -1056,7 +1045,7 @@ "@jest/transform@^29.7.0": version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.7.0.tgz#df2dd9c346c7d7768b8a06639994640c642e284c" + resolved "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz" integrity sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw== dependencies: "@babel/core" "^7.11.6" @@ -1077,7 +1066,7 @@ "@jest/types@^29.6.3": version "29.6.3" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" + resolved "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz" integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== dependencies: "@jest/schemas" "^29.6.3" @@ -1121,7 +1110,7 @@ "@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.9": version "0.3.20" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz#72e45707cf240fa6b081d0366f8265b0cd10197f" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz" integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q== dependencies: "@jridgewell/resolve-uri" "^3.1.0" @@ -1261,21 +1250,13 @@ semver "^7.5.4" superstruct "^1.0.3" -"@monerium/sdk@^2.9.0": - version "2.9.0" - resolved "https://registry.yarnpkg.com/@monerium/sdk/-/sdk-2.9.0.tgz#ec7296623853acd0b7477b1b088f8c8fae42f197" - integrity sha512-6tr1fWau5tca2xjgIB/7NLJQFoVLcRvGQh6gqzgPJZCS9kRIVlupGk1MaejFdGWOmoEqJSFVUzi0TGhEJK+VcA== +"@monerium/sdk@^2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@monerium/sdk/-/sdk-2.12.0.tgz#57ccc1668a354c28d083c29928690f15fe11c479" + integrity sha512-tZxQNAlUpCbVkZfWIVB2yWYjyYZGKckEfzUZbWQyDdxUo487iNJQRr1Z64MZofJ/gKCPfOPJbiZzUGWbl8eLQA== dependencies: crypto-js "^4.2.0" -"@morgan-stanley/ts-mocking-bird@^0.6.2": - version "0.6.4" - resolved "https://registry.npmjs.org/@morgan-stanley/ts-mocking-bird/-/ts-mocking-bird-0.6.4.tgz" - integrity sha512-57VJIflP8eR2xXa9cD1LUawh+Gh+BVQfVu0n6GALyg/AqV/Nz25kDRvws3i9kIe1PTrbsZZOYpsYp6bXPd6nVA== - dependencies: - lodash "^4.17.16" - uuid "^7.0.3" - "@noble/curves@1.1.0", "@noble/curves@~1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.1.0.tgz#f13fc667c89184bc04cccb9b11e8e7bae27d8c3d" @@ -1283,7 +1264,7 @@ dependencies: "@noble/hashes" "1.3.1" -"@noble/curves@1.2.0": +"@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== @@ -1302,15 +1283,15 @@ "@noble/hashes@1.3.1": version "1.3.1" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9" + resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz" integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== "@noble/hashes@1.3.2": version "1.3.2" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" + resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz" integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== -"@noble/hashes@^1.3.1", "@noble/hashes@^1.3.3", "@noble/hashes@~1.3.0", "@noble/hashes@~1.3.1": +"@noble/hashes@^1.3.1", "@noble/hashes@^1.3.3", "@noble/hashes@~1.3.0", "@noble/hashes@~1.3.1", "@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== @@ -1343,7 +1324,7 @@ "@nomicfoundation/ethereumjs-block@5.0.2": version "5.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-5.0.2.tgz#13a7968f5964f1697da941281b7f7943b0465d04" + resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-5.0.2.tgz" integrity sha512-hSe6CuHI4SsSiWWjHDIzWhSiAVpzMUcDRpWYzN0T9l8/Rz7xNn3elwVOJ/tAyS0LqL6vitUD78Uk7lQDXZun7Q== dependencies: "@nomicfoundation/ethereumjs-common" "4.0.2" @@ -1356,7 +1337,7 @@ "@nomicfoundation/ethereumjs-blockchain@7.0.2": version "7.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-7.0.2.tgz#45323b673b3d2fab6b5008535340d1b8fea7d446" + resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-7.0.2.tgz" integrity sha512-8UUsSXJs+MFfIIAKdh3cG16iNmWzWC/91P40sazNvrqhhdR/RtGDlFk2iFTGbBAZPs2+klZVzhRX8m2wvuvz3w== dependencies: "@nomicfoundation/ethereumjs-block" "5.0.2" @@ -1375,7 +1356,7 @@ "@nomicfoundation/ethereumjs-common@4.0.2": version "4.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.2.tgz#a15d1651ca36757588fdaf2a7d381a150662a3c3" + resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.2.tgz" integrity sha512-I2WGP3HMGsOoycSdOTSqIaES0ughQTueOsddJ36aYVpI3SN8YSusgRFLwzDJwRFVIYDKx/iJz0sQ5kBHVgdDwg== dependencies: "@nomicfoundation/ethereumjs-util" "9.0.2" @@ -1383,7 +1364,7 @@ "@nomicfoundation/ethereumjs-ethash@3.0.2": version "3.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-3.0.2.tgz#da77147f806401ee996bfddfa6487500118addca" + resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-3.0.2.tgz" integrity sha512-8PfoOQCcIcO9Pylq0Buijuq/O73tmMVURK0OqdjhwqcGHYC2PwhbajDh7GZ55ekB0Px197ajK3PQhpKoiI/UPg== dependencies: "@nomicfoundation/ethereumjs-block" "5.0.2" @@ -1395,7 +1376,7 @@ "@nomicfoundation/ethereumjs-evm@2.0.2": version "2.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-2.0.2.tgz#4c2f4b84c056047102a4fa41c127454e3f0cfcf6" + resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-2.0.2.tgz" integrity sha512-rBLcUaUfANJxyOx9HIdMX6uXGin6lANCulIm/pjMgRqfiCRMZie3WKYxTSd8ZE/d+qT+zTedBF4+VHTdTSePmQ== dependencies: "@ethersproject/providers" "^5.7.1" @@ -1409,12 +1390,12 @@ "@nomicfoundation/ethereumjs-rlp@5.0.2": version "5.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.2.tgz#4fee8dc58a53ac6ae87fb1fca7c15dc06c6b5dea" + resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.2.tgz" integrity sha512-QwmemBc+MMsHJ1P1QvPl8R8p2aPvvVcKBbvHnQOKBpBztEo0omN0eaob6FeZS/e3y9NSe+mfu3nNFBHszqkjTA== "@nomicfoundation/ethereumjs-statemanager@2.0.2": version "2.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-2.0.2.tgz#3ba4253b29b1211cafe4f9265fee5a0d780976e0" + resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-2.0.2.tgz" integrity sha512-dlKy5dIXLuDubx8Z74sipciZnJTRSV/uHG48RSijhgm1V7eXYFC567xgKtsKiVZB1ViTP9iFL4B6Je0xD6X2OA== dependencies: "@nomicfoundation/ethereumjs-common" "4.0.2" @@ -1426,7 +1407,7 @@ "@nomicfoundation/ethereumjs-trie@6.0.2": version "6.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-6.0.2.tgz#9a6dbd28482dca1bc162d12b3733acab8cd12835" + resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-6.0.2.tgz" integrity sha512-yw8vg9hBeLYk4YNg5MrSJ5H55TLOv2FSWUTROtDtTMMmDGROsAu+0tBjiNGTnKRi400M6cEzoFfa89Fc5k8NTQ== dependencies: "@nomicfoundation/ethereumjs-rlp" "5.0.2" @@ -1437,7 +1418,7 @@ "@nomicfoundation/ethereumjs-tx@5.0.2": version "5.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.2.tgz#117813b69c0fdc14dd0446698a64be6df71d7e56" + resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.2.tgz" integrity sha512-T+l4/MmTp7VhJeNloMkM+lPU3YMUaXdcXgTGCf8+ZFvV9NYZTRLFekRwlG6/JMmVfIfbrW+dRRJ9A6H5Q/Z64g== dependencies: "@chainsafe/ssz" "^0.9.2" @@ -1449,7 +1430,7 @@ "@nomicfoundation/ethereumjs-util@9.0.2": version "9.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.2.tgz#16bdc1bb36f333b8a3559bbb4b17dac805ce904d" + resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.2.tgz" integrity sha512-4Wu9D3LykbSBWZo8nJCnzVIYGvGCuyiYLIJa9XXNVt1q1jUzHdB+sJvx95VGCpPkCT+IbLecW6yfzy3E1bQrwQ== dependencies: "@chainsafe/ssz" "^0.10.0" @@ -1458,7 +1439,7 @@ "@nomicfoundation/ethereumjs-vm@7.0.2": version "7.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-7.0.2.tgz#3b0852cb3584df0e18c182d0672a3596c9ca95e6" + resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-7.0.2.tgz" integrity sha512-Bj3KZT64j54Tcwr7Qm/0jkeZXJMfdcAtRBedou+Hx0dPOSIgqaIr0vvLwP65TpHbak2DmAq+KJbW2KNtIoFwvA== dependencies: "@nomicfoundation/ethereumjs-block" "5.0.2" @@ -1549,13 +1530,6 @@ "@nomicfoundation/solidity-analyzer-win32-ia32-msvc" "0.1.1" "@nomicfoundation/solidity-analyzer-win32-x64-msvc" "0.1.1" -"@nomiclabs/hardhat-web3@^2.0.0": - version "2.0.0" - resolved "https://registry.npmjs.org/@nomiclabs/hardhat-web3/-/hardhat-web3-2.0.0.tgz" - integrity sha512-zt4xN+D+fKl3wW2YlTX3k9APR3XZgPkxJYf36AcliJn3oujnKEVRZaHu0PhgLjO+gR+F/kiYayo9fgd2L8970Q== - dependencies: - "@types/bignumber.js" "^5.0.0" - "@npmcli/fs@^2.1.0": version "2.1.2" resolved "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz" @@ -1822,7 +1796,7 @@ "@openzeppelin/contracts@^2.5.1": version "2.5.1" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-2.5.1.tgz#c76e3fc57aa224da3718ec351812a4251289db31" + resolved "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-2.5.1.tgz" integrity sha512-qIy6tLx8rtybEsIOAlrM4J/85s2q2nPkDqj/Rx46VakBZ0LwtFhXIVub96LXHczQX0vaqmAueDqNPXtbSXSaYQ== "@parcel/watcher@2.0.4": @@ -1838,17 +1812,10 @@ resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== -"@pkgr/utils@^2.4.2": - version "2.4.2" - resolved "https://registry.yarnpkg.com/@pkgr/utils/-/utils-2.4.2.tgz#9e638bbe9a6a6f165580dc943f138fd3309a2cbc" - integrity sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw== - dependencies: - cross-spawn "^7.0.3" - fast-glob "^3.3.0" - is-glob "^4.0.3" - open "^9.1.0" - picocolors "^1.0.0" - tslib "^2.6.0" +"@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== "@safe-global/safe-contracts-v1.4.1@npm:@safe-global/safe-contracts@1.4.1": version "1.4.1" @@ -1867,10 +1834,10 @@ resolved "https://registry.yarnpkg.com/@safe-global/safe-modules-deployments/-/safe-modules-deployments-2.0.0.tgz#08a201a6ddc141714b475c8d205d0a0f6c73d7f2" integrity sha512-TIlZ2j/nqj5kK7cKHSwwYTJrXcata6nKMI+lm2oed70eAoKqFIMdCG0JQQzl5vy85xfu9KPJxS8bTUXH10YJsw== -"@scure/base@^1.1.3", "@scure/base@~1.1.0": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.3.tgz#8584115565228290a6c6c4961973e0903bb3df2f" - integrity sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q== +"@scure/base@^1.1.3", "@scure/base@~1.1.0", "@scure/base@~1.1.2": + version "1.1.6" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.6.tgz#8ce5d304b436e4c84f896e0550c83e4d88cb917d" + integrity sha512-ok9AWwhcgYuGG3Zfhyqg+zwl+Wn5uE+dwC0NV/2qQkx4dABbb/bx96vWu8NSj+BNjjSjno+JRYRjle1jV08k3g== "@scure/bip32@1.1.5": version "1.1.5" @@ -1890,6 +1857,15 @@ "@noble/hashes" "~1.3.1" "@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/bip39@1.1.1": version "1.1.1" resolved "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz" @@ -1976,19 +1952,19 @@ "@sigstore/bundle@^1.1.0": version "1.1.0" - resolved "https://registry.yarnpkg.com/@sigstore/bundle/-/bundle-1.1.0.tgz#17f8d813b09348b16eeed66a8cf1c3d6bd3d04f1" + resolved "https://registry.npmjs.org/@sigstore/bundle/-/bundle-1.1.0.tgz" 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" + resolved "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.2.1.tgz" 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" + resolved "https://registry.npmjs.org/@sigstore/sign/-/sign-1.0.0.tgz" integrity sha512-INxFVNQteLtcfGmcoldzV6Je0sbbfh9I16DM4yJPw3j5+TFP8X6uIiA18mvpEa9yyeycAKgPmOA3X9hVdVTPUA== dependencies: "@sigstore/bundle" "^1.1.0" @@ -1997,7 +1973,7 @@ "@sigstore/tuf@^1.0.3": version "1.0.3" - resolved "https://registry.yarnpkg.com/@sigstore/tuf/-/tuf-1.0.3.tgz#2a65986772ede996485728f027b0514c0b70b160" + resolved "https://registry.npmjs.org/@sigstore/tuf/-/tuf-1.0.3.tgz" integrity sha512-2bRovzs0nJZFlCN3rXirE4gwxCn97JNjMmwpecqlbgV9WcxX7WRuIrgzx/X7Ib7MYRbyUTpBYE0s2x6AmZXnlg== dependencies: "@sigstore/protobuf-specs" "^0.2.0" @@ -2008,11 +1984,6 @@ resolved "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz" integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== -"@sindresorhus/is@^4.0.0", "@sindresorhus/is@^4.6.0": - version "4.6.0" - resolved "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz" - integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== - "@sinonjs/commons@^1.7.0": version "1.8.6" resolved "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz" @@ -2067,23 +2038,9 @@ "@stripe/stripe-js@^1.54.2": version "1.54.2" - resolved "https://registry.yarnpkg.com/@stripe/stripe-js/-/stripe-js-1.54.2.tgz#0665848e22cbda936cfd05256facdfbba121438d" + resolved "https://registry.npmjs.org/@stripe/stripe-js/-/stripe-js-1.54.2.tgz" integrity sha512-R1PwtDvUfs99cAjfuQ/WpwJ3c92+DAMy9xGApjqlWQMj0FKQabUAys2swfTRNzuYAYJh7NqK2dzcYVNkKLEKUg== -"@szmarczak/http-timer@^4.0.5": - version "4.0.6" - resolved "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz" - integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w== - dependencies: - defer-to-connect "^2.0.0" - -"@szmarczak/http-timer@^5.0.1": - version "5.0.1" - resolved "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz" - integrity sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw== - dependencies: - defer-to-connect "^2.0.1" - "@tootallnate/once@2": version "2.0.0" resolved "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz" @@ -2221,28 +2178,12 @@ "@tufjs/models@1.0.4": version "1.0.4" - resolved "https://registry.yarnpkg.com/@tufjs/models/-/models-1.0.4.tgz#5a689630f6b9dbda338d4b208019336562f176ef" + resolved "https://registry.npmjs.org/@tufjs/models/-/models-1.0.4.tgz" integrity sha512-qaGV9ltJP0EO25YfFUPhxRVK0evXFIAGicsVXuRim4Ed9cjPxYhNnNJ49SFmbeLgtxpslIkX317IgpfcHPVj/A== dependencies: "@tufjs/canonical-json" "1.0.0" minimatch "^9.0.0" -"@typechain/ethers-v6@^0.5.0": - version "0.5.0" - resolved "https://registry.npmjs.org/@typechain/ethers-v6/-/ethers-v6-0.5.0.tgz" - integrity sha512-wsz7AvbY5n2uVwpS2RHDYsW6wYOrhWxeTLFpxuzhO62w/ZDQEVIipArX731KA/hdqygP2zJ2RTkVXgzU1WrU1g== - dependencies: - lodash "^4.17.15" - ts-essentials "^7.0.1" - -"@typechain/web3-v1@^6.0.7": - version "6.0.7" - resolved "https://registry.yarnpkg.com/@typechain/web3-v1/-/web3-v1-6.0.7.tgz#7da0b3bcdb16a173b73f9e3c9d5a47daffe65138" - integrity sha512-HWkGplyPL3eWiP0sszqKZh6Bjrdm23srtirUdKp/4BEWKp/o6zofLt8lDn468bRQlQdHaobrbfEeT+3gf/r4eg== - dependencies: - lodash "^4.17.15" - ts-essentials "^7.0.1" - "@types/babel__core@^7.1.14": version "7.20.0" resolved "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.0.tgz" @@ -2276,20 +2217,6 @@ dependencies: "@babel/types" "^7.3.0" -"@types/bignumber.js@^5.0.0": - version "5.0.0" - resolved "https://registry.npmjs.org/@types/bignumber.js/-/bignumber.js-5.0.0.tgz" - integrity sha512-0DH7aPGCClywOFaxxjE6UwpN2kQYe9LwuDQMv+zYA97j5GkOMo8e66LYT+a8JYU7jfmUFRZLa9KycxHDsKXJCA== - dependencies: - bignumber.js "*" - -"@types/bn.js@*", "@types/bn.js@^5.1.0", "@types/bn.js@^5.1.1": - version "5.1.1" - resolved "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz" - integrity sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g== - dependencies: - "@types/node" "*" - "@types/bn.js@^4.11.3": version "4.11.6" resolved "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz" @@ -2297,27 +2224,24 @@ dependencies: "@types/node" "*" -"@types/cacheable-request@^6.0.1", "@types/cacheable-request@^6.0.2": - version "6.0.3" - resolved "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz" - integrity sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw== +"@types/bn.js@^5.1.0": + version "5.1.1" + resolved "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz" + integrity sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g== dependencies: - "@types/http-cache-semantics" "*" - "@types/keyv" "^3.1.4" "@types/node" "*" - "@types/responselike" "^1.0.0" "@types/chai-as-promised@^7.1.8": version "7.1.8" - resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz#f2b3d82d53c59626b5d6bbc087667ccb4b677fe9" + resolved "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz" integrity sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw== dependencies: "@types/chai" "*" -"@types/chai@*", "@types/chai@^4.3.11": - version "4.3.11" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.11.tgz#e95050bf79a932cb7305dd130254ccdf9bde671c" - integrity sha512-qQR1dr2rGIHYlJulmr8Ioq3De0Le9E4MJ5AiaeAETJJpndT1uUNHsGFK3L/UIu+rbkQSdj8J/w2bCsBZc/Y5fQ== +"@types/chai@*", "@types/chai@^4.3.16": + version "4.3.16" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.16.tgz#b1572967f0b8b60bf3f87fe1d854a5604ea70c82" + integrity sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ== "@types/debug@^4.1.7": version "4.1.12" @@ -2333,11 +2257,6 @@ dependencies: "@types/node" "*" -"@types/http-cache-semantics@*": - version "4.0.1" - resolved "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz" - integrity sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ== - "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": version "2.0.4" resolved "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz" @@ -2357,10 +2276,10 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@^29.5.11": - version "29.5.11" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.11.tgz#0c13aa0da7d0929f078ab080ae5d4ced80fa2f2c" - integrity sha512-S2mHmYIVe13vrm6q4kN6fLYYAka15ALQki/vgDC3mIukEOx8WJlv0kQPM+d4w8Gp6u0uSdKND04IlTXBv0rwnQ== +"@types/jest@^29.5.12": + 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" @@ -2379,13 +2298,6 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== -"@types/keyv@^3.1.4": - version "3.1.4" - resolved "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz" - integrity sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg== - dependencies: - "@types/node" "*" - "@types/lru-cache@^5.1.0": version "5.1.1" resolved "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz" @@ -2411,17 +2323,17 @@ resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.34.tgz#10964ba0dee6ac4cd462e2795b6bebd407303433" integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g== -"@types/node-fetch@^2.6.9": - version "2.6.9" - resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.9.tgz#15f529d247f1ede1824f7e7acdaa192d5f28071e" - integrity sha512-bQVlnMLFJ2d35DkPNjEPmd9ueO/rh5EiaZt2bhqiSarPjZIuIV6bPQVqcrEyvNo+AfTrRGVazle1tl597w3gfA== +"@types/node-fetch@^2.6.11": + version "2.6.11" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.11.tgz#9b39b78665dae0e82a08f02f4967d62c66f95d24" + integrity sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g== dependencies: "@types/node" "*" form-data "^4.0.0" "@types/node@*", "@types/node@^18.18.8": version "18.18.9" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.18.9.tgz#5527ea1832db3bba8eb8023ce8497b7d3f299592" + resolved "https://registry.npmjs.org/@types/node/-/node-18.18.9.tgz" integrity sha512-0f5klcuImLnG4Qreu9hPj/rEfFq6YRc5n2mAjSsH+ec/mJL+3voBH0+8T7o8RpFjH7ovc+TRsL/c7OYIQsPTfQ== dependencies: undici-types "~5.26.4" @@ -2431,11 +2343,6 @@ resolved "https://registry.npmjs.org/@types/node/-/node-18.15.13.tgz" integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== -"@types/node@^12.12.6": - version "12.20.55" - resolved "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz" - integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== - "@types/normalize-package-data@^2.4.0": version "2.4.1" resolved "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz" @@ -2448,11 +2355,6 @@ dependencies: "@types/node" "*" -"@types/prettier@^2.1.1": - version "2.7.2" - resolved "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz" - integrity sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg== - "@types/qs@^6.9.7": version "6.9.7" resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz" @@ -2466,13 +2368,6 @@ "@types/node" "*" safe-buffer "~5.1.1" -"@types/responselike@^1.0.0": - version "1.0.0" - resolved "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz" - integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA== - dependencies: - "@types/node" "*" - "@types/secp256k1@^4.0.1": version "4.0.3" resolved "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz" @@ -2480,14 +2375,14 @@ dependencies: "@types/node" "*" -"@types/semver@^7.5.0", "@types/semver@^7.5.6": - version "7.5.6" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.6.tgz#c65b2bfce1bec346582c07724e3f8c1017a20339" - integrity sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A== +"@types/semver@^7.5.0", "@types/semver@^7.5.8": + version "7.5.8" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e" + integrity sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ== "@types/sinon-chai@^3.2.11": version "3.2.12" - resolved "https://registry.yarnpkg.com/@types/sinon-chai/-/sinon-chai-3.2.12.tgz#c7cb06bee44a534ec84f3a5534c3a3a46fd779b6" + resolved "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.12.tgz" integrity sha512-9y0Gflk3b0+NhQZ/oxGtaAJDvRywCa5sIyaVnounqLvmf93yBF4EgIRspePtkMs3Tr844nCclYMlcCNmLCvjuQ== dependencies: "@types/chai" "*" @@ -2515,18 +2410,12 @@ resolved "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.2.tgz" integrity sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw== -"@types/underscore@*": - version "1.11.4" - resolved "https://registry.npmjs.org/@types/underscore/-/underscore-1.11.4.tgz" - integrity sha512-uO4CD2ELOjw8tasUrAhvnn2W4A0ZECOvMjCivJr4gA9pGgjv+qxKWY9GLTMVEK8ej85BxQOocUyE7hImmSQYcg== - -"@types/web3@1.0.20": - version "1.0.20" - resolved "https://registry.npmjs.org/@types/web3/-/web3-1.0.20.tgz" - integrity sha512-KTDlFuYjzCUlBDGt35Ir5QRtyV9klF84MMKUsEJK10sTWga/71V+8VYLT7yysjuBjaOx2uFYtIWNGoz3yrNDlg== +"@types/ws@8.5.3": + version "8.5.3" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" + integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== dependencies: - "@types/bn.js" "*" - "@types/underscore" "*" + "@types/node" "*" "@types/yargs-parser@*": version "21.0.0" @@ -2627,7 +2516,7 @@ "@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" + resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz" integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== "@web3auth/safeauth-embed@^0.0.0": @@ -2689,11 +2578,26 @@ abbrev@^1.0.0: resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== +abitype@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/abitype/-/abitype-0.7.1.tgz#16db20abe67de80f6183cf75f3de1ff86453b745" + integrity sha512-VBkRHTDZf9Myaek/dO3yMmOzB/y2s3Zo6nVU7yaw1G+TvCHAjwaJzNGN9yo4K5D8bU/VZXKP1EJpRhFr862PlQ== + +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.1.6: version "0.1.8" resolved "https://registry.npmjs.org/abitype/-/abitype-0.1.8.tgz" integrity sha512-2pde0KepTzdfu19ZrzYTYVIWo69+6UbBCY4B1RDiwWgo2XZtFSJhF6C+XThuRXbbZ823J0Rw1Y5cP0NXYVcCdQ== +abitype@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/abitype/-/abitype-1.0.2.tgz#183c28f2f3b4278810ed1543941b555bb73f301d" + integrity sha512-aFt4k2H+eiAKy/zxtnORa9iIb10BMBeWL18l8v4+QuwYEBXPxxjSB1bFZCzQmKPoj8m7j68K705l3uY+E2gAjg== + abort-controller@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz" @@ -2701,11 +2605,6 @@ abort-controller@^3.0.0: dependencies: event-target-shim "^5.0.0" -abortcontroller-polyfill@^1.7.5: - version "1.7.5" - resolved "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz" - integrity sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ== - abstract-level@^1.0.0, abstract-level@^1.0.2, abstract-level@^1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/abstract-level/-/abstract-level-1.0.3.tgz" @@ -2719,14 +2618,6 @@ abstract-level@^1.0.0, abstract-level@^1.0.2, abstract-level@^1.0.3: module-error "^1.0.1" queue-microtask "^1.2.3" -accepts@~1.3.8: - version "1.3.8" - resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz" - integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== - dependencies: - mime-types "~2.1.34" - negotiator "0.6.3" - acorn-globals@^7.0.0: version "7.0.1" resolved "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz" @@ -2747,7 +2638,7 @@ acorn-walk@^8.0.2, acorn-walk@^8.1.1: acorn@^8.1.0, acorn@^8.4.1, acorn@^8.8.1, acorn@^8.9.0: version "8.11.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.2.tgz#ca0d78b51895be5390a5903c5b3bdcdaf78ae40b" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz" integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w== add-stream@^1.0.0: @@ -2794,7 +2685,7 @@ aggregate-error@^3.0.0: clean-stack "^2.0.0" indent-string "^4.0.0" -ajv@^6.12.3, ajv@^6.12.4: +ajv@^6.12.4: version "6.12.6" resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -2823,7 +2714,7 @@ ansi-escapes@^4.2.1, ansi-escapes@^4.3.0: ansi-escapes@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-5.0.0.tgz#b6a0caf0eef0c41af190e9a749e0c00ec04bb2a6" + resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz" integrity sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA== dependencies: type-fest "^1.0.2" @@ -2912,26 +2803,11 @@ argparse@^2.0.1: resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -array-back@^3.0.1, array-back@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz" - integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q== - -array-back@^4.0.1, array-back@^4.0.2: - version "4.0.2" - resolved "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz" - integrity sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg== - array-differ@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz" integrity sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg== -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz" - integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== - array-ify@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz" @@ -2952,28 +2828,11 @@ arrify@^2.0.1: resolved "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz" integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== -asn1@~0.2.3: - version "0.2.6" - resolved "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz" - integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" - integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== - assertion-error@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz" integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== -async-limiter@~1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz" - integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== - async-mutex@^0.4.0: version "0.4.0" resolved "https://registry.npmjs.org/async-mutex/-/async-mutex-0.4.0.tgz" @@ -2996,19 +2855,9 @@ available-typed-arrays@^1.0.5: resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz" - integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA== - -aws4@^1.8.0: - version "1.12.0" - resolved "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz" - integrity sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg== - axios@0.27.2: version "0.27.2" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972" + resolved "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz" integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ== dependencies: follow-redirects "^1.14.9" @@ -3032,7 +2881,7 @@ axios@^1.0.0: babel-jest@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" + resolved "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz" integrity sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg== dependencies: "@jest/transform" "^29.7.0" @@ -3056,7 +2905,7 @@ babel-plugin-istanbul@^6.1.1: 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" + resolved "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz" integrity sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg== dependencies: "@babel/template" "^7.3.3" @@ -3084,7 +2933,7 @@ babel-preset-current-node-syntax@^1.0.0: 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" + resolved "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz" integrity sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA== dependencies: babel-plugin-jest-hoist "^29.6.3" @@ -3095,7 +2944,7 @@ balanced-match@^1.0.0: resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base-x@^3.0.2, base-x@^3.0.8: +base-x@^3.0.2: version "3.0.9" resolved "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz" integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== @@ -3112,13 +2961,6 @@ base64url@^3.0.1: resolved "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz" integrity sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A== -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz" - integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== - dependencies: - tweetnacl "^0.14.3" - bech32@1.1.4: version "1.1.4" resolved "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz" @@ -3129,17 +2971,12 @@ before-after-hook@^2.2.0: resolved "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz" integrity sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ== -big-integer@^1.6.44: - version "1.6.52" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.52.tgz#60a887f3047614a8e1bffe5d7173490a97dc8c85" - integrity sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg== - bigint-crypto-utils@^3.0.23: version "3.2.2" resolved "https://registry.npmjs.org/bigint-crypto-utils/-/bigint-crypto-utils-3.2.2.tgz" integrity sha512-U1RbE3aX9ayCUVcIPHuPDPKcK3SFOXf93J1UK/iHlJuQB7bhagPIX06/CLpLEsDThJ7KA4Dhrnzynl+d2weTiw== -bignumber.js@*, bignumber.js@^9.0.0, bignumber.js@^9.1.2: +bignumber.js@^9.1.2: 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== @@ -3163,17 +3000,7 @@ blakejs@^1.1.0: resolved "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz" integrity sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ== -bluebird@^3.5.0: - version "3.7.2" - resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz" - integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== - -bn.js@4.11.6: - version "4.11.6" - resolved "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz" - integrity sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA== - -bn.js@^4.11.0, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.11.9: +bn.js@^4.11.0, bn.js@^4.11.8, bn.js@^4.11.9: version "4.12.0" resolved "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== @@ -3183,36 +3010,11 @@ bn.js@^5.1.2, bn.js@^5.2.0, bn.js@^5.2.1: resolved "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz" integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== -body-parser@1.20.2, body-parser@^1.16.0: - version "1.20.2" - resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz" - integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== - dependencies: - bytes "3.1.2" - content-type "~1.0.5" - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - http-errors "2.0.0" - iconv-lite "0.4.24" - on-finished "2.4.1" - qs "6.11.0" - raw-body "2.5.2" - type-is "~1.6.18" - unpipe "1.0.0" - bowser@^2.11.0: version "2.11.0" resolved "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz" integrity sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA== -bplist-parser@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.2.0.tgz#43a9d183e5bf9d545200ceac3e712f79ebbe8d0e" - integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw== - dependencies: - big-integer "^1.6.44" - brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" @@ -3268,14 +3070,14 @@ browserify-aes@^1.2.0: safe-buffer "^5.0.1" browserslist@^4.21.3: - version "4.21.5" - resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz" - integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== + version "4.22.1" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz" + integrity sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ== dependencies: - caniuse-lite "^1.0.30001449" - electron-to-chromium "^1.4.284" - node-releases "^2.0.8" - update-browserslist-db "^1.0.10" + caniuse-lite "^1.0.30001541" + electron-to-chromium "^1.4.535" + node-releases "^2.0.13" + update-browserslist-db "^1.0.13" bs-logger@0.x: version "0.2.6" @@ -3312,17 +3114,12 @@ buffer-from@^1.0.0: resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -buffer-to-arraybuffer@^0.0.5: - version "0.0.5" - resolved "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz" - integrity sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ== - buffer-xor@^1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz" integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ== -buffer@^5.0.5, buffer@^5.5.0, buffer@^5.6.0: +buffer@^5.5.0: version "5.7.1" resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz" integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== @@ -3338,13 +3135,6 @@ buffer@^6.0.3: base64-js "^1.3.1" ieee754 "^1.2.1" -bufferutil@^4.0.1: - version "4.0.8" - resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.8.tgz#1de6a71092d65d7766c4d8a522b261a6e787e8ea" - integrity sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw== - dependencies: - node-gyp-build "^4.3.0" - builtins@^1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz" @@ -3357,13 +3147,6 @@ builtins@^5.0.0: dependencies: semver "^7.0.0" -bundle-name@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bundle-name/-/bundle-name-3.0.0.tgz#ba59bcc9ac785fb67ccdbf104a2bf60c099f0e1a" - integrity sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw== - dependencies: - run-applescript "^5.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" @@ -3417,29 +3200,6 @@ cacache@^17.0.0: tar "^6.1.11" unique-filename "^3.0.0" -cacheable-lookup@^5.0.3: - version "5.0.4" - resolved "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz" - integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== - -cacheable-lookup@^6.0.4: - version "6.1.0" - resolved "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz" - integrity sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww== - -cacheable-request@^7.0.2: - version "7.0.2" - resolved "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz" - integrity sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew== - dependencies: - clone-response "^1.0.2" - get-stream "^5.1.0" - http-cache-semantics "^4.0.0" - keyv "^4.0.0" - lowercase-keys "^2.0.0" - normalize-url "^6.0.1" - responselike "^2.0.0" - caching-transform@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz" @@ -3450,13 +3210,14 @@ caching-transform@^4.0.0: package-hash "^4.0.0" write-file-atomic "^3.0.0" -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== +call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz" + integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" + function-bind "^1.1.2" + get-intrinsic "^1.2.1" + set-function-length "^1.1.1" callsites@^3.0.0: version "3.1.0" @@ -3482,21 +3243,16 @@ camelcase@^6.0.0, camelcase@^6.2.0: resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001449: - version "1.0.30001478" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001478.tgz" - integrity sha512-gMhDyXGItTHipJj2ApIvR+iVB5hd0KP3svMWWXDvZOmjzJJassGLMfxRkQCSYgGd2gtdL/ReeiyvMSFD1Ss6Mw== +caniuse-lite@^1.0.30001541: + version "1.0.30001563" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001563.tgz" + integrity sha512-na2WUmOxnwIZtwnFI2CZ/3er0wdNzU7hN+cPYz/z2ajHThnkWjNBOpEPP4n+4r2WPM847JaMotaJE3bnfzjyKw== case@^1.6.3: version "1.6.3" resolved "https://registry.npmjs.org/case/-/case-1.6.3.tgz" integrity sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ== -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz" - integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== - catering@^2.1.0, catering@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/catering/-/catering-2.1.1.tgz" @@ -3511,7 +3267,7 @@ chai-as-promised@^7.1.1: chai@^4.3.10: version "4.3.10" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.10.tgz#d784cec635e3b7e2ffb66446a63b4e33bd390384" + resolved "https://registry.npmjs.org/chai/-/chai-4.3.10.tgz" integrity sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g== dependencies: assertion-error "^1.1.0" @@ -3532,7 +3288,7 @@ chalk@4.1.0: chalk@5.3.0: version "5.3.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.3.0.tgz#67c20a7ebef70e7f3970a01f90fa210cb6860385" + resolved "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz" integrity sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w== chalk@^2.4.2: @@ -3564,7 +3320,7 @@ chardet@^0.7.0: check-error@^1.0.2, check-error@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.3.tgz#a6502e4312a7ee969f646e83bb3ddd56281bd694" + resolved "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz" integrity sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg== dependencies: get-func-name "^2.0.2" @@ -3584,11 +3340,6 @@ chokidar@3.5.3, chokidar@^3.4.0, chokidar@^3.5.2, chokidar@^3.5.3: optionalDependencies: fsevents "~2.3.2" -chownr@^1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz" - integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== - chownr@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz" @@ -3601,20 +3352,9 @@ ci-info@^2.0.0: 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" + resolved "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz" integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== -cids@^0.7.1: - version "0.7.5" - resolved "https://registry.npmjs.org/cids/-/cids-0.7.5.tgz" - integrity sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA== - dependencies: - buffer "^5.5.0" - class-is "^1.1.0" - multibase "~0.6.0" - multicodec "^1.0.0" - multihashes "~0.4.15" - cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" resolved "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz" @@ -3628,11 +3368,6 @@ cjs-module-lexer@^1.0.0: resolved "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz" integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== -class-is@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz" - integrity sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw== - classic-level@^1.2.0: version "1.3.0" resolved "https://registry.npmjs.org/classic-level/-/classic-level-1.3.0.tgz" @@ -3658,7 +3393,7 @@ cli-cursor@3.1.0, cli-cursor@^3.1.0: cli-cursor@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-4.0.0.tgz#3cecfe3734bf4fe02a8361cbdc0f6fe28c6a57ea" + resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz" integrity sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg== dependencies: restore-cursor "^4.0.0" @@ -3722,13 +3457,6 @@ clone-deep@4.0.1: kind-of "^6.0.2" shallow-clone "^3.0.0" -clone-response@^1.0.2: - version "1.0.3" - resolved "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz" - integrity sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA== - dependencies: - mimic-response "^1.0.0" - clone@^1.0.2: version "1.0.4" resolved "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz" @@ -3780,7 +3508,7 @@ color-support@^1.1.3: colorette@^2.0.20: version "2.0.20" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" + resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz" integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== columnify@1.6.0: @@ -3791,7 +3519,7 @@ columnify@1.6.0: strip-ansi "^6.0.1" wcwidth "^1.0.0" -combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: +combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -3803,29 +3531,9 @@ command-exists@^1.2.8: resolved "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz" integrity sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w== -command-line-args@^5.1.1: - version "5.2.1" - resolved "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz" - integrity sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg== - dependencies: - array-back "^3.1.0" - find-replace "^3.0.0" - lodash.camelcase "^4.3.0" - typical "^4.0.0" - -command-line-usage@^6.1.0: - version "6.1.3" - resolved "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.3.tgz" - integrity sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw== - dependencies: - array-back "^4.0.2" - chalk "^2.4.2" - table-layout "^1.0.2" - typical "^5.2.0" - commander@11.0.0: version "11.0.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-11.0.0.tgz#43e19c25dbedc8256203538e8d7e9346877a6f67" + resolved "https://registry.npmjs.org/commander/-/commander-11.0.0.tgz" integrity sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ== commander@3.0.2: @@ -3871,27 +3579,6 @@ console-control-strings@^1.1.0: resolved "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz" integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== -content-disposition@0.5.4: - version "0.5.4" - resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz" - integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== - dependencies: - safe-buffer "5.2.1" - -content-hash@^2.5.2: - version "2.5.2" - resolved "https://registry.npmjs.org/content-hash/-/content-hash-2.5.2.tgz" - integrity sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw== - dependencies: - cids "^0.7.1" - multicodec "^0.5.5" - multihashes "^0.4.15" - -content-type@~1.0.4, content-type@~1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz" - integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== - 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" @@ -3975,39 +3662,16 @@ convert-source-map@^2.0.0: resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz" integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" - integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== - -cookie@0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" - integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== - cookie@^0.4.1: version "0.4.2" resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz" integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== -core-util-is@1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" - integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== - core-util-is@~1.0.0: version "1.0.3" resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== -cors@^2.8.1: - version "2.8.5" - resolved "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz" - integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== - dependencies: - object-assign "^4" - vary "^1" - cosmiconfig@^8.2.0: version "8.3.6" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3" @@ -4018,7 +3682,7 @@ cosmiconfig@^8.2.0: parse-json "^5.2.0" path-type "^4.0.0" -crc-32@^1.2.0: +crc-32@^1.2.0, crc-32@^1.2.2: version "1.2.2" resolved "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz" integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ== @@ -4053,7 +3717,7 @@ create-hmac@^1.1.4, create-hmac@^1.1.7: create-jest@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/create-jest/-/create-jest-29.7.0.tgz#a355c5b3cb1e1af02ba177fe7afd7feee49a5320" + resolved "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz" integrity sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q== dependencies: "@jest/types" "^29.6.3" @@ -4107,26 +3771,11 @@ cssstyle@^2.3.0: dependencies: cssom "~0.3.6" -d@1, d@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/d/-/d-1.0.1.tgz" - integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== - dependencies: - es5-ext "^0.10.50" - type "^1.0.1" - dargs@^7.0.0: version "7.0.0" resolved "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz" integrity sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg== -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz" - integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g== - dependencies: - assert-plus "^1.0.0" - data-urls@^3.0.2: version "3.0.2" resolved "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz" @@ -4141,14 +3790,7 @@ dateformat@^3.0.3: resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== -debug@2.6.9, debug@^2.2.0: - version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -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, debug@~4.3.1, debug@~4.3.2: +debug@4, debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2: version "4.3.4" resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -4178,25 +3820,6 @@ decimal.js@^10.4.2: resolved "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz" integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== -decode-uri-component@^0.2.0: - version "0.2.2" - resolved "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz" - integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== - -decompress-response@^3.3.0: - version "3.3.0" - resolved "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz" - integrity sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA== - dependencies: - mimic-response "^1.0.0" - -decompress-response@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz" - integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== - dependencies: - mimic-response "^3.1.0" - dedent@0.7.0: version "0.7.0" resolved "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz" @@ -4204,7 +3827,7 @@ dedent@0.7.0: dedent@^1.0.0: version "1.5.1" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.5.1.tgz#4f3fc94c8b711e9bb2800d185cd6ad20f2a90aff" + resolved "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz" integrity sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg== deep-eql@^4.1.3: @@ -4214,11 +3837,6 @@ deep-eql@^4.1.3: dependencies: type-detect "^4.0.0" -deep-extend@~0.6.0: - version "0.6.0" - resolved "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - deep-is@^0.1.3, deep-is@~0.1.3: version "0.1.4" resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" @@ -4229,24 +3847,6 @@ deepmerge@^4.2.2: resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz" integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== -default-browser-id@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-3.0.0.tgz#bee7bbbef1f4e75d31f98f4d3f1556a14cea790c" - integrity sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA== - dependencies: - bplist-parser "^0.2.0" - untildify "^4.0.0" - -default-browser@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/default-browser/-/default-browser-4.0.0.tgz#53c9894f8810bf86696de117a6ce9085a3cbc7da" - integrity sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA== - dependencies: - bundle-name "^3.0.0" - default-browser-id "^3.0.0" - execa "^7.1.1" - titleize "^3.0.0" - default-require-extensions@^3.0.0: version "3.0.1" resolved "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz" @@ -4261,21 +3861,20 @@ defaults@^1.0.3: dependencies: clone "^1.0.2" -defer-to-connect@^2.0.0, defer-to-connect@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz" - integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== +define-data-property@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz" + integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== + dependencies: + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" define-lazy-prop@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz" integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== -define-lazy-prop@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" - integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== - delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" @@ -4296,11 +3895,6 @@ deprecation@^2.0.0: resolved "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz" integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== -destroy@1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz" - integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== - detect-indent@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz" @@ -4313,7 +3907,7 @@ detect-newline@^3.0.0: diff-sequences@^29.6.3: version "29.6.3" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" + resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz" integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== diff@5.0.0: @@ -4345,11 +3939,6 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -dom-walk@^0.1.0: - version "0.1.2" - resolved "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz" - integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== - domexception@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz" @@ -4369,7 +3958,12 @@ dotenv-expand@~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, dotenv@~16.3.1: +dotenv@^16.4.5: + version "16.4.5" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" + integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== + +dotenv@~16.3.1: version "16.3.1" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== @@ -4384,19 +3978,6 @@ eastasianwidth@^0.2.0: resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz" integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz" - integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw== - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" - integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== - ejs@^3.1.7: version "3.1.10" resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.10.tgz#69ab8358b14e896f80cc39e62087b88500c3ac3b" @@ -4404,12 +3985,12 @@ ejs@^3.1.7: dependencies: jake "^10.8.5" -electron-to-chromium@^1.4.284: - version "1.4.363" - resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.363.tgz" - integrity sha512-ReX5qgmSU7ybhzMuMdlJAdYnRhT90UB3k9M05O5nF5WH3wR5wgdJjXw0uDeFyKNhmglmQiOxkAbzrP0hMKM59g== +electron-to-chromium@^1.4.535: + version "1.4.589" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.589.tgz" + integrity sha512-zF6y5v/YfoFIgwf2dDfAqVlPPsyQeWNpEWXbAlDUS8Ax4Z2VoiiZpAPC0Jm9hXEkJm2vIZpwB6rc4KnLTQffbQ== -elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.4: +elliptic@6.5.4, elliptic@^6.5.2, elliptic@^6.5.4: version "6.5.4" resolved "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz" integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== @@ -4442,11 +4023,6 @@ encode-utf8@^1.0.2: resolved "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz" integrity sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw== -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" - integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== - encoding@^0.1.13: version "0.1.13" resolved "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz" @@ -4511,52 +4087,16 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es5-ext@^0.10.35, es5-ext@^0.10.50: - version "0.10.62" - resolved "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz" - integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA== - dependencies: - es6-iterator "^2.0.3" - es6-symbol "^3.1.3" - next-tick "^1.1.0" - es6-error@^4.0.1: version "4.1.1" resolved "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz" integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== -es6-iterator@^2.0.3: - version "2.0.3" - resolved "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz" - integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g== - dependencies: - d "1" - es5-ext "^0.10.35" - es6-symbol "^3.1.1" - -es6-promise@^4.2.8: - version "4.2.8" - resolved "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz" - integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== - -es6-symbol@^3.1.1, es6-symbol@^3.1.3: - version "3.1.3" - resolved "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz" - integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== - dependencies: - d "^1.0.1" - ext "^1.1.2" - escalade@^3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" - integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== - escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" @@ -4589,17 +4129,17 @@ eslint-config-prettier@^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-plugin-prettier@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.1.tgz#a3b399f04378f79f066379f544e42d6b73f11515" - integrity sha512-m3u5RnR56asrwV/lDC4GHorlW75DsFfmUcjfCYylTUs85dBRnB7VM6xG8eCMJdeDRnppzmxZVf1GEPJvl1JmNg== +eslint-plugin-prettier@^5.1.3: + 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.5" + synckit "^0.8.6" eslint-scope@^7.2.2: version "7.2.2" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz" integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== dependencies: esrecurse "^4.3.0" @@ -4607,7 +4147,7 @@ eslint-scope@^7.2.2: 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" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== eslint@^8.56.0: @@ -4656,7 +4196,7 @@ eslint@^8.56.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" + resolved "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz" integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== dependencies: acorn "^8.9.0" @@ -4692,40 +4232,6 @@ esutils@^2.0.2: resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz" - integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== - -eth-ens-namehash@2.0.8: - version "2.0.8" - resolved "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz" - integrity sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw== - dependencies: - idna-uts46-hx "^2.3.1" - js-sha3 "^0.5.7" - -eth-lib@0.2.8: - version "0.2.8" - resolved "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz" - integrity sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw== - dependencies: - bn.js "^4.11.6" - elliptic "^6.4.0" - xhr-request-promise "^0.1.2" - -eth-lib@^0.1.26: - version "0.1.29" - resolved "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz" - integrity sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ== - dependencies: - bn.js "^4.11.6" - elliptic "^6.4.0" - nano-json-stream-parser "^0.1.2" - servify "^0.1.12" - ws "^3.0.0" - xhr-request-promise "^0.1.2" - eth-testing@^1.14.0: version "1.14.0" resolved "https://registry.npmjs.org/eth-testing/-/eth-testing-1.14.0.tgz" @@ -4734,13 +4240,6 @@ eth-testing@^1.14.0: abitype "^0.1.6" ethers "^5.5.4" -ethereum-bloom-filters@^1.0.6: - version "1.0.10" - resolved "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz" - 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.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz" @@ -4816,7 +4315,7 @@ ethereumjs-util@^7.1.5: ethers@6.7.0: version "6.7.0" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.7.0.tgz#0f772c31a9450de28aa518b181c8cb269bbe7fd1" + resolved "https://registry.npmjs.org/ethers/-/ethers-6.7.0.tgz" integrity sha512-pxt5hK82RNwcTX2gOZP81t6qVPVspnkpeivwEgQuK9XUvbNtghBnT8GNIb/gPh+WnVSfi8cXC9XlfT8sqc6D6w== dependencies: "@adraffy/ens-normalize" "1.9.2" @@ -4863,12 +4362,12 @@ ethers@^5.5.4, ethers@^5.7.0, ethers@^5.7.1: "@ethersproject/web" "5.7.1" "@ethersproject/wordlists" "5.7.0" -ethers@^6.7.1, ethers@^6.8.1: - version "6.8.1" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.8.1.tgz#ee2a1a39b5f62a13678f90ccd879175391d0a2b4" - integrity sha512-iEKm6zox5h1lDn6scuRWdIdFJUCGg3+/aQWu0F4K0GVyEZiktFkqrJbRjTn1FlYEPz7RKA707D6g5Kdk6j7Ljg== +ethers@^6.12.1, ethers@^6.8.1: + version "6.12.1" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.12.1.tgz#517ff6d66d4fd5433e38e903051da3e57c87ff37" + integrity sha512-j6wcVoZf06nqEcBbDWkKg8Fp895SS96dSnTCjiXT+8vt2o02raTn4Lo9ERUuIVU5bAjoPYeA+7ytQFexFmLuVw== dependencies: - "@adraffy/ens-normalize" "1.10.0" + "@adraffy/ens-normalize" "1.10.1" "@noble/curves" "1.2.0" "@noble/hashes" "1.3.2" "@types/node" "18.15.13" @@ -4876,14 +4375,6 @@ ethers@^6.7.1, ethers@^6.8.1: tslib "2.4.0" ws "8.5.0" -ethjs-unit@0.1.6: - version "0.1.6" - resolved "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz" - 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.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz" @@ -4897,11 +4388,6 @@ event-target-shim@^5.0.0: resolved "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz" integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== -eventemitter3@4.0.4: - version "4.0.4" - resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz" - integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ== - eventemitter3@^4.0.4: version "4.0.7" resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" @@ -4909,7 +4395,7 @@ eventemitter3@^4.0.4: eventemitter3@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" + resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz" integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== events@^3.3.0: @@ -4940,9 +4426,9 @@ execa@5.0.0: signal-exit "^3.0.3" strip-final-newline "^2.0.0" -execa@7.2.0, execa@^7.1.1: +execa@7.2.0: version "7.2.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-7.2.0.tgz#657e75ba984f42a70f38928cedc87d6f2d4fe4e9" + resolved "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz" integrity sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA== dependencies: cross-spawn "^7.0.3" @@ -4977,7 +4463,7 @@ exit@^0.1.2: expect@^29.0.0, expect@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc" + resolved "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz" integrity sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw== dependencies: "@jest/expect-utils" "^29.7.0" @@ -4986,55 +4472,6 @@ expect@^29.0.0, expect@^29.7.0: jest-message-util "^29.7.0" jest-util "^29.7.0" -express@^4.14.0: - version "4.19.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465" - integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q== - dependencies: - accepts "~1.3.8" - array-flatten "1.1.1" - body-parser "1.20.2" - content-disposition "0.5.4" - content-type "~1.0.4" - cookie "0.6.0" - cookie-signature "1.0.6" - debug "2.6.9" - depd "2.0.0" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "1.2.0" - fresh "0.5.2" - http-errors "2.0.0" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "2.4.1" - parseurl "~1.3.3" - path-to-regexp "0.1.7" - proxy-addr "~2.0.7" - qs "6.11.0" - range-parser "~1.2.1" - safe-buffer "5.2.1" - send "0.18.0" - serve-static "1.15.0" - setprototypeof "1.2.0" - statuses "2.0.1" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - -ext@^1.1.2: - version "1.7.0" - resolved "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz" - integrity sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw== - dependencies: - type "^2.7.2" - -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - external-editor@^3.0.3: version "3.1.0" resolved "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz" @@ -5044,16 +4481,6 @@ external-editor@^3.0.3: iconv-lite "^0.4.24" tmp "^0.0.33" -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz" - integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g== - -extsprintf@^1.2.0: - version "1.4.1" - resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz" - integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== - fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" @@ -5064,7 +4491,7 @@ fast-diff@^1.1.2: resolved "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz" integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== -fast-glob@^3.2.9, fast-glob@^3.3.0: +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== @@ -5137,19 +4564,6 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" -finalhandler@1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz" - integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "2.4.1" - parseurl "~1.3.3" - statuses "2.0.1" - unpipe "~1.0.0" - find-cache-dir@^3.2.0: version "3.3.2" resolved "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz" @@ -5159,13 +4573,6 @@ find-cache-dir@^3.2.0: make-dir "^3.0.2" pkg-dir "^4.1.0" -find-replace@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz" - integrity sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ== - dependencies: - array-back "^3.0.1" - find-up@5.0.0, find-up@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" @@ -5242,16 +4649,6 @@ foreground-child@^3.1.0: cross-spawn "^7.0.0" signal-exit "^4.0.1" -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz" - integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== - -form-data-encoder@1.7.1: - version "1.7.1" - resolved "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.1.tgz" - integrity sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg== - form-data@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz" @@ -5261,20 +4658,6 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -forwarded@0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz" - integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== - fp-ts@1.19.3: version "1.19.3" resolved "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz" @@ -5285,11 +4668,6 @@ fp-ts@^1.0.0: resolved "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.5.tgz" integrity sha512-wDNqTimnzs8QqpldiId9OavWK2NptormjXnRJTQecNjzwfyp6P/8s/zG8e4h3ja3oqkKaY72UlTjQYt/1yXf9A== -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" - integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== - fromentries@^1.2.0: version "1.3.2" resolved "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz" @@ -5329,31 +4707,15 @@ fs-extra@^11.1.0, fs-extra@^11.1.1: jsonfile "^6.0.1" universalify "^2.0.0" -fs-extra@^4.0.2: - version "4.0.3" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz" - integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== +fs-extra@^7.0.1: + version "7.0.1" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz" + integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== dependencies: graceful-fs "^4.1.2" jsonfile "^4.0.0" universalify "^0.1.0" -fs-extra@^7.0.0, fs-extra@^7.0.1: - version "7.0.1" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz" - integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-minipass@^1.2.7: - version "1.2.7" - resolved "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz" - integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== - dependencies: - minipass "^2.6.0" - fs-minipass@^2.0.0, fs-minipass@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz" @@ -5378,10 +4740,10 @@ fsevents@^2.3.2, fsevents@~2.3.2: resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +function-bind@^1.1.1, function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== functional-red-black-tree@^1.0.1: version "1.0.1" @@ -5417,14 +4779,15 @@ get-func-name@^2.0.0, get-func-name@^2.0.2: resolved "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz" integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.3: - version "1.2.0" - resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz" - integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q== +get-intrinsic@^1.0.2, get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: + version "1.2.2" + resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz" + integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== dependencies: - function-bind "^1.1.1" - has "^1.0.3" + 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" @@ -5451,25 +4814,11 @@ get-stream@6.0.0: resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz" integrity sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg== -get-stream@^5.1.0: - version "5.2.0" - resolved "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz" - integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== - dependencies: - pump "^3.0.0" - get-stream@^6.0.0, get-stream@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz" - integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng== - dependencies: - assert-plus "^1.0.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" @@ -5543,18 +4892,6 @@ glob@7.1.4: once "^1.3.0" path-is-absolute "^1.0.0" -glob@7.1.7: - version "7.1.7" - resolved "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz" - integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== - 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.npmjs.org/glob/-/glob-7.2.0.tgz" @@ -5611,14 +4948,6 @@ glob@^9.2.0, glob@^9.3.1: minipass "^4.2.4" path-scurry "^1.6.1" -global@~4.4.0: - version "4.4.0" - resolved "https://registry.npmjs.org/global/-/global-4.4.0.tgz" - integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== - dependencies: - min-document "^2.19.0" - process "^0.11.10" - globals@^11.1.0: version "11.12.0" resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" @@ -5650,42 +4979,6 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" -got@12.1.0: - version "12.1.0" - resolved "https://registry.npmjs.org/got/-/got-12.1.0.tgz" - integrity sha512-hBv2ty9QN2RdbJJMK3hesmSkFTjVIHyIDDbssCKnSmq62edGgImJWD10Eb1k77TiV1bxloxqcFAVK8+9pkhOig== - dependencies: - "@sindresorhus/is" "^4.6.0" - "@szmarczak/http-timer" "^5.0.1" - "@types/cacheable-request" "^6.0.2" - "@types/responselike" "^1.0.0" - cacheable-lookup "^6.0.4" - cacheable-request "^7.0.2" - decompress-response "^6.0.0" - form-data-encoder "1.7.1" - get-stream "^6.0.1" - http2-wrapper "^2.1.10" - lowercase-keys "^3.0.0" - p-cancelable "^3.0.0" - responselike "^2.0.0" - -got@^11.8.5: - version "11.8.6" - resolved "https://registry.npmjs.org/got/-/got-11.8.6.tgz" - integrity sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g== - dependencies: - "@sindresorhus/is" "^4.0.0" - "@szmarczak/http-timer" "^4.0.5" - "@types/cacheable-request" "^6.0.1" - "@types/responselike" "^1.0.0" - cacheable-lookup "^5.0.3" - cacheable-request "^7.0.2" - decompress-response "^6.0.0" - http2-wrapper "^1.0.0-beta.5.2" - lowercase-keys "^2.0.0" - p-cancelable "^2.0.0" - responselike "^2.0.0" - 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.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz" @@ -5693,7 +4986,7 @@ graceful-fs@4.2.11, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2 graphemer@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + resolved "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz" integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== handlebars@^4.7.7: @@ -5708,28 +5001,15 @@ handlebars@^4.7.7: optionalDependencies: uglify-js "^3.1.4" -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz" - integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q== - -har-validator@~5.1.3: - version "5.1.5" - resolved "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz" - integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== - dependencies: - ajv "^6.12.3" - har-schema "^2.0.0" - hard-rejection@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz" integrity sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA== -hardhat-deploy-ethers@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/hardhat-deploy-ethers/-/hardhat-deploy-ethers-0.4.1.tgz#dd70b0cc413ed99e98994047b383a004cf1c14f8" - integrity sha512-RM6JUcD0dOCjemxnKLtK7XQQI7NWn+LxF5qicGYax0PtWayEUXAewOb4WIHZ/yearhj+s2t6dL0MnHyLTENwJg== +hardhat-deploy-ethers@^0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/hardhat-deploy-ethers/-/hardhat-deploy-ethers-0.4.2.tgz#10aa44ef806ec8cf3d67ad9692f3762ed965b5e7" + integrity sha512-AskNH/XRYYYqPT94MvO5s1yMi+/QvoNjS4oU5VcVqfDU99kgpGETl+uIYHIrSXtH5sy7J6gyVjpRMf4x0tjLSQ== hardhat-deploy@^0.11.45: version "0.11.45" @@ -5762,9 +5042,9 @@ hardhat-deploy@^0.11.45: zksync-web3 "^0.14.3" hardhat@^2.19.3: - version "2.19.3" - resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.19.3.tgz#fe3b28b889e34a074ea5b740c227e3c8d4ce56e8" - integrity sha512-zUvfILiu1O7W1a+t5E1nCJ6z1danRLNizQkSEQCCgDYcRx13AGXtH1MVZajKmdLmXIjKAPReTp/8JQQ4ZHaX3g== + version "2.19.4" + resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.19.4.tgz#5112c30295d8be2e18e55d847373c50483ed1902" + integrity sha512-fTQJpqSt3Xo9Mn/WrdblNGAfcANM6XC3tAEi6YogB4s02DmTf93A8QsGb8uR0KR8TFcpcS8lgiW4ugAIYpnbrQ== dependencies: "@ethersproject/abi" "^5.1.2" "@metamask/eth-sig-util" "^4.0.0" @@ -5825,6 +5105,18 @@ has-flag@^4.0.0: resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-property-descriptors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz#52ba30b6c5ec87fd89fa574bc1c39125c6f65340" + integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg== + dependencies: + get-intrinsic "^1.2.2" + +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" @@ -5874,6 +5166,13 @@ hasha@^5.0.0: is-stream "^2.0.0" type-fest "^0.8.0" +hasown@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz" + integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== + dependencies: + function-bind "^1.1.2" + he@1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz" @@ -5926,7 +5225,7 @@ html-escaper@^2.0.0: resolved "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== -http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.0, http-cache-semantics@^4.1.1: +http-cache-semantics@^4.1.0, http-cache-semantics@^4.1.1: version "4.1.1" resolved "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz" integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== @@ -5942,11 +5241,6 @@ http-errors@2.0.0: statuses "2.0.1" toidentifier "1.0.1" -http-https@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz" - integrity sha512-o0PWwVCSp3O0wS6FvNr6xfBCHgt0m1tvPLFOCc2iFDKTRAXhB7m8klDf7ErowFH8POa6dVdGatKU5I1YYwzUyg== - http-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz" @@ -5956,31 +5250,6 @@ http-proxy-agent@^5.0.0: agent-base "6" debug "4" -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz" - integrity sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ== - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -http2-wrapper@^1.0.0-beta.5.2: - version "1.0.3" - resolved "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz" - integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg== - dependencies: - quick-lru "^5.1.1" - resolve-alpn "^1.0.0" - -http2-wrapper@^2.1.10: - version "2.2.0" - resolved "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.0.tgz" - integrity sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ== - dependencies: - quick-lru "^5.1.1" - resolve-alpn "^1.2.0" - https-proxy-agent@^5.0.0, https-proxy-agent@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz" @@ -6025,13 +5294,6 @@ iconv-lite@0.6.3, iconv-lite@^0.6.2: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" -idna-uts46-hx@^2.3.1: - version "2.3.1" - resolved "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz" - integrity sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA== - dependencies: - punycode "2.1.0" - ieee754@^1.1.13, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" @@ -6161,11 +5423,6 @@ ip@^2.0.0: resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.1.tgz#e8f3595d33a3ea66490204234b77636965307105" integrity sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ== -ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - is-arguments@^1.0.4: version "1.1.1" resolved "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz" @@ -6215,11 +5472,6 @@ is-docker@^2.0.0, is-docker@^2.1.1: resolved "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz" integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== -is-docker@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-3.0.0.tgz#90093aa3106277d8a77a5910dbae71747e15a200" - integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ== - is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" @@ -6235,11 +5487,6 @@ is-fullwidth-code-point@^4.0.0: resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz" integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ== -is-function@^1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz" - integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ== - is-generator-fn@^2.0.0: version "2.1.0" resolved "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz" @@ -6264,13 +5511,6 @@ is-hex-prefixed@1.0.0: resolved "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz" integrity sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA== -is-inside-container@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-inside-container/-/is-inside-container-1.0.0.tgz#e81fba699662eb31dbdaf26766a61d4814717ea4" - integrity sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA== - dependencies: - is-docker "^3.0.0" - is-interactive@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz" @@ -6363,7 +5603,7 @@ is-typed-array@^1.1.10, is-typed-array@^1.1.3: gopd "^1.0.1" has-tostringtag "^1.0.0" -is-typedarray@^1.0.0, is-typedarray@~1.0.0: +is-typedarray@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== @@ -6390,6 +5630,11 @@ isarray@0.0.1: resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + isarray@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" @@ -6407,13 +5652,13 @@ isobject@^3.0.1: isomorphic-ws@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz#e5529148912ecb9b451b46ed44d53dae1ce04bbf" + resolved "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz" integrity sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw== -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz" - integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== +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.0" @@ -6450,7 +5695,7 @@ istanbul-lib-instrument@^5.0.4: istanbul-lib-instrument@^6.0.0: version "6.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz#71e87707e8041428732518c6fb5211761753fbdf" + resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz" integrity sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA== dependencies: "@babel/core" "^7.12.3" @@ -6518,7 +5763,7 @@ jake@^10.8.5: 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" + resolved "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz" integrity sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w== dependencies: execa "^5.0.0" @@ -6527,7 +5772,7 @@ jest-changed-files@^29.7.0: jest-circus@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.7.0.tgz#b6817a45fcc835d8b16d5962d0c026473ee3668a" + resolved "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz" integrity sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw== dependencies: "@jest/environment" "^29.7.0" @@ -6553,7 +5798,7 @@ jest-circus@^29.7.0: jest-cli@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.7.0.tgz#5592c940798e0cae677eec169264f2d839a37995" + resolved "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz" integrity sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg== dependencies: "@jest/core" "^29.7.0" @@ -6570,7 +5815,7 @@ jest-cli@^29.7.0: jest-config@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.7.0.tgz#bcbda8806dbcc01b1e316a46bb74085a84b0245f" + resolved "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz" integrity sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ== dependencies: "@babel/core" "^7.11.6" @@ -6598,7 +5843,7 @@ jest-config@^29.7.0: "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" + resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz" integrity sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw== dependencies: chalk "^4.0.0" @@ -6608,14 +5853,14 @@ jest-config@^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" + resolved "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz" 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" + resolved "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz" integrity sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ== dependencies: "@jest/types" "^29.6.3" @@ -6626,7 +5871,7 @@ jest-each@^29.7.0: jest-environment-jsdom@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-29.7.0.tgz#d206fa3551933c3fd519e5dfdb58a0f5139a837f" + resolved "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.7.0.tgz" integrity sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA== dependencies: "@jest/environment" "^29.7.0" @@ -6640,7 +5885,7 @@ jest-environment-jsdom@^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" + resolved "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz" integrity sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw== dependencies: "@jest/environment" "^29.7.0" @@ -6652,12 +5897,12 @@ jest-environment-node@^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" + resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz" 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" + resolved "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz" integrity sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA== dependencies: "@jest/types" "^29.6.3" @@ -6676,7 +5921,7 @@ jest-haste-map@^29.7.0: 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" + resolved "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz" integrity sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw== dependencies: jest-get-type "^29.6.3" @@ -6684,7 +5929,7 @@ jest-leak-detector@^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" + resolved "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz" integrity sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g== dependencies: chalk "^4.0.0" @@ -6694,7 +5939,7 @@ jest-matcher-utils@^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" + resolved "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz" integrity sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w== dependencies: "@babel/code-frame" "^7.12.13" @@ -6709,7 +5954,7 @@ jest-message-util@^29.7.0: jest-mock@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.7.0.tgz#4e836cf60e99c6fcfabe9f99d017f3fdd50a6347" + resolved "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz" integrity sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw== dependencies: "@jest/types" "^29.6.3" @@ -6723,12 +5968,12 @@ jest-pnp-resolver@^1.2.2: 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" + resolved "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz" 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" + resolved "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz" integrity sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA== dependencies: jest-regex-util "^29.6.3" @@ -6736,7 +5981,7 @@ jest-resolve-dependencies@^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" + resolved "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz" integrity sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA== dependencies: chalk "^4.0.0" @@ -6751,7 +5996,7 @@ jest-resolve@^29.7.0: jest-runner@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.7.0.tgz#809af072d408a53dcfd2e849a4c976d3132f718e" + resolved "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz" integrity sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ== dependencies: "@jest/console" "^29.7.0" @@ -6778,7 +6023,7 @@ jest-runner@^29.7.0: jest-runtime@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.7.0.tgz#efecb3141cf7d3767a3a0cc8f7c9990587d3d817" + resolved "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz" integrity sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ== dependencies: "@jest/environment" "^29.7.0" @@ -6806,7 +6051,7 @@ jest-runtime@^29.7.0: jest-snapshot@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.7.0.tgz#c2c574c3f51865da1bb329036778a69bf88a6be5" + resolved "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz" integrity sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw== dependencies: "@babel/core" "^7.11.6" @@ -6832,7 +6077,7 @@ jest-snapshot@^29.7.0: 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" + resolved "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz" integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== dependencies: "@jest/types" "^29.6.3" @@ -6844,7 +6089,7 @@ jest-util@^29.0.0, jest-util@^29.7.0: jest-validate@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.7.0.tgz#7bf705511c64da591d46b15fce41400d52147d9c" + resolved "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz" integrity sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw== dependencies: "@jest/types" "^29.6.3" @@ -6856,7 +6101,7 @@ jest-validate@^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" + resolved "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz" integrity sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g== dependencies: "@jest/test-result" "^29.7.0" @@ -6870,7 +6115,7 @@ jest-watcher@^29.7.0: jest-worker@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.7.0.tgz#acad073acbbaeb7262bd5389e1bcf43e10058d4a" + resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz" integrity sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw== dependencies: "@types/node" "*" @@ -6880,7 +6125,7 @@ jest-worker@^29.7.0: jest@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest/-/jest-29.7.0.tgz#994676fc24177f088f1c5e3737f5697204ff2613" + resolved "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz" integrity sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw== dependencies: "@jest/core" "^29.7.0" @@ -6893,16 +6138,11 @@ js-sdsl@^4.1.4: resolved "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz" integrity sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg== -js-sha3@0.8.0, js-sha3@^0.8.0: +js-sha3@0.8.0: version "0.8.0" resolved "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz" integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== -js-sha3@^0.5.7: - version "0.5.7" - resolved "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz" - integrity sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g== - "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" @@ -6923,11 +6163,6 @@ js-yaml@^3.10.0, js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz" - integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== - jsdom@^20.0.0: version "20.0.3" resolved "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz" @@ -6965,11 +6200,6 @@ jsesc@^2.5.1: resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== -json-buffer@3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz" - integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== - json-parse-better-errors@^1.0.1: version "1.0.2" resolved "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz" @@ -6990,24 +6220,22 @@ json-schema-traverse@^0.4.1: resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== -json-schema@0.4.0: - version "0.4.0" - resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz" - integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== - json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== json-stable-stringify@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.2.tgz" - integrity sha512-eunSSaEnxV12z+Z73y/j5N37/In40GK4GmsSy+tEHJMxknvqnA7/djeYtAgW0GsWHUfg+847WJjKaEylk2y09g== + version "1.1.0" + resolved "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.1.0.tgz" + integrity sha512-zfA+5SuwYN2VWqN1/5HZaDzQKLJHaBVMZIIM+wuYjdptkaQsqzDdqjqf+lZZJUuJq1aanHiY8LhH8LmH+qBYJA== dependencies: + call-bind "^1.0.5" + isarray "^2.0.5" jsonify "^0.0.1" + object-keys "^1.1.1" -json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: +json-stringify-safe@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== @@ -7060,16 +6288,6 @@ jsonschema@^1.4.1: resolved "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz" integrity sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ== -jsprim@^1.2.2: - version "1.4.2" - resolved "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz" - integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.4.0" - verror "1.10.0" - just-extend@^4.0.2: version "4.2.1" resolved "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz" @@ -7084,13 +6302,6 @@ keccak@^3.0.0, keccak@^3.0.2: node-gyp-build "^4.2.0" readable-stream "^3.6.0" -keyv@^4.0.0: - version "4.5.2" - resolved "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz" - integrity sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g== - dependencies: - json-buffer "3.0.1" - kind-of@^6.0.2, kind-of@^6.0.3: version "6.0.3" resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz" @@ -7286,7 +6497,7 @@ lint-staged@^14.0.1: listr2@6.6.1: version "6.6.1" - resolved "https://registry.yarnpkg.com/listr2/-/listr2-6.6.1.tgz#08b2329e7e8ba6298481464937099f4a2cd7f95d" + resolved "https://registry.npmjs.org/listr2/-/listr2-6.6.1.tgz" integrity sha512-+rAXGHh0fkEWdXBmX+L6mmfmXmXvDGEKzkjxO+8mP3+nI/r/CWznVBvsibXdxda9Zz0OW2e2ikphN3OwCT/jSg== dependencies: cli-truncate "^3.1.0" @@ -7338,11 +6549,6 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" -lodash.camelcase@^4.3.0: - version "4.3.0" - resolved "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz" - integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== - lodash.flattendeep@^4.4.0: version "4.4.0" resolved "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz" @@ -7373,7 +6579,7 @@ lodash.merge@^4.6.2: resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.16, lodash@^4.17.21: +lodash@^4.17.11, lodash@^4.17.21: version "4.17.21" resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -7388,7 +6594,7 @@ log-symbols@4.1.0, log-symbols@^4.1.0: log-update@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/log-update/-/log-update-5.0.1.tgz#9e928bf70cb183c1f0c9e91d9e6b7115d597ce09" + resolved "https://registry.npmjs.org/log-update/-/log-update-5.0.1.tgz" integrity sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw== dependencies: ansi-escapes "^5.0.0" @@ -7416,16 +6622,6 @@ loupe@^2.3.6: dependencies: get-func-name "^2.0.0" -lowercase-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz" - integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== - -lowercase-keys@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz" - integrity sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ== - lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" @@ -7506,7 +6702,7 @@ make-fetch-happen@^10.0.3: 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" + resolved "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz" integrity sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w== dependencies: agentkeepalive "^4.2.1" @@ -7561,11 +6757,6 @@ md5.js@^1.3.4: inherits "^2.0.1" safe-buffer "^5.1.2" -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz" - integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== - memory-level@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/memory-level/-/memory-level-1.0.0.tgz" @@ -7597,11 +6788,6 @@ meow@^8.1.2: type-fest "^0.18.0" yargs-parser "^20.2.3" -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz" - integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== - merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" @@ -7612,11 +6798,6 @@ merge2@^1.3.0, merge2@^1.4.1: resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz" - integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== - micro-ftch@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/micro-ftch/-/micro-ftch-0.3.1.tgz#6cb83388de4c1f279a034fb0cf96dfc050853c5f" @@ -7635,18 +6816,13 @@ mime-db@1.52.0: resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.12, mime-types@^2.1.16, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34: +mime-types@^2.1.12: version "2.1.35" resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: mime-db "1.52.0" -mime@1.6.0: - version "1.6.0" - resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" @@ -7657,23 +6833,6 @@ mimic-fn@^4.0.0: resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz" integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== -mimic-response@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz" - integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== - -mimic-response@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz" - integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== - -min-document@^2.19.0: - version "2.19.0" - resolved "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz" - integrity sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ== - dependencies: - dom-walk "^0.1.0" - min-indent@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz" @@ -7733,7 +6892,7 @@ minimatch@^8.0.2: minimatch@^9.0.0, minimatch@^9.0.1: version "9.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz" integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== dependencies: brace-expansion "^2.0.1" @@ -7810,14 +6969,6 @@ minipass-sized@^1.0.3: dependencies: minipass "^3.0.0" -minipass@^2.6.0, minipass@^2.9.0: - version "2.9.0" - resolved "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz" - integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== - dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" - minipass@^3.0.0, minipass@^3.1.1, minipass@^3.1.6: version "3.3.6" resolved "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz" @@ -7840,13 +6991,6 @@ minipass@^5.0.0: resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== -minizlib@^1.3.3: - version "1.3.3" - resolved "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz" - integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== - dependencies: - minipass "^2.9.0" - minizlib@^2.1.1, minizlib@^2.1.2: version "2.1.2" resolved "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz" @@ -7855,25 +6999,6 @@ minizlib@^2.1.1, minizlib@^2.1.2: minipass "^3.0.0" yallist "^4.0.0" -mkdirp-promise@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz" - integrity sha512-Hepn5kb1lJPtVW84RFT40YG1OddBNTOVUZR2bzQUHc+Z03en8/3uX0+060JDhcEzyO08HmipsN9DcnFMxhIL9w== - dependencies: - mkdirp "*" - -mkdirp@*: - version "3.0.0" - resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.0.tgz" - integrity sha512-7+JDnNsyCvZXoUJdkMR0oUE2AmAdsNXGTmRbiOjYIwQ6q+bL6NwrozGQdPcmYaNcrhH37F50HHBUzoaBV6FITQ== - -mkdirp@^0.5.5: - version "0.5.6" - resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz" - integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== - dependencies: - minimist "^1.2.6" - mkdirp@^1.0.3, mkdirp@^1.0.4: version "1.0.4" resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" @@ -7913,11 +7038,6 @@ mocha@^10.0.0, mocha@^10.2.0: yargs-parser "20.2.4" yargs-unparser "2.0.0" -mock-fs@^4.1.0: - version "4.14.0" - resolved "https://registry.npmjs.org/mock-fs/-/mock-fs-4.14.0.tgz" - integrity sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw== - modify-values@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" @@ -7928,11 +7048,6 @@ module-error@^1.0.1, module-error@^1.0.2: resolved "https://registry.npmjs.org/module-error/-/module-error-1.0.2.tgz" integrity sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA== -ms@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== - ms@2.1.2: version "2.1.2" resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" @@ -7943,46 +7058,6 @@ ms@2.1.3, ms@^2.0.0: resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -multibase@^0.7.0: - version "0.7.0" - resolved "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz" - integrity sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg== - dependencies: - base-x "^3.0.8" - buffer "^5.5.0" - -multibase@~0.6.0: - version "0.6.1" - resolved "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz" - integrity sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw== - dependencies: - base-x "^3.0.8" - buffer "^5.5.0" - -multicodec@^0.5.5: - version "0.5.7" - resolved "https://registry.npmjs.org/multicodec/-/multicodec-0.5.7.tgz" - integrity sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA== - dependencies: - varint "^5.0.0" - -multicodec@^1.0.0: - version "1.0.4" - resolved "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz" - integrity sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg== - dependencies: - buffer "^5.6.0" - varint "^5.0.0" - -multihashes@^0.4.15, multihashes@~0.4.15: - version "0.4.21" - resolved "https://registry.npmjs.org/multihashes/-/multihashes-0.4.21.tgz" - integrity sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw== - dependencies: - buffer "^5.5.0" - multibase "^0.7.0" - varint "^5.0.0" - multimatch@5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz" @@ -8018,11 +7093,6 @@ mylas@^2.1.9: resolved "https://registry.npmjs.org/mylas/-/mylas-2.1.13.tgz" integrity sha512-+MrqnJRtxdF+xngFfUUkIMQrUUL0KsxbADUkn23Z/4ibGg192Q+z+CQyiYwvWTsYjJygmMR8+w3ZDa98Zh6ESg== -nano-json-stream-parser@^0.1.2: - version "0.1.2" - resolved "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz" - integrity sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew== - nanoid@3.3.3: version "3.3.3" resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz" @@ -8038,7 +7108,7 @@ natural-compare@^1.4.0: resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== -negotiator@0.6.3, negotiator@^0.6.3: +negotiator@^0.6.3: version "0.6.3" resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== @@ -8048,11 +7118,6 @@ neo-async@^2.6.0: resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== -next-tick@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz" - integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== - nise@^5.1.2: version "5.1.4" resolved "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz" @@ -8083,7 +7148,7 @@ node-fetch@2.6.7: node-fetch@^2.6.12, node-fetch@^2.6.7, node-fetch@^2.7.0: version "2.7.0" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz" integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== dependencies: whatwg-url "^5.0.0" @@ -8126,10 +7191,10 @@ node-preload@^0.2.1: dependencies: process-on-spawn "^1.0.0" -node-releases@^2.0.8: - version "2.0.10" - resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz" - integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== +node-releases@^2.0.13: + version "2.0.13" + resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz" + integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== nopt@^6.0.0: version "6.0.0" @@ -8173,11 +7238,6 @@ normalize-path@^3.0.0, normalize-path@~3.0.0: resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -normalize-url@^6.0.1: - version "6.1.0" - resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz" - integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== - npm-bundled@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz" @@ -8292,14 +7352,6 @@ npmlog@^6.0.0, npmlog@^6.0.2: gauge "^4.0.3" set-blocking "^2.0.0" -number-to-bn@1.7.0: - version "1.7.0" - resolved "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz" - integrity sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig== - dependencies: - bn.js "4.11.6" - strip-hex-prefix "1.0.0" - nwsapi@^2.2.2: version "2.2.4" resolved "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.4.tgz" @@ -8391,21 +7443,16 @@ nyc@^15.1.0: test-exclude "^6.0.0" yargs "^15.0.2" -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - -object-assign@^4, object-assign@^4.1.0, object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" - integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== - object-inspect@^1.9.0: version "1.12.3" resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz" integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== +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== + obliterator@^2.0.0: version "2.0.4" resolved "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz" @@ -8416,20 +7463,6 @@ oblivious-set@1.1.1: resolved "https://registry.npmjs.org/oblivious-set/-/oblivious-set-1.1.1.tgz" integrity sha512-Oh+8fK09mgGmAshFdH6hSVco6KZmd1tTwNFWj35OvzdmJTMZtAkbn05zar2iG3v6sDs1JLEtOiBGNb6BHwkb2w== -oboe@2.1.5: - version "2.1.5" - resolved "https://registry.npmjs.org/oboe/-/oboe-2.1.5.tgz" - integrity sha512-zRFWiF+FoicxEs3jNI/WYUrVEgA7DeET/InK0XQuudGHRg8iIob3cNPrJTKaz4004uaA9Pbe+Dwa8iluhjLZWA== - dependencies: - http-https "^1.0.0" - -on-finished@2.4.1: - version "2.4.1" - resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" - integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== - dependencies: - ee-first "1.1.1" - once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" @@ -8460,16 +7493,6 @@ open@^8.4.0: is-docker "^2.1.1" is-wsl "^2.2.0" -open@^9.1.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/open/-/open-9.1.0.tgz#684934359c90ad25742f5a26151970ff8c6c80b6" - integrity sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg== - dependencies: - default-browser "^4.0.0" - define-lazy-prop "^3.0.0" - is-inside-container "^1.0.0" - is-wsl "^2.2.0" - optionator@^0.8.1: version "0.8.3" resolved "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz" @@ -8484,7 +7507,7 @@ optionator@^0.8.1: optionator@^0.9.3: version "0.9.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" + resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz" integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== dependencies: "@aashutoshrathi/word-wrap" "^1.2.3" @@ -8514,16 +7537,6 @@ os-tmpdir@~1.0.2: resolved "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz" integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== -p-cancelable@^2.0.0: - version "2.1.1" - resolved "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz" - integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg== - -p-cancelable@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz" - integrity sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw== - p-finally@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz" @@ -8673,11 +7686,6 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -parse-headers@^2.0.0: - version "2.0.5" - resolved "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz" - integrity sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA== - parse-json@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz" @@ -8717,11 +7725,6 @@ parse5@^7.0.0, parse5@^7.1.1: dependencies: entities "^4.4.0" -parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - path-exists@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz" @@ -8760,11 +7763,6 @@ path-scurry@^1.10.1, path-scurry@^1.6.1: lru-cache "^9.1.1 || ^10.0.0" minipass "^5.0.0 || ^6.0.2 || ^7.0.0" -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz" - integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== - path-to-regexp@^1.7.0: version "1.8.0" resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz" @@ -8800,11 +7798,6 @@ pbkdf2@^3.0.17: safe-buffer "^5.0.1" sha.js "^2.4.8" -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz" - integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== - picocolors@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz" @@ -8881,19 +7874,14 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@^2.3.1: - version "2.8.8" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" - integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== - -prettier@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.1.1.tgz#6ba9f23165d690b6cbdaa88cb0807278f7019848" - integrity sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw== +prettier@^3.2.5: + 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" + resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz" integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== dependencies: "@jest/schemas" "^29.6.3" @@ -8955,20 +7943,12 @@ protocols@^2.0.0, protocols@^2.0.1: resolved "https://registry.npmjs.org/protocols/-/protocols-2.0.1.tgz" integrity sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q== -proxy-addr@~2.0.7: - version "2.0.7" - resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz" - integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== - dependencies: - forwarded "0.2.0" - ipaddr.js "1.9.1" - proxy-from-env@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz" integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== -psl@^1.1.28, psl@^1.1.33: +psl@^1.1.33: version "1.9.0" resolved "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz" integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== @@ -8981,11 +7961,6 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" -punycode@2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz" - integrity sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA== - punycode@^2.1.0, punycode@^2.1.1: version "2.3.0" resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz" @@ -8996,13 +7971,6 @@ pure-rand@^6.0.0: resolved "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.1.tgz" integrity sha512-t+x1zEHDjBwkDGY5v5ApnZ/utcd4XYDiJsaQQoptTXgUXX95sDg1elCdJghzicm7n2mbCBJ3uYWr6M22SO19rg== -qs@6.11.0: - version "6.11.0" - resolved "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz" - integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== - dependencies: - side-channel "^1.0.4" - qs@^6.9.4: version "6.11.1" resolved "https://registry.npmjs.org/qs/-/qs-6.11.1.tgz" @@ -9010,20 +7978,6 @@ qs@^6.9.4: dependencies: side-channel "^1.0.4" -qs@~6.5.2: - version "6.5.3" - resolved "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz" - integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== - -query-string@^5.0.1: - version "5.1.1" - resolved "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz" - integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== - dependencies: - decode-uri-component "^0.2.0" - object-assign "^4.1.0" - strict-uri-encode "^1.0.0" - querystringify@^2.1.1: version "2.2.0" resolved "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz" @@ -9044,11 +7998,6 @@ quick-lru@^4.0.1: resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz" integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== -quick-lru@^5.1.1: - version "5.1.1" - resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz" - integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== - randombytes@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" @@ -9056,12 +8005,7 @@ randombytes@^2.1.0: dependencies: safe-buffer "^5.1.0" -range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - -raw-body@2.5.2, raw-body@^2.4.1: +raw-body@^2.4.1: version "2.5.2" resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz" integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== @@ -9205,11 +8149,6 @@ redent@^3.0.0: indent-string "^4.0.0" strip-indent "^3.0.0" -reduce-flatten@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz" - integrity sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w== - regenerator-runtime@^0.14.0: version "0.14.0" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" @@ -9222,32 +8161,6 @@ release-zalgo@^1.0.0: dependencies: es6-error "^4.0.1" -request@^2.79.0: - version "2.88.2" - resolved "https://registry.npmjs.org/request/-/request-2.88.2.tgz" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" @@ -9268,11 +8181,6 @@ requires-port@^1.0.0: resolved "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz" integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== -resolve-alpn@^1.0.0, resolve-alpn@^1.2.0: - version "1.2.1" - resolved "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz" - integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== - resolve-cwd@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz" @@ -9311,13 +8219,6 @@ resolve@^1.10.0, resolve@^1.20.0: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -responselike@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz" - integrity sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw== - dependencies: - lowercase-keys "^2.0.0" - restore-cursor@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz" @@ -9328,7 +8229,7 @@ restore-cursor@^3.1.0: restore-cursor@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-4.0.0.tgz#519560a4318975096def6e609d44100edaa4ccb9" + resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz" integrity sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg== dependencies: onetime "^5.1.0" @@ -9385,13 +8286,6 @@ rlp@^2.2.3, rlp@^2.2.4: dependencies: bn.js "^5.2.0" -run-applescript@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/run-applescript/-/run-applescript-5.0.0.tgz#e11e1c932e055d5c6b40d98374e0268d9b11899c" - integrity sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg== - dependencies: - execa "^5.0.0" - run-async@^2.4.0: version "2.4.1" resolved "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz" @@ -9423,7 +8317,7 @@ rxjs@^7.5.5: dependencies: tslib "^2.1.0" -safe-buffer@5.2.1, 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.1, safe-buffer@~5.2.0: +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.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -9433,7 +8327,7 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -9452,7 +8346,7 @@ scheduler@^0.23.0: dependencies: loose-envify "^1.1.0" -scrypt-js@3.0.1, scrypt-js@^3.0.0, scrypt-js@^3.0.1: +scrypt-js@3.0.1, scrypt-js@^3.0.0: version "3.0.1" resolved "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz" integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== @@ -9483,31 +8377,10 @@ semver@^6.0.0, semver@^6.3.0: 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, semver@^7.6.0: - 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" - -send@0.18.0: - version "0.18.0" - resolved "https://registry.npmjs.org/send/-/send-0.18.0.tgz" - integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== - dependencies: - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "2.0.0" - mime "1.6.0" - ms "2.1.3" - on-finished "2.4.1" - range-parser "~1.2.1" - statuses "2.0.1" +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, semver@^7.6.0, semver@^7.6.1: + version "7.6.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.1.tgz#60bfe090bf907a25aa8119a72b9f90ef7ca281b2" + integrity sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA== serialize-javascript@6.0.0: version "6.0.0" @@ -9516,32 +8389,21 @@ serialize-javascript@6.0.0: dependencies: randombytes "^2.1.0" -serve-static@1.15.0: - version "1.15.0" - resolved "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz" - integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.18.0" - -servify@^0.1.12: - version "0.1.12" - resolved "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz" - integrity sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw== - dependencies: - body-parser "^1.16.0" - cors "^2.8.1" - express "^4.14.0" - request "^2.79.0" - xhr "^2.3.3" - set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz" integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== +set-function-length@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz" + integrity sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ== + dependencies: + define-data-property "^1.1.1" + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + setimmediate@^1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz" @@ -9600,7 +8462,7 @@ signal-exit@^4.0.1: sigstore@^1.3.0, sigstore@^1.4.0: version "1.9.0" - resolved "https://registry.yarnpkg.com/sigstore/-/sigstore-1.9.0.tgz#1e7ad8933aa99b75c6898ddd0eeebc3eb0d59875" + resolved "https://registry.npmjs.org/sigstore/-/sigstore-1.9.0.tgz" integrity sha512-0Zjz0oe37d08VeOtBIuB6cRriqXse2e8w+7yIy2XSXjshRKxbc2KkhXjL229jXSxEm7UbcjS76wcJDGQddVI9A== dependencies: "@sigstore/bundle" "^1.1.0" @@ -9609,20 +8471,6 @@ sigstore@^1.3.0, sigstore@^1.4.0: "@sigstore/tuf" "^1.0.3" make-fetch-happen "^11.0.1" -simple-concat@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz" - integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== - -simple-get@^2.7.0: - version "2.8.2" - resolved "https://registry.npmjs.org/simple-get/-/simple-get-2.8.2.tgz" - integrity sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw== - dependencies: - decompress-response "^3.3.0" - once "^1.3.1" - simple-concat "^1.0.0" - sinon-chai@^3.7.0: version "3.7.0" resolved "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.7.0.tgz" @@ -9798,21 +8646,6 @@ sprintf-js@~1.0.2: resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== -sshpk@^1.7.0: - version "1.17.0" - resolved "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz" - integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - ssri@^10.0.0, ssri@^10.0.1: version "10.0.3" resolved "https://registry.npmjs.org/ssri/-/ssri-10.0.3.tgz" @@ -9846,21 +8679,11 @@ statuses@2.0.1: resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== -strict-uri-encode@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz" - integrity sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ== - string-argv@0.3.2: version "0.3.2" - resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6" + resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz" integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q== -string-format@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/string-format/-/string-format-2.0.0.tgz" - integrity sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA== - string-length@^4.0.1: version "4.0.2" resolved "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz" @@ -10010,46 +8833,19 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -swarm-js@^0.1.40: - version "0.1.42" - resolved "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.42.tgz" - integrity sha512-BV7c/dVlA3R6ya1lMlSSNPLYrntt0LUq4YMgy3iwpCIc6rZnS5W2wUoctarZ5pXlpKtxDDf9hNziEkcfrxdhqQ== - dependencies: - bluebird "^3.5.0" - buffer "^5.0.5" - eth-lib "^0.1.26" - fs-extra "^4.0.2" - got "^11.8.5" - mime-types "^2.1.16" - mkdirp-promise "^5.0.1" - mock-fs "^4.1.0" - setimmediate "^1.0.5" - tar "^4.0.2" - xhr-request "^1.0.1" - symbol-tree@^3.2.4: version "3.2.4" resolved "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== -synckit@^0.8.5: - version "0.8.6" - resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.8.6.tgz#b69b7fbce3917c2673cbdc0d87fb324db4a5b409" - integrity sha512-laHF2savN6sMeHCjLRkheIU4wo3Zg9Ln5YOjOo7sZ5dVQW8yF5pPE5SIw1dsPhq3TRp1jisKRCdPhfs/1WMqDA== +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/utils" "^2.4.2" + "@pkgr/core" "^0.1.0" tslib "^2.6.2" -table-layout@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz" - integrity sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A== - dependencies: - array-back "^4.0.1" - deep-extend "~0.6.0" - typical "^5.2.0" - wordwrapjs "^4.0.0" - tar-stream@~2.2.0: version "2.2.0" resolved "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz" @@ -10073,19 +8869,6 @@ tar@6.1.11: mkdirp "^1.0.3" yallist "^4.0.0" -tar@^4.0.2: - version "4.4.19" - resolved "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz" - integrity sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA== - dependencies: - chownr "^1.1.4" - fs-minipass "^1.2.7" - minipass "^2.9.0" - minizlib "^1.3.3" - mkdirp "^0.5.5" - safe-buffer "^5.2.1" - yallist "^3.1.1" - tar@^6.1.11, tar@^6.1.2: version "6.1.13" resolved "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz" @@ -10135,16 +8918,6 @@ through@2, "through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6: resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== -timed-out@^4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz" - integrity sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA== - -titleize@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/titleize/-/titleize-3.0.0.tgz#71c12eb7fdd2558aa8a44b0be83b8a76694acd53" - integrity sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ== - tmp@0.0.33, tmp@^0.0.33: version "0.0.33" resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz" @@ -10191,14 +8964,6 @@ tough-cookie@^4.1.2: universalify "^0.2.0" url-parse "^1.5.3" -tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - tr46@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz" @@ -10221,26 +8986,10 @@ ts-api-utils@^1.0.1: resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.3.tgz#f12c1c781d04427313dbac808f453f050e54a331" integrity sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg== -ts-command-line-args@^2.2.0: - version "2.5.0" - resolved "https://registry.npmjs.org/ts-command-line-args/-/ts-command-line-args-2.5.0.tgz" - integrity sha512-Ff7Xt04WWCjj/cmPO9eWTJX3qpBZWuPWyQYG1vnxJao+alWWYjwJBc5aYz3h5p5dE08A6AnpkgiCtP/0KXXBYw== - dependencies: - "@morgan-stanley/ts-mocking-bird" "^0.6.2" - chalk "^4.1.0" - command-line-args "^5.1.1" - command-line-usage "^6.1.0" - string-format "^2.0.0" - -ts-essentials@^7.0.1: - version "7.0.3" - resolved "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz" - integrity sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ== - -ts-jest@^29.1.1: - version "29.1.1" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.1.1.tgz#f58fe62c63caf7bfcc5cc6472082f79180f0815b" - integrity sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA== +ts-jest@^29.1.2: + 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" @@ -10272,7 +9021,7 @@ ts-node@^10.9.2: tsc-alias@^1.8.8: version "1.8.8" - resolved "https://registry.yarnpkg.com/tsc-alias/-/tsc-alias-1.8.8.tgz#48696af442b7656dd7905e37ae0bc332d80be3fe" + resolved "https://registry.npmjs.org/tsc-alias/-/tsc-alias-1.8.8.tgz" integrity sha512-OYUOd2wl0H858NvABWr/BoSKNERw3N9GTi3rHPK8Iv4O1UyUXIrTTOAZNHsjlVpXFOhpJBVARI1s+rzwLivN3Q== dependencies: chokidar "^3.5.3" @@ -10301,7 +9050,7 @@ tslib@^1.9.3: resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.1.0, tslib@^2.3.0, tslib@^2.4.0, tslib@^2.6.0, tslib@^2.6.2: +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== @@ -10313,30 +9062,18 @@ tsort@0.0.1: tuf-js@^1.1.7: version "1.1.7" - resolved "https://registry.yarnpkg.com/tuf-js/-/tuf-js-1.1.7.tgz#21b7ae92a9373015be77dfe0cb282a80ec3bbe43" + resolved "https://registry.npmjs.org/tuf-js/-/tuf-js-1.1.7.tgz" integrity sha512-i3P9Kgw3ytjELUfpuKVDNBJvk4u5bXL6gskv572mcevPbSKCV3zt3djhmlEQ65yERjIbOSncy7U4cQJaB1CBCg== dependencies: "@tufjs/models" "1.0.4" debug "^4.3.4" make-fetch-happen "^11.1.1" -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz" - integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== - dependencies: - safe-buffer "^5.0.1" - tweetnacl-util@^0.15.1: version "0.15.1" resolved "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz" integrity sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw== -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz" - integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== - tweetnacl@^1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz" @@ -10398,43 +9135,9 @@ type-fest@^0.8.0, type-fest@^0.8.1: type-fest@^1.0.2: version "1.4.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz" integrity sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA== -type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -type@^1.0.1: - version "1.2.0" - resolved "https://registry.npmjs.org/type/-/type-1.2.0.tgz" - integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== - -type@^2.7.2: - version "2.7.2" - resolved "https://registry.npmjs.org/type/-/type-2.7.2.tgz" - integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw== - -typechain@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/typechain/-/typechain-8.3.2.tgz#1090dd8d9c57b6ef2aed3640a516bdbf01b00d73" - integrity sha512-x/sQYr5w9K7yv3es7jo4KTX05CLxOf7TRWwoHlrjRh8H82G64g+k7VuWPJlgMo6qrjfCulOdfBjiaDtmhFYD/Q== - dependencies: - "@types/prettier" "^2.1.1" - debug "^4.3.1" - fs-extra "^7.0.0" - glob "7.1.7" - js-sha3 "^0.8.0" - lodash "^4.17.15" - mkdirp "^1.0.4" - prettier "^2.3.1" - ts-command-line-args "^2.2.0" - ts-essentials "^7.0.1" - typedarray-to-buffer@^3.1.5: version "3.1.5" resolved "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz" @@ -10452,29 +9155,14 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37" integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== -typical@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz" - integrity sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw== - -typical@^5.2.0: - version "5.2.0" - resolved "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz" - integrity sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg== - uglify-js@^3.1.4: version "3.17.4" resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz" integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== -ultron@~1.1.0: - version "1.1.1" - resolved "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz" - integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og== - undici-types@~5.26.4: version "5.26.5" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + resolved "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== undici@^5.14.0: @@ -10537,25 +9225,20 @@ unload@^2.4.1: resolved "https://registry.npmjs.org/unload/-/unload-2.4.1.tgz" integrity sha512-IViSAm8Z3sRBYA+9wc0fLQmU9Nrxb16rcDmIiR6Y9LJSZzI7QY5QsDhqPpKOjAn0O9/kfK1TfNEMMAGPTIraPw== -unpipe@1.0.0, unpipe@~1.0.0: +unpipe@1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== -untildify@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" - integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== - upath@2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz" integrity sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w== -update-browserslist-db@^1.0.10: - version "1.0.10" - resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz" - integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== +update-browserslist-db@^1.0.13: + version "1.0.13" + resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz" + integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg== dependencies: escalade "^3.1.1" picocolors "^1.0.0" @@ -10575,23 +9258,6 @@ url-parse@^1.5.3: querystringify "^2.1.1" requires-port "^1.0.0" -url-set-query@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz" - integrity sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg== - -utf-8-validate@^5.0.2: - version "5.0.10" - resolved "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz" - integrity sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ== - dependencies: - node-gyp-build "^4.3.0" - -utf8@3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz" - integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== - util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" @@ -10608,21 +9274,6 @@ util@^0.12.5: is-typed-array "^1.1.3" which-typed-array "^1.1.2" -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" - integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== - -uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - -uuid@^7.0.3: - version "7.0.3" - resolved "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz" - integrity sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg== - uuid@^8.3.2: version "8.3.2" resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" @@ -10674,24 +9325,19 @@ validate-npm-package-name@^3.0.0: dependencies: builtins "^1.0.3" -varint@^5.0.0: - version "5.0.2" - resolved "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz" - integrity sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow== - -vary@^1, vary@~1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" - integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz" - integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw== +viem@^2.10.2: + version "2.10.2" + resolved "https://registry.yarnpkg.com/viem/-/viem-2.10.2.tgz#65c2ca82b64e6fb9ee84c02b95dcf2c270ffe651" + integrity sha512-gcOL+XxA0UWDarli856OEgumaBz4df/qNMpgno4NTSSZtJSC1XixIb3gWjVBei6Vx085ivw/U9ZE8gdniIo7fA== dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" + "@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" w3c-xmlserializer@^4.0.0: version "4.0.0" @@ -10714,235 +9360,218 @@ wcwidth@^1.0.0, wcwidth@^1.0.1: dependencies: defaults "^1.0.3" -web3-bzz@1.10.3: - version "1.10.3" - resolved "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.10.3.tgz" - integrity sha512-XDIRsTwekdBXtFytMpHBuun4cK4x0ZMIDXSoo1UVYp+oMyZj07c7gf7tNQY5qZ/sN+CJIas4ilhN25VJcjSijQ== +web3-core@^4.3.0, web3-core@^4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-4.3.2.tgz#f24b11d6a57dee527de8d42c89de2a439f0c4bed" + integrity sha512-uIMVd/j4BgOnwfpY8ZT+QKubOyM4xohEhFZXz9xB8wimXWMMlYVlIK/TbfHqFolS9uOerdSGhsMbcK9lETae8g== + dependencies: + web3-errors "^1.1.4" + web3-eth-accounts "^4.1.0" + web3-eth-iban "^4.0.7" + web3-providers-http "^4.1.0" + web3-providers-ws "^4.0.7" + web3-types "^1.3.1" + web3-utils "^4.1.0" + web3-validator "^2.0.3" + optionalDependencies: + web3-providers-ipc "^4.0.7" + +web3-errors@^1.1.3, web3-errors@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/web3-errors/-/web3-errors-1.1.4.tgz#5667a0a5f66fc936e101ef32032ccc1e8ca4d5a1" + integrity sha512-WahtszSqILez+83AxGecVroyZsMuuRT+KmQp4Si5P4Rnqbczno1k748PCrZTS1J4UCPmXMG2/Vt+0Bz2zwXkwQ== dependencies: - "@types/node" "^12.12.6" - got "12.1.0" - swarm-js "^0.1.40" + web3-types "^1.3.1" -web3-core-helpers@1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.10.3.tgz#f2db40ea57e888795e46f229b06113b60bcd671c" - integrity sha512-Yv7dQC3B9ipOc5sWm3VAz1ys70Izfzb8n9rSiQYIPjpqtJM+3V4EeK6ghzNR6CO2es0+Yu9CtCkw0h8gQhrTxA== +web3-eth-abi@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-4.2.1.tgz#b1260dace8380221f12f4274af240c1dfed1045c" + integrity sha512-IE91WUhhiDpBtbkl/DHUoZz7z7T5FXvl3zPLkrxT+dNlOT+wni+US/67jQCLvJRbqf9ApQ26lVYry0bovFgyqA== dependencies: - web3-eth-iban "1.10.3" - web3-utils "1.10.3" + abitype "0.7.1" + web3-errors "^1.1.4" + web3-types "^1.6.0" + web3-utils "^4.2.3" + web3-validator "^2.0.5" -web3-core-method@1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.10.3.tgz#63f16310ccab4eec8eca0a337d534565c2ba8d33" - integrity sha512-VZ/Dmml4NBmb0ep5PTSg9oqKoBtG0/YoMPei/bq/tUdlhB2dMB79sbeJPwx592uaV0Vpk7VltrrrBv5hTM1y4Q== +web3-eth-accounts@^4.1.0, web3-eth-accounts@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-4.1.2.tgz#652d6e3daf4d6cb3fe67cec6a878e768f6e8b8e8" + integrity sha512-y0JynDeTDnclyuE9mShXLeEj+BCrPHxPHOyPCgTchUBQsALF9+0OhP7WiS3IqUuu0Hle5bjG2f5ddeiPtNEuLg== dependencies: - "@ethersproject/transactions" "^5.6.2" - web3-core-helpers "1.10.3" - web3-core-promievent "1.10.3" - web3-core-subscriptions "1.10.3" - web3-utils "1.10.3" + "@ethereumjs/rlp" "^4.0.1" + crc-32 "^1.2.2" + ethereum-cryptography "^2.0.0" + web3-errors "^1.1.4" + web3-types "^1.6.0" + web3-utils "^4.2.3" + web3-validator "^2.0.5" -web3-core-promievent@1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.10.3.tgz#9765dd42ce6cf2dc0a08eaffee607b855644f290" - integrity sha512-HgjY+TkuLm5uTwUtaAfkTgRx/NzMxvVradCi02gy17NxDVdg/p6svBHcp037vcNpkuGeFznFJgULP+s2hdVgUQ== +web3-eth-contract@^4.3.0, web3-eth-contract@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-4.4.0.tgz#21760ef39ab95b34c55e7eaee316e0632e56cd21" + integrity sha512-pZ/w6Lb6ZDUUs7f5GCKXiHDAGGvt2tdwiHkvgmQTRnq9b0MEsUpteDyPYspHxKzQWLgbeK37jPb8zbQe4kE/Hg== + dependencies: + web3-core "^4.3.2" + web3-errors "^1.1.4" + web3-eth "^4.6.0" + web3-eth-abi "^4.2.1" + web3-types "^1.6.0" + web3-utils "^4.2.3" + web3-validator "^2.0.5" + +web3-eth-ens@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-4.2.0.tgz#8734b034efd48a735f7052fef0205653a78b84cb" + integrity sha512-qYj34te2UctoObt8rlEIY/t2MuTMiMiiHhO2JAHRGqSLCQ7b8DM3RpvkiiSB0N0ZyEn+CetZqJCTYb8DNKBS/g== + dependencies: + "@adraffy/ens-normalize" "^1.8.8" + web3-core "^4.3.2" + web3-errors "^1.1.4" + web3-eth "^4.5.0" + web3-eth-contract "^4.3.0" + web3-net "^4.0.7" + web3-types "^1.5.0" + web3-utils "^4.2.2" + web3-validator "^2.0.5" + +web3-eth-iban@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-4.0.7.tgz#ee504f845d7b6315f0be78fcf070ccd5d38e4aaf" + integrity sha512-8weKLa9KuKRzibC87vNLdkinpUE30gn0IGY027F8doeJdcPUfsa4IlBgNC4k4HLBembBB2CTU0Kr/HAOqMeYVQ== dependencies: - eventemitter3 "4.0.4" + web3-errors "^1.1.3" + web3-types "^1.3.0" + web3-utils "^4.0.7" + web3-validator "^2.0.3" -web3-core-requestmanager@1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.10.3.tgz#c34ca8e998a18d6ca3fa7f7a11d4391da401c987" - integrity sha512-VT9sKJfgM2yBOIxOXeXiDuFMP4pxzF6FT+y8KTLqhDFHkbG3XRe42Vm97mB/IvLQCJOmokEjl3ps8yP1kbggyw== +web3-eth-personal@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-4.0.8.tgz#b51628c560de550ca8b354fa784f9556aae6065c" + integrity sha512-sXeyLKJ7ddQdMxz1BZkAwImjqh7OmKxhXoBNF3isDmD4QDpMIwv/t237S3q4Z0sZQamPa/pHebJRWVuvP8jZdw== dependencies: - util "^0.12.5" - web3-core-helpers "1.10.3" - web3-providers-http "1.10.3" - web3-providers-ipc "1.10.3" - web3-providers-ws "1.10.3" - -web3-core-subscriptions@1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.10.3.tgz#58768cd72a9313252ef05dc52c09536f009a9479" - integrity sha512-KW0Mc8sgn70WadZu7RjQ4H5sNDJ5Lx8JMI3BWos+f2rW0foegOCyWhRu33W1s6ntXnqeBUw5rRCXZRlA3z+HNA== - dependencies: - eventemitter3 "4.0.4" - web3-core-helpers "1.10.3" - -web3-core@1.10.3, web3-core@^1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.10.3.tgz#4aeb8f4b0cb5775d9fa4edf1127864743f1c3ae3" - integrity sha512-Vbk0/vUNZxJlz3RFjAhNNt7qTpX8yE3dn3uFxfX5OHbuon5u65YEOd3civ/aQNW745N0vGUlHFNxxmn+sG9DIw== - dependencies: - "@types/bn.js" "^5.1.1" - "@types/node" "^12.12.6" - bignumber.js "^9.0.0" - web3-core-helpers "1.10.3" - web3-core-method "1.10.3" - web3-core-requestmanager "1.10.3" - web3-utils "1.10.3" - -web3-eth-abi@1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.10.3.tgz#7decfffa8fed26410f32cfefdc32d3e76f717ca2" - integrity sha512-O8EvV67uhq0OiCMekqYsDtb6FzfYzMXT7VMHowF8HV6qLZXCGTdB/NH4nJrEh2mFtEwVdS6AmLFJAQd2kVyoMQ== - dependencies: - "@ethersproject/abi" "^5.6.3" - web3-utils "1.10.3" - -web3-eth-accounts@1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.10.3.tgz#9ecb816b81cd97333988bfcd0afaee5d13bbb198" - integrity sha512-8MipGgwusDVgn7NwKOmpeo3gxzzd+SmwcWeBdpXknuyDiZSQy9tXe+E9LeFGrmys/8mLLYP79n3jSbiTyv+6pQ== - dependencies: - "@ethereumjs/common" "2.6.5" - "@ethereumjs/tx" "3.5.2" - "@ethereumjs/util" "^8.1.0" - eth-lib "0.2.8" - scrypt-js "^3.0.1" - uuid "^9.0.0" - web3-core "1.10.3" - web3-core-helpers "1.10.3" - web3-core-method "1.10.3" - web3-utils "1.10.3" - -web3-eth-contract@1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.10.3.tgz#8880468e2ba7d8a4791cf714f67d5e1ec1591275" - integrity sha512-Y2CW61dCCyY4IoUMD4JsEQWrILX4FJWDWC/Txx/pr3K/+fGsBGvS9kWQN5EsVXOp4g7HoFOfVh9Lf7BmVVSRmg== - dependencies: - "@types/bn.js" "^5.1.1" - web3-core "1.10.3" - web3-core-helpers "1.10.3" - web3-core-method "1.10.3" - web3-core-promievent "1.10.3" - web3-core-subscriptions "1.10.3" - web3-eth-abi "1.10.3" - web3-utils "1.10.3" - -web3-eth-ens@1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.10.3.tgz#ae5b49bcb9823027e0b28aa6b1de58d726cbaafa" - integrity sha512-hR+odRDXGqKemw1GFniKBEXpjYwLgttTES+bc7BfTeoUyUZXbyDHe5ifC+h+vpzxh4oS0TnfcIoarK0Z9tFSiQ== - dependencies: - content-hash "^2.5.2" - eth-ens-namehash "2.0.8" - web3-core "1.10.3" - web3-core-helpers "1.10.3" - web3-core-promievent "1.10.3" - web3-eth-abi "1.10.3" - web3-eth-contract "1.10.3" - web3-utils "1.10.3" - -web3-eth-iban@1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.10.3.tgz#91d458e5400195edc883a0d4383bf1cecd17240d" - integrity sha512-ZCfOjYKAjaX2TGI8uif5ah+J3BYFuo+47JOIV1RIz2l7kD9VfnxvRH5UiQDRyMALQC7KFd2hUqIEtHklapNyKA== + web3-core "^4.3.0" + web3-eth "^4.3.1" + web3-rpc-methods "^1.1.3" + web3-types "^1.3.0" + web3-utils "^4.0.7" + web3-validator "^2.0.3" + +web3-eth@^4.3.1, web3-eth@^4.5.0, web3-eth@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-4.6.0.tgz#75c177e2bde88a613a6996fab515f104e16921da" + integrity sha512-8KtxlGsomovoFULqEpfixgmCpaJ2YIJGxbXUfezh2coXHjVgEopQhARYtKGClyV5kkdCIqwHS8Gvsm6TVNqH6Q== + dependencies: + setimmediate "^1.0.5" + web3-core "^4.3.2" + web3-errors "^1.1.4" + web3-eth-abi "^4.2.1" + web3-eth-accounts "^4.1.2" + web3-net "^4.0.7" + web3-providers-ws "^4.0.7" + web3-rpc-methods "^1.2.0" + web3-types "^1.6.0" + web3-utils "^4.2.3" + web3-validator "^2.0.5" + +web3-net@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-4.0.7.tgz#ed2c1bd700cf94be93a6dbd8bd8aa413d8681942" + integrity sha512-SzEaXFrBjY25iQGk5myaOfO9ZyfTwQEa4l4Ps4HDNVMibgZji3WPzpjq8zomVHMwi8bRp6VV7YS71eEsX7zLow== + dependencies: + web3-core "^4.3.0" + web3-rpc-methods "^1.1.3" + web3-types "^1.3.0" + web3-utils "^4.0.7" + +web3-providers-http@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-4.1.0.tgz#8d7afda67d1d8542ca85b30f60a3d1fe1993b561" + integrity sha512-6qRUGAhJfVQM41E5t+re5IHYmb5hSaLc02BE2MaRQsz2xKA6RjmHpOA5h/+ojJxEpI9NI2CrfDKOAgtJfoUJQg== dependencies: - bn.js "^5.2.1" - web3-utils "1.10.3" - -web3-eth-personal@1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.10.3.tgz#4e72008aa211327ccc3bfa7671c510e623368457" - integrity sha512-avrQ6yWdADIvuNQcFZXmGLCEzulQa76hUOuVywN7O3cklB4nFc/Gp3yTvD3bOAaE7DhjLQfhUTCzXL7WMxVTsw== - dependencies: - "@types/node" "^12.12.6" - web3-core "1.10.3" - web3-core-helpers "1.10.3" - web3-core-method "1.10.3" - web3-net "1.10.3" - web3-utils "1.10.3" - -web3-eth@1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.10.3.tgz#b8c6f37f1aac52422583a5a9c29130983a3fb3b1" - integrity sha512-Uk1U2qGiif2mIG8iKu23/EQJ2ksB1BQXy3wF3RvFuyxt8Ft9OEpmGlO7wOtAyJdoKzD5vcul19bJpPcWSAYZhA== - dependencies: - web3-core "1.10.3" - web3-core-helpers "1.10.3" - web3-core-method "1.10.3" - web3-core-subscriptions "1.10.3" - web3-eth-abi "1.10.3" - web3-eth-accounts "1.10.3" - web3-eth-contract "1.10.3" - web3-eth-ens "1.10.3" - web3-eth-iban "1.10.3" - web3-eth-personal "1.10.3" - web3-net "1.10.3" - web3-utils "1.10.3" - -web3-net@1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.10.3.tgz#9486c2fe51452cb958e11915db6f90bd6caa5482" - integrity sha512-IoSr33235qVoI1vtKssPUigJU9Fc/Ph0T9CgRi15sx+itysmvtlmXMNoyd6Xrgm9LuM4CIhxz7yDzH93B79IFg== - dependencies: - web3-core "1.10.3" - web3-core-method "1.10.3" - web3-utils "1.10.3" - -web3-providers-http@1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.10.3.tgz#d8166ee89db82d37281ea9e15c5882a2d7928755" - integrity sha512-6dAgsHR3MxJ0Qyu3QLFlQEelTapVfWNTu5F45FYh8t7Y03T1/o+YAkVxsbY5AdmD+y5bXG/XPJ4q8tjL6MgZHw== - dependencies: - abortcontroller-polyfill "^1.7.5" cross-fetch "^4.0.0" - es6-promise "^4.2.8" - web3-core-helpers "1.10.3" + web3-errors "^1.1.3" + web3-types "^1.3.0" + web3-utils "^4.0.7" -web3-providers-ipc@1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.10.3.tgz#a7e015957fc037d8a87bd4b6ae3561c1b1ad1f46" - integrity sha512-vP5WIGT8FLnGRfswTxNs9rMfS1vCbMezj/zHbBe/zB9GauBRTYVrUo2H/hVrhLg8Ut7AbsKZ+tCJ4mAwpKi2hA== +web3-providers-ipc@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-4.0.7.tgz#9ec4c8565053af005a5170ba80cddeb40ff3e3d3" + integrity sha512-YbNqY4zUvIaK2MHr1lQFE53/8t/ejHtJchrWn9zVbFMGXlTsOAbNoIoZWROrg1v+hCBvT2c9z8xt7e/+uz5p1g== dependencies: - oboe "2.1.5" - web3-core-helpers "1.10.3" + web3-errors "^1.1.3" + web3-types "^1.3.0" + web3-utils "^4.0.7" -web3-providers-ws@1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.10.3.tgz#03c84958f9da251349cd26fd7a4ae567e3af6caa" - integrity sha512-/filBXRl48INxsh6AuCcsy4v5ndnTZ/p6bl67kmO9aK1wffv7CT++DrtclDtVMeDGCgB3van+hEf9xTAVXur7Q== +web3-providers-ws@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-4.0.7.tgz#7a78a0dcf077e0e802da524fbb37d080b356c14b" + integrity sha512-n4Dal9/rQWjS7d6LjyEPM2R458V8blRm0eLJupDEJOOIBhGYlxw5/4FthZZ/cqB7y/sLVi7K09DdYx2MeRtU5w== dependencies: - eventemitter3 "4.0.4" - web3-core-helpers "1.10.3" - websocket "^1.0.32" + "@types/ws" "8.5.3" + isomorphic-ws "^5.0.0" + web3-errors "^1.1.3" + web3-types "^1.3.0" + web3-utils "^4.0.7" + ws "^8.8.1" -web3-shh@1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.10.3.tgz#ee44f760598a65a290d611c443838aac854ee858" - integrity sha512-cAZ60CPvs9azdwMSQ/PSUdyV4PEtaW5edAZhu3rCXf6XxQRliBboic+AvwUvB6j3eswY50VGa5FygfVmJ1JVng== +web3-rpc-methods@^1.1.3, web3-rpc-methods@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/web3-rpc-methods/-/web3-rpc-methods-1.2.0.tgz#761dcb036ab16edb2b03e80c11e3f5df24690345" + integrity sha512-CWJ/g4I4WyYvLkf21wCZAehdhU/VjX/OAPHnqF5/FPDJlogOsOnGXHqi1Z5AP+ocdt395PNubd8jyMMJoYGSBA== dependencies: - web3-core "1.10.3" - web3-core-method "1.10.3" - web3-core-subscriptions "1.10.3" - web3-net "1.10.3" + web3-core "^4.3.2" + web3-types "^1.5.0" + web3-validator "^2.0.4" -web3-utils@1.10.3, web3-utils@^1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.10.3.tgz#f1db99c82549c7d9f8348f04ffe4e0188b449714" - integrity sha512-OqcUrEE16fDBbGoQtZXWdavsPzbGIDc5v3VrRTZ0XrIpefC/viZ1ZU9bGEemazyS0catk/3rkOOxpzTfY+XsyQ== +web3-types@^1.3.0, web3-types@^1.3.1, web3-types@^1.5.0, web3-types@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/web3-types/-/web3-types-1.6.0.tgz#ebe7f140c31f7cc0ad15f238ad7e7ac72797ff3b" + integrity sha512-qgOtADqlD5hw+KPKBUGaXAcdNLL0oh6qTeVgXwewCfbL/lG9R+/GrgMQB1gbTJ3cit8hMwtH8KX2Em6OwO0HRw== + +web3-utils@^4.0.7, web3-utils@^4.1.0, web3-utils@^4.2.2, web3-utils@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-4.2.3.tgz#e1d30c4b087cd95f4307baeb80e3160f174e1cfd" + integrity sha512-m5plKTC2YtQntHITQRyIePw52UVP1IrShhmA2FACtn4zmc5ADmrXOlQWiPzxFP/18eRJsAaUAw2+CQn1u4WPxQ== 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" + ethereum-cryptography "^2.0.0" + eventemitter3 "^5.0.1" + web3-errors "^1.1.4" + web3-types "^1.6.0" + web3-validator "^2.0.5" -web3@^1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/web3/-/web3-1.10.3.tgz#5e80ac532dc432b09fde668d570b0ad4e6710897" - integrity sha512-DgUdOOqC/gTqW+VQl1EdPxrVRPB66xVNtuZ5KD4adVBtko87hkgM8BTZ0lZ8IbUfnQk6DyjcDujMiH3oszllAw== +web3-validator@^2.0.3, web3-validator@^2.0.4, web3-validator@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/web3-validator/-/web3-validator-2.0.5.tgz#de1984bdb34f292251b86400dba7169700db0849" + integrity sha512-2gLOSW8XqEN5pw5jVUm20EB7A8SbQiekpAtiI0JBmCIV0a2rp97v8FgWY5E3UEqnw5WFfEqvcDVW92EyynDTyQ== dependencies: - web3-bzz "1.10.3" - web3-core "1.10.3" - web3-eth "1.10.3" - web3-eth-personal "1.10.3" - web3-net "1.10.3" - web3-shh "1.10.3" - web3-utils "1.10.3" + ethereum-cryptography "^2.0.0" + util "^0.12.5" + web3-errors "^1.1.4" + web3-types "^1.5.0" + zod "^3.21.4" + +web3@^4.7.0: + version "4.8.0" + resolved "https://registry.yarnpkg.com/web3/-/web3-4.8.0.tgz#c7c7d2a7616ae387f8b2e3a3e416153a4bff479a" + integrity sha512-kQSF2NlHk8yjS3SRiJW3S+U5ibkEmVRhB4/GYsVwGvdAkFC2b+EIE1Ob7J56OmqW9VBZgkx1+SuWqo5JTIJSYQ== + dependencies: + web3-core "^4.3.2" + web3-errors "^1.1.4" + web3-eth "^4.6.0" + web3-eth-abi "^4.2.1" + web3-eth-accounts "^4.1.2" + web3-eth-contract "^4.4.0" + web3-eth-ens "^4.2.0" + web3-eth-iban "^4.0.7" + web3-eth-personal "^4.0.8" + web3-net "^4.0.7" + web3-providers-http "^4.1.0" + web3-providers-ws "^4.0.7" + web3-rpc-methods "^1.2.0" + web3-types "^1.6.0" + web3-utils "^4.2.3" + web3-validator "^2.0.5" webidl-conversions@^3.0.0: version "3.0.1" @@ -10954,18 +9583,6 @@ webidl-conversions@^7.0.0: resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz" integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== -websocket@^1.0.32: - version "1.0.34" - resolved "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz" - integrity sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ== - dependencies: - bufferutil "^4.0.1" - debug "^2.2.0" - es5-ext "^0.10.50" - typedarray-to-buffer "^3.1.5" - utf-8-validate "^5.0.2" - yaeti "^0.0.6" - whatwg-encoding@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz" @@ -11042,14 +9659,6 @@ wordwrap@^1.0.0: resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz" integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== -wordwrapjs@^4.0.0: - version "4.0.1" - resolved "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz" - integrity sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA== - dependencies: - reduce-flatten "^2.0.0" - typical "^5.2.0" - workerpool@6.2.1: version "6.2.1" resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz" @@ -11084,7 +9693,7 @@ wrap-ansi@^7.0.0: wrap-ansi@^8.0.1, wrap-ansi@^8.1.0: version "8.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz" integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== dependencies: ansi-styles "^6.1.0" @@ -11157,65 +9766,31 @@ ws@7.4.6: resolved "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz" 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@8.5.0: version "8.5.0" resolved "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz" integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== -ws@^3.0.0: - version "3.3.3" - resolved "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz" - integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA== - dependencies: - async-limiter "~1.0.0" - safe-buffer "~5.1.0" - ultron "~1.1.0" - ws@^7.4.6: version "7.5.9" resolved "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz" integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== -ws@^8.11.0, ws@^8.5.0: - version "8.14.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.14.2.tgz#6c249a806eb2db7a20d26d51e7709eab7b2e6c7f" - integrity sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g== +ws@^8.11.0, ws@^8.5.0, ws@^8.8.1: + version "8.16.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.16.0.tgz#d1cd774f36fbc07165066a60e40323eab6446fd4" + integrity sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ== ws@~8.11.0: version "8.11.0" resolved "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz" integrity sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg== -xhr-request-promise@^0.1.2: - version "0.1.3" - resolved "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz" - integrity sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg== - dependencies: - xhr-request "^1.1.0" - -xhr-request@^1.0.1, xhr-request@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz" - integrity sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA== - dependencies: - buffer-to-arraybuffer "^0.0.5" - object-assign "^4.1.1" - query-string "^5.0.1" - simple-get "^2.7.0" - timed-out "^4.0.1" - url-set-query "^1.0.0" - xhr "^2.0.4" - -xhr@^2.0.4, xhr@^2.3.3: - version "2.6.0" - resolved "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz" - integrity sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA== - dependencies: - global "~4.4.0" - is-function "^1.0.1" - parse-headers "^2.0.0" - xtend "^4.0.0" - xml-name-validator@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz" @@ -11231,7 +9806,7 @@ xmlhttprequest-ssl@~2.0.0: resolved "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz" integrity sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A== -xtend@^4.0.0, xtend@~4.0.1: +xtend@~4.0.1: version "4.0.2" resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== @@ -11246,12 +9821,7 @@ y18n@^5.0.5: resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yaeti@^0.0.6: - version "0.0.6" - resolved "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz" - integrity sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug== - -yallist@^3.0.0, yallist@^3.0.2, yallist@^3.1.1: +yallist@^3.0.2: version "3.1.1" resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== @@ -11263,7 +9833,7 @@ yallist@^4.0.0: yaml@2.3.1: version "2.3.1" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.1.tgz#02fe0975d23cd441242aa7204e09fc28ac2ac33b" + resolved "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz" integrity sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ== yargs-parser@20.2.4: @@ -11356,3 +9926,8 @@ zksync-web3@^0.14.3: version "0.14.3" resolved "https://registry.npmjs.org/zksync-web3/-/zksync-web3-0.14.3.tgz" integrity sha512-hT72th4AnqyLW1d5Jlv8N2B/qhEnl2NePK2A3org7tAa24niem/UAaHMkEvmWI3SF9waYUPtqAtjpf+yvQ9zvQ== + +zod@^3.21.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==