From 024d8f627b9b65d8e7f420f4941fe08d93a040f6 Mon Sep 17 00:00:00 2001 From: aboudjem Date: Thu, 7 Sep 2023 18:40:10 +0700 Subject: [PATCH 1/9] =?UTF-8?q?=F0=9F=94=A7=20fix=20ts=20config?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tsconfig.json | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tsconfig.json b/tsconfig.json index 15eb2a2ca..3f0596634 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,9 +11,7 @@ "lib": ["es2020"], "types": ["node", "jest"] }, - "include": [ - "./src/**/*" - ], + "include": ["packages/**/*"], "references": [ { "path": "./packages/common" }, { "path": "./packages/core-types" }, @@ -25,4 +23,4 @@ { "path": "./packages/paymaster" }, { "path": "./packages/account" } ] -} \ No newline at end of file +} From 781ea63b37190e67621efdd1cfd62ebf09b56cd4 Mon Sep 17 00:00:00 2001 From: aboudjem Date: Thu, 7 Sep 2023 18:41:50 +0700 Subject: [PATCH 2/9] =?UTF-8?q?=F0=9F=99=88=20=F0=9F=94=A7=20add=20eslinti?= =?UTF-8?q?gnore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintignore | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .eslintignore diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 000000000..bc013db12 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,14 @@ +# Ignore node_modules in the root and in all packages +**/node_modules/ + +# Ignore build or dist directories +**/dist/ +**/build/ +**/coverage/ + +# Ignore any auto-generated files +**/typechain/ + +# Ignore any config files +*.config.js +*.config.ts \ No newline at end of file From 0ef1f50bf1030d640ec9ff5c7c8790685ee76557 Mon Sep 17 00:00:00 2001 From: aboudjem Date: Thu, 7 Sep 2023 18:41:59 +0700 Subject: [PATCH 3/9] =?UTF-8?q?=F0=9F=99=88=20=F0=9F=94=A7=20add=20prettie?= =?UTF-8?q?rignore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .prettierignore | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .prettierignore diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..bc013db12 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,14 @@ +# Ignore node_modules in the root and in all packages +**/node_modules/ + +# Ignore build or dist directories +**/dist/ +**/build/ +**/coverage/ + +# Ignore any auto-generated files +**/typechain/ + +# Ignore any config files +*.config.js +*.config.ts \ No newline at end of file From 5b4cab8d75388f358a5b13b3e983a1a82127afa4 Mon Sep 17 00:00:00 2001 From: aboudjem Date: Thu, 7 Sep 2023 18:45:36 +0700 Subject: [PATCH 4/9] =?UTF-8?q?=F0=9F=94=A7=20update=20eslint=20config=20a?= =?UTF-8?q?dd=20new=20rules?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc.js | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 2ac78efe4..a85bda168 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,11 +1,35 @@ module.exports = { - parser: '@typescript-eslint/parser', // Specifies the ESLint parser - extends: [ - 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin - 'plugin:prettier/recommended' // Enables eslint-plugin-prettier and displays prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array. - ], + parser: "@typescript-eslint/parser", + extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended", "airbnb-typescript/base", "plugin:prettier/recommended"], parserOptions: { - ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features - sourceType: 'module' // Allows for the use of imports - } -} + ecmaVersion: 2020, + sourceType: "module", + project: './tsconfig.eslint.json', + }, + env: { + node: true, + es6: true, + }, + plugins: ["@typescript-eslint", "prettier", "security", "import"], + rules: { + "prettier/prettier": "error", + "no-var": "error", + "prefer-const": "error", + "no-unused-vars": ["error", { argsIgnorePattern: "^_" }], + "no-console": "warn", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/explicit-module-boundary-types": "off", + "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }], + "security/detect-object-injection": "warn", + "security/detect-unsafe-regex": "error", + }, + settings: {}, + overrides: [ + { + files: ["*.ts", "*.tsx"], + rules: { + "@typescript-eslint/explicit-function-return-type": ["warn", { allowExpressions: true }], + }, + }, + ], +}; From 92d7dee041c9e86161889bbc25468609ff4d3173 Mon Sep 17 00:00:00 2001 From: aboudjem Date: Thu, 7 Sep 2023 18:45:56 +0700 Subject: [PATCH 5/9] =?UTF-8?q?=F0=9F=94=A7=20update=20config=20of=20prett?= =?UTF-8?q?ierc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .prettierrc.json | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.prettierrc.json b/.prettierrc.json index 5cdd74073..6b3f54736 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,6 +1,7 @@ { - "printWidth": 100, - "semi": false, - "singleQuote": true, - "trailingComma": "none" + "printWidth": 150, + "semi": true, + "singleQuote": false, + "trailingComma": "all", + "tabWidth": 2 } From 065ba17cf983426dc3649417f0300fc1b0d735d7 Mon Sep 17 00:00:00 2001 From: aboudjem Date: Thu, 7 Sep 2023 18:46:21 +0700 Subject: [PATCH 6/9] =?UTF-8?q?=F0=9F=94=A7=20create=20tsconfig=20for=20es?= =?UTF-8?q?lintrc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tsconfig.eslint.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 tsconfig.eslint.json diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json new file mode 100644 index 000000000..92546355a --- /dev/null +++ b/tsconfig.eslint.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "include": [ + "packages/**/*" + ] + } + \ No newline at end of file From 9752192d6fd07d48175034a53323840a75436cef Mon Sep 17 00:00:00 2001 From: aboudjem Date: Thu, 7 Sep 2023 18:47:52 +0700 Subject: [PATCH 7/9] =?UTF-8?q?=F0=9F=93=A6=20install=20eslint=20airbnb,?= =?UTF-8?q?=20security,=20prettier?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index bf0e685f7..16cee71eb 100644 --- a/package.json +++ b/package.json @@ -33,14 +33,21 @@ "author": "Biconomy (https://biconomy.io)", "devDependencies": { "@types/jest": "^29.5.4", - "eslint-plugin-import": "^2.26.0", - "eslint-plugin-prettier": "^4.2.1", + "@typescript-eslint/eslint-plugin": "^6.0.0", + "@typescript-eslint/parser": "^6.0.0", + "eslint": "^8.2.0", + "eslint-config-airbnb-base": "15.0.0", + "eslint-config-airbnb-typescript": "17.1.0", + "eslint-config-prettier": "^9.0.0", + "eslint-plugin-import": "^2.25.3", + "eslint-plugin-prettier": "^5.0.0", + "eslint-plugin-security": "^1.7.1", "hardhat": "^2.9.9", "jest": "^29.6.4", "lerna": "^7.2.0", "lerna-changelog": "^2.2.0", "nx": "^15.8.3", - "prettier": "2.7.1", + "prettier": "^3.0.3", "rimraf": "^3.0.2", "ts-jest": "^29.1.1", "ts-node": "^10.9.1" From d9cb848ae504823c91234eb0416747ffa43f6963 Mon Sep 17 00:00:00 2001 From: aboudjem Date: Thu, 7 Sep 2023 18:49:24 +0700 Subject: [PATCH 8/9] =?UTF-8?q?=F0=9F=9A=A8=20fix=20lint=20warnings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/ISSUE_TEMPLATE/bug_report.md | 24 +- .github/ISSUE_TEMPLATE/feature_request.md | 7 +- .github/pull_request_template.md | 10 +- .nycrc.json | 4 +- LICENSE.md | 328 ++++++------- README.md | 23 +- jest.config.ts | 30 +- lerna.json | 10 +- packages/account/CHANGELOG.md | 25 +- packages/account/Readme.md | 75 ++- packages/account/src/BiconomySmartAccount.ts | 458 ++++++++---------- packages/account/src/SmartAccount.ts | 314 ++++++------ packages/account/src/index.ts | 10 +- .../src/interfaces/IBiconomySmartAccount.ts | 44 +- .../account/src/interfaces/ISmartAccount.ts | 12 +- packages/account/src/utils/Constants.ts | 26 +- packages/account/src/utils/Preverificaiton.ts | 63 ++- packages/account/src/utils/Types.ts | 74 +-- packages/account/tests/account.spec.ts | 9 +- packages/account/tsconfig.json | 2 +- packages/bundler/CHANGELOG.md | 19 +- packages/bundler/Readme.md | 46 +- packages/bundler/package.json | 2 +- packages/bundler/src/Bundler.ts | 134 +++-- packages/bundler/src/index.ts | 6 +- packages/bundler/src/interfaces/IBundler.ts | 17 +- packages/bundler/src/utils/Constants.ts | 6 +- packages/bundler/src/utils/HelperFunction.ts | 32 +- packages/bundler/src/utils/Types.ts | 114 ++--- packages/bundler/tests/bundler.spec.ts | 9 +- packages/bundler/tsconfig.json | 2 +- packages/common/CHANGELOG.md | 46 +- packages/common/src/Constants.ts | 44 +- packages/common/src/ContractsInstances.ts | 62 ++- packages/common/src/ERC4337Utils.ts | 156 +++--- packages/common/src/Logger.ts | 29 +- packages/common/src/Utils.ts | 4 +- packages/common/src/httpRequests.ts | 78 ++- packages/common/src/index.ts | 14 +- packages/common/tests/ERC4337Utils.spec.ts | 52 +- packages/common/tsconfig.json | 15 +- packages/core-types/CHANGELOG.md | 54 +-- packages/core-types/README.md | 9 +- packages/core-types/src/BundlerTypes.ts | 14 +- packages/core-types/src/ChainsTypes.ts | 50 +- .../core-types/src/PaymasterServiceTypes.ts | 6 +- packages/core-types/src/Types.ts | 38 +- packages/core-types/src/index.ts | 4 +- packages/core-types/tests/core-types.spec.ts | 9 +- packages/node-client/CHANGELOG.md | 22 +- packages/node-client/README.md | 10 +- packages/node-client/package.json | 2 +- packages/node-client/src/INodeClient.ts | 34 +- packages/node-client/src/NodeClient.ts | 85 ++-- packages/node-client/src/index.ts | 8 +- .../node-client/src/types/NodeClientTypes.ts | 352 +++++++------- .../node-client/src/utils/HttpRequests.ts | 48 +- packages/node-client/src/utils/index.ts | 2 +- .../node-client/tests/node-client.spec.ts | 27 +- packages/particle-auth/CHANGELOG.md | 18 +- packages/particle-auth/README.md | 16 +- packages/particle-auth/src/index.ts | 13 +- .../particle-auth/tests/particle-auth.spec.ts | 9 +- packages/particle-auth/tsconfig.json | 9 +- packages/paymaster/CHANGELOG.md | 29 +- packages/paymaster/Readme.md | 40 +- packages/paymaster/package.json | 2 +- packages/paymaster/src/BiconomyPaymaster.ts | 317 ++++++------ packages/paymaster/src/constants.ts | 14 +- packages/paymaster/src/index.ts | 8 +- .../src/interfaces/IHybridPaymaster.ts | 35 +- .../paymaster/src/interfaces/IPaymaster.ts | 8 +- packages/paymaster/src/utils/Types.ts | 148 +++--- packages/paymaster/tests/paymaster.spec.ts | 9 +- packages/paymaster/tsconfig.json | 2 +- packages/transak/CHANGELOG.md | 12 +- packages/transak/README.md | 4 +- packages/transak/src/index.ts | 35 +- packages/transak/src/interface.ts | 102 ++-- packages/transak/tests/transak.spec.ts | 9 +- packages/transak/tsconfig.json | 9 +- packages/web3-auth-native/.prettierrc.yaml | 2 +- packages/web3-auth-native/CHANGELOG.md | 13 +- packages/web3-auth-native/README.md | 1 + packages/web3-auth-native/src/SocialLogin.ts | 5 +- .../tests/web3-auth-native.spec.ts | 9 +- packages/web3-auth-native/tsconfig.json | 16 +- packages/web3-auth/CHANGELOG.md | 58 +-- packages/web3-auth/src/SocialLogin.tsx | 404 +++++++-------- packages/web3-auth/src/UI.tsx | 110 ++--- packages/web3-auth/src/index.ts | 6 +- packages/web3-auth/src/style.css | 51 +- .../web3-auth/src/types/Web3AuthConfig.ts | 20 +- packages/web3-auth/tests/web3-auth.spec.ts | 9 +- packages/web3-auth/tsconfig.json | 9 +- tsconfig.settings.json | 44 +- 96 files changed, 2184 insertions(+), 2630 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index dd84ea782..9b77ea713 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,10 +1,9 @@ --- name: Bug report about: Create a report to help us improve -title: '' -labels: '' -assignees: '' - +title: "" +labels: "" +assignees: "" --- **Describe the bug** @@ -12,6 +11,7 @@ A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: + 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' @@ -24,15 +24,17 @@ A clear and concise description of what you expected to happen. If applicable, add screenshots to help explain your problem. **Desktop (please complete the following information):** - - OS: [e.g. iOS] - - Browser [e.g. chrome, safari] - - Version [e.g. 22] + +- OS: [e.g. iOS] +- Browser [e.g. chrome, safari] +- Version [e.g. 22] **Smartphone (please complete the following information):** - - Device: [e.g. iPhone6] - - OS: [e.g. iOS8.1] - - Browser [e.g. stock browser, safari] - - Version [e.g. 22] + +- Device: [e.g. iPhone6] +- OS: [e.g. iOS8.1] +- Browser [e.g. stock browser, safari] +- Version [e.g. 22] **Additional context** Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index bbcbbe7d6..2bc5d5f71 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,10 +1,9 @@ --- name: Feature request about: Suggest an idea for this project -title: '' -labels: '' -assignees: '' - +title: "" +labels: "" +assignees: "" --- **Is your feature request related to a problem? Please describe.** diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 837ce9029..5fad78231 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -17,12 +17,12 @@ Please delete options that are not relevant. Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration - **Test Configuration**: -* Firmware version: -* Hardware: -* Toolchain: -* SDK: + +- Firmware version: +- Hardware: +- Toolchain: +- SDK: # Checklist: diff --git a/.nycrc.json b/.nycrc.json index 913d652ef..5d9f97afe 100644 --- a/.nycrc.json +++ b/.nycrc.json @@ -1,5 +1,3 @@ { - "include": [ - "src/**/*.ts" - ] + "include": ["src/**/*.ts"] } diff --git a/LICENSE.md b/LICENSE.md index f288702d2..a5eae1527 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,190 +1,190 @@ GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. +Copyright (C) 2007 Free Software Foundation, Inc. +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. Preamble - The GNU General Public License is a free, copyleft license for +The GNU General Public License is a free, copyleft license for software and other kinds of works. - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, +The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the +software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to +any other work released this way by its authors. You can apply it to your programs, too. - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you +When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have +To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. - For example, if you distribute copies of such a program, whether +For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they know their rights. - Developers that use the GNU GPL protect your rights with two steps: +Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and +For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. - Some devices are designed to deny users access to install or run +Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we +use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we +products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. - Finally, every program is threatened constantly by software patents. +Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that +make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. - The precise terms and conditions for copying, distribution and +The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS - 0. Definitions. +0. Definitions. - "This License" refers to version 3 of the GNU General Public License. +"This License" refers to version 3 of the GNU General Public License. - "Copyright" also means copyright-like laws that apply to other kinds of +"Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and +"The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. - To "modify" a work means to copy from or adapt all or part of the work +To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the +exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. - A "covered work" means either the unmodified Program or a work based +A "covered work" means either the unmodified Program or a work based on the Program. - To "propagate" a work means to do anything with it that, without +To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, +computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through +To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. - An interactive user interface displays "Appropriate Legal Notices" +An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If +work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. - 1. Source Code. +1. Source Code. - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source +The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source form of a work. - A "Standard Interface" means an interface that either is an official +A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. - The "System Libraries" of an executable work include anything, other +The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A +implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. - The "Corresponding Source" for a work in object code form means all +The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's +control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source +which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. - The Corresponding Source need not include anything that users +The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. - The Corresponding Source for a work in source code form is that +The Corresponding Source for a work in source code form is that same work. - 2. Basic Permissions. +2. Basic Permissions. - All rights granted under this License are granted for the term of +All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your +content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. - You may make, run and propagate covered works that you do not +You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose +in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works +not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 +Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. +3. Protecting Users' Legal Rights From Anti-Circumvention Law. - No covered work shall be deemed part of an effective technological +No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. - When you convey a covered work, you waive any legal power to forbid +When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or @@ -192,9 +192,9 @@ modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. - 4. Conveying Verbatim Copies. +4. Conveying Verbatim Copies. - You may convey verbatim copies of the Program's source code as you +You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any @@ -202,12 +202,12 @@ non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. - You may charge any price or no price for each copy that you convey, +You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. - 5. Conveying Modified Source Versions. +5. Conveying Modified Source Versions. - You may convey a work based on the Program, or the modifications to +You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: @@ -232,19 +232,19 @@ terms of section 4, provided that you also meet all of these conditions: interfaces that do not display Appropriate Legal Notices, your work need not make them do so. - A compilation of a covered work with other separate and independent +A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work +beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. - 6. Conveying Non-Source Forms. +6. Conveying Non-Source Forms. - You may convey a covered work in object code form under the terms +You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: @@ -290,75 +290,75 @@ in one of these ways: Source of the work are being offered to the general public at no charge under subsection 6d. - A separable portion of the object code, whose source code is excluded +A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. - A "User Product" is either (1) a "consumer product", which means any +A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product +actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. - "Installation Information" for a User Product means any methods, +"Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must +a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. - If you convey an object code work under this section in, or with, or +If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply +by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). - The requirement to provide Installation Information does not include a +The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a +the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. - Corresponding Source conveyed, and Installation Information provided, +Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. - 7. Additional Terms. +7. Additional Terms. - "Additional permissions" are terms that supplement the terms of this +"Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions +that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. - When you convey a copy of a covered work, you may at your option +When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. - Notwithstanding any other provision of this License, for material you +Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: @@ -385,74 +385,74 @@ that material) supplement the terms of this License with terms: any liability that these contractual assumptions directly impose on those licensors and authors. - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you +All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains +restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. - If you add terms to a covered work in accord with this section, you +If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. - Additional terms, permissive or non-permissive, may be stated in the +Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. - 8. Termination. +8. Termination. - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or +You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). - However, if you cease all violation of this License, then your +However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. - Moreover, your license from a particular copyright holder is +Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. - Termination of your rights under this section does not terminate the +Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently +this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. - 9. Acceptance Not Required for Having Copies. +9. Acceptance Not Required for Having Copies. - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work +You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, +to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. - 10. Automatic Licensing of Downstream Recipients. +10. Automatic Licensing of Downstream Recipients. - Each time you convey a covered work, the recipient automatically +Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible +propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. - An "entity transaction" is a transaction transferring control of an +An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered +organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could @@ -460,43 +460,43 @@ give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may +You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. - 11. Patents. +11. Patents. - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The +A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". - A contributor's "essential patent claims" are all patent claims +A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For +consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. - Each contributor grants you a non-exclusive, worldwide, royalty-free +Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. - In the following three paragraphs, a "patent license" is any express +In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a +sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. - If you convey a covered work, knowingly relying on a patent license, +If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, @@ -504,13 +504,13 @@ then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have +license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. - If, pursuant to or in connection with a single transaction or +If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify @@ -518,10 +518,10 @@ or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. - A patent license is "discriminatory" if it does not include within +A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered +specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying @@ -533,73 +533,73 @@ for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. - Nothing in this License shall be construed as excluding or limiting +Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. - 12. No Surrender of Others' Freedom. +12. No Surrender of Others' Freedom. - If conditions are imposed on you (whether by court order, agreement or +If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a +excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you +not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. - 13. Use with the GNU Affero General Public License. +13. Use with the GNU Affero General Public License. - Notwithstanding any other provision of this License, you have +Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this +combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. - 14. Revised Versions of this License. +14. Revised Versions of this License. - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will +The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. - Each version is given a distinguishing version number. If the +Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the +Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. - If the Program specifies that a proxy can decide which future +If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any +Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. - 15. Disclaimer of Warranty. +15. Disclaimer of Warranty. - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - 16. Limitation of Liability. +16. Limitation of Liability. - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE @@ -609,9 +609,9 @@ PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - 17. Interpretation of Sections 15 and 16. +17. Interpretation of Sections 15 and 16. - If the disclaimer of warranty and limitation of liability provided +If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the @@ -622,11 +622,11 @@ copy of the Program in return for a fee. How to Apply These Terms to Your New Programs - If you develop a new program, and you want it to be of the greatest +If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. - To do so, attach the following notices to the program. It is safest +To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. @@ -649,7 +649,7 @@ the "copyright" line and a pointer to where the full notice is found. Also add information on how to contact you by electronic and paper mail. - If the program does terminal interaction, make it output a short +If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) @@ -658,17 +658,17 @@ notice like this when it starts in an interactive mode: under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands +parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". - You should also get your employer (if you work as a programmer) or school, +You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you +The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read . diff --git a/README.md b/README.md index 1870742b5..841e1df9a 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ # Biconomy SDK + The Biconomy Software Development Kit (SDK) is plug & play toolkit for dApps to make use of ERC4337 Account Abstraction and enable a highly customised one-click experiences for their users. It presents a comprehensive range of solutions, from user onboarding to sustained engagement, managing and deploying smart accounts, dispatching user transactions with gas abtraction of your choice. This SDK functions in a non-custodial fashion, provides a unified solution that enhances the user experience within your dApp. +## Packages -## Packages ### Account Building and sending UserOperations is a key offering of any toolkit designed for ERC4337. The Biconomy account package stands as an exemplary toolkit in this regard. Meticulously crafted with developers' needs in mind, this package seamlessly integrates the essential features associated with ERC-4337. It simplifies the process of creating and sending UserOperations, thus optimizing the development and management of decentralized applications (dApps). @@ -11,39 +12,29 @@ The Biconomy account package achieves this by providing a comprehensive set of m ### Bundler -In the context of (ERC4337), the concept of a bundler plays a central role in the infrastructure. This concept is integral to the operation of account abstraction across any network that utilizes the Ethereum Virtual Machine (EVM). +In the context of (ERC4337), the concept of a bundler plays a central role in the infrastructure. This concept is integral to the operation of account abstraction across any network that utilizes the Ethereum Virtual Machine (EVM). Bundler infrastructure is designed and implemented in accordance with standardised specifications. This standardisation across all bundlers offers a significant advantage, particularly when it comes to interoperability with various tools and services, such as the Biconomy SDK. - ### Paymaster ERC4337, Account abstraction, introduces the concept of Paymasters. These specialised entities play a pivotal role in revolutionising the traditional gas payment system in EVM transactions. Paymasters, acting as third-party intermediaries, possess the capability to sponsor gas fees for an account, provided specific predefined conditions are satisfied. - - ## Services Screenshot 2022-11-13 at 7 45 04 PM 1. SDK Backend node - responsible for chain configurations and gas estimation endpoints -2. Indexer +2. Indexer 3. Paymaster Service - used for checking policies and verifying paymaster signing 4. Bundler Node - - ## Quickstart - -https://github.com/bcnmy/sdk-examples/blob/modular-sdk-v3/backend-node/README.md - +https://github.com/bcnmy/sdk-examples/blob/modular-sdk-v3/backend-node/README.md ## Resources -https://docs.biconomy.io/docs/overview - -https://dashboard.biconomy.io/ - - +https://docs.biconomy.io/docs/overview +https://dashboard.biconomy.io/ diff --git a/jest.config.ts b/jest.config.ts index 96259308c..a968e1995 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -3,7 +3,7 @@ * https://jestjs.io/docs/configuration */ -import type {Config} from 'jest'; +import type { Config } from "jest"; const config: Config = { // All imported modules in your tests should be mocked automatically @@ -22,11 +22,7 @@ const config: Config = { collectCoverage: false, // An array of glob patterns indicating a set of files for which coverage information should be collected - collectCoverageFrom: [ - "packages/**/*.{js,ts}", - "!packages/**/node_modules/**", - "!packages/**/dist/**" - ], + collectCoverageFrom: ["packages/**/*.{js,ts}", "!packages/**/node_modules/**", "!packages/**/dist/**"], // The directory where Jest should output its coverage files coverageDirectory: "coverage", @@ -79,16 +75,7 @@ const config: Config = { // ], // An array of file extensions your modules use - moduleFileExtensions: [ - "js", - "mjs", - "cjs", - "jsx", - "ts", - "tsx", - "json", - "node" - ], + moduleFileExtensions: ["js", "mjs", "cjs", "jsx", "ts", "tsx", "json", "node"], // A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module // moduleNameMapper: {}, @@ -103,7 +90,7 @@ const config: Config = { // notifyMode: "failure-change", // A preset that is used as a base for Jest's configuration - preset: 'ts-jest', + preset: "ts-jest", // Run tests from one or more projects // projects: undefined, @@ -127,9 +114,7 @@ const config: Config = { // rootDir: undefined, // A list of paths to directories that Jest should use to search for files in - roots: [ - "/packages/" - ], + roots: ["/packages/"], // Allows you to use a custom runner instead of Jest's default test runner // runner: "jest-runner", @@ -156,7 +141,7 @@ const config: Config = { // testLocationInResults: false, // The glob patterns Jest uses to detect test files - testMatch: ['**/*.spec.ts'], + testMatch: ["**/*.spec.ts"], // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped // testPathIgnorePatterns: [ @@ -174,10 +159,9 @@ const config: Config = { // A map from regular expressions to paths to transformers transform: { - '^.+\\.tsx?$': 'ts-jest', + "^.+\\.tsx?$": "ts-jest", }, - // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation // transformIgnorePatterns: [ // "/node_modules/", diff --git a/lerna.json b/lerna.json index 7f2c1493c..519b24060 100644 --- a/lerna.json +++ b/lerna.json @@ -7,11 +7,5 @@ "conventionalCommits": true } }, - "ignoreChanges": [ - "**/CHANGELOG.md", - "**/node_modules/**", - "**/package.json", - "**/*.md", - "**/perf/**" - ] -} \ No newline at end of file + "ignoreChanges": ["**/CHANGELOG.md", "**/node_modules/**", "**/package.json", "**/*.md", "**/perf/**"] +} diff --git a/packages/account/CHANGELOG.md b/packages/account/CHANGELOG.md index e5012dac7..87a16b748 100644 --- a/packages/account/CHANGELOG.md +++ b/packages/account/CHANGELOG.md @@ -9,40 +9,27 @@ VERSION bump only Modular SDK - consists stable version of below updates done in Alphas. - - ## 3.1.1-alpha.0 (2023-08-02) - ### Bug Fixes VERSION bump only - - - - # 3.1.0-alpha.0 (2023-07-24) - ### Bug Fixes -* avoid sending populated values of gas prices when estimating from bundler ([c58c9fc](https://github.com/bcnmy/biconomy-client-sdk/commit/c58c9fc29ee83978e1a90305e839002431db2b7b)) - - - +- avoid sending populated values of gas prices when estimating from bundler ([c58c9fc](https://github.com/bcnmy/biconomy-client-sdk/commit/c58c9fc29ee83978e1a90305e839002431db2b7b)) ## 3.0.0-alpha.0 (2023-07-12) - ### Bug Fixes -* estimation without bundler ([5e49473](https://github.com/bcnmy/biconomy-client-sdk/commit/5e49473e7745c2e87e241731ef8ca1f65ee90388)) -* unshift error for batch ([4d090e8](https://github.com/bcnmy/biconomy-client-sdk/commit/4d090e8fbc7e7bcc03805d8dd28c738d5c95dae7)) - +- estimation without bundler ([5e49473](https://github.com/bcnmy/biconomy-client-sdk/commit/5e49473e7745c2e87e241731ef8ca1f65ee90388)) +- unshift error for batch ([4d090e8](https://github.com/bcnmy/biconomy-client-sdk/commit/4d090e8fbc7e7bcc03805d8dd28c738d5c95dae7)) ### Features -* get fee quote or data method in biconomy paymaster ([47748a6](https://github.com/bcnmy/biconomy-client-sdk/commit/47748a6384c2b74e1d9be4d570554098e1ac02e7)) -* update responses to support calculateGasLimits flag + update interfaces ([55bbd38](https://github.com/bcnmy/biconomy-client-sdk/commit/55bbd38b4ef8acaf8da1d52e36846557b134aba4)) -* using hybrid paymaster interface ([5fc56a7](https://github.com/bcnmy/biconomy-client-sdk/commit/5fc56a7db2de4a3f4bb87cd4d75584e79010b206)) +- get fee quote or data method in biconomy paymaster ([47748a6](https://github.com/bcnmy/biconomy-client-sdk/commit/47748a6384c2b74e1d9be4d570554098e1ac02e7)) +- update responses to support calculateGasLimits flag + update interfaces ([55bbd38](https://github.com/bcnmy/biconomy-client-sdk/commit/55bbd38b4ef8acaf8da1d52e36846557b134aba4)) +- using hybrid paymaster interface ([5fc56a7](https://github.com/bcnmy/biconomy-client-sdk/commit/5fc56a7db2de4a3f4bb87cd4d75584e79010b206)) diff --git a/packages/account/Readme.md b/packages/account/Readme.md index 66bf46ee4..6fcd0157a 100644 --- a/packages/account/Readme.md +++ b/packages/account/Readme.md @@ -1,9 +1,11 @@ # installation + Using `npm` package manager ```bash -npm i @biconomy/account +npm i @biconomy/account ``` + OR Using `yarn` package manager @@ -18,64 +20,61 @@ Building and sending UserOperations is a key offering of any toolkit designed fo The Biconomy account package achieves this by providing a comprehensive set of methods that enable developers to effortlessly create UserOperations. Combined with the sophisticated backend infrastructure of the Biconomy platform, it ensures efficient and reliable transmission of these operations across EVM networks. - ## Smart Account instance configuration -| Key | Description | -| ------------- | ------------- | -| signer | This signer will be used for signing userOps for any transactions you build. You can supply your your EOA wallet signer| -| chainId | This represents the network your smart wallet transactions will be conducted on. Take a look following Link for supported chain id's | -| rpcUrl | This represents the EVM node RPC URL you'll interact with, adjustable according to your needs. We recommend to use some private node url for efficient userOp building| -| paymaster | you can pass same paymaster instance that you have build in previous step. Alternatively, you can skip this if you are not interested in sponsoring transaction using paymaster| -| | Note: if you don't pass the paymaster instance, your smart account will need funds to pay for transaction fees.| -| bundler | You can pass same bundler instance that you have build in previous step. Alternatively, you can skip this if you are only interested in building userOP| - +| Key | Description | +| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| signer | This signer will be used for signing userOps for any transactions you build. You can supply your your EOA wallet signer | +| chainId | This represents the network your smart wallet transactions will be conducted on. Take a look following Link for supported chain id's | +| rpcUrl | This represents the EVM node RPC URL you'll interact with, adjustable according to your needs. We recommend to use some private node url for efficient userOp building | +| paymaster | you can pass same paymaster instance that you have build in previous step. Alternatively, you can skip this if you are not interested in sponsoring transaction using paymaster | +| | Note: if you don't pass the paymaster instance, your smart account will need funds to pay for transaction fees. | +| bundler | You can pass same bundler instance that you have build in previous step. Alternatively, you can skip this if you are only interested in building userOP | ## Example Usage ```typescript // This is how you create BiconomySmartAccount instance in your dapp's -import { BiconomySmartAccount, BiconomySmartAccountConfig } from "@biconomy/account" +import { BiconomySmartAccount, BiconomySmartAccountConfig } from "@biconomy/account"; -// Note that paymaster and bundler are optional. You can choose to create new instances of this later and make account API use +// Note that paymaster and bundler are optional. You can choose to create new instances of this later and make account API use const biconomySmartAccountConfig: BiconomySmartAccountConfig = { - signer: wallet.getSigner(), - chainId: ChainId.POLYGON_MAINNET, - rpcUrl: '', - // paymaster: paymaster, // check the README.md section of Paymaster package - // bundler: bundler, // check the README.md section of Bundler package -} + signer: wallet.getSigner(), + chainId: ChainId.POLYGON_MAINNET, + rpcUrl: "", + // paymaster: paymaster, // check the README.md section of Paymaster package + // bundler: bundler, // check the README.md section of Bundler package +}; -const biconomyAccount = new BiconomySmartAccount(biconomySmartAccountConfig) -const biconomySmartAccount = await biconomyAccount.init() +const biconomyAccount = new BiconomySmartAccount(biconomySmartAccountConfig); +const biconomySmartAccount = await biconomyAccount.init(); // native token transfer -// you can create any sort of transaction following same structure +// you can create any sort of transaction following same structure const transaction = { - to: '0x85B51B068bF0fefFEFD817882a14f6F5BDF7fF2E', - data: '0x', - value: ethers.utils.parseEther('0.1'), -} + to: "0x85B51B068bF0fefFEFD817882a14f6F5BDF7fF2E", + data: "0x", + value: ethers.utils.parseEther("0.1"), +}; // building partialUserOp -const partialUserOp = await biconomySmartAccount.buildUserOp([transaction]) +const partialUserOp = await biconomySmartAccount.buildUserOp([transaction]); // using the paymaster package one can populate paymasterAndData to partial userOp. by default it is '0x' - - ``` ```typescript -const userOpResponse = await smartAccount.sendUserOp(partialUserOp) -const transactionDetails = await userOpResponse.wait() -console.log("transaction details below") -console.log(transactionDetails) +const userOpResponse = await smartAccount.sendUserOp(partialUserOp); +const transactionDetails = await userOpResponse.wait(); +console.log("transaction details below"); +console.log(transactionDetails); ``` -Finally we send the userOp and save the value to a variable named userOpResponse and get the transactionDetails after calling ```typescript userOpResponse.wait()``` + +Finally we send the userOp and save the value to a variable named userOpResponse and get the transactionDetails after calling `typescript userOpResponse.wait()` ```typescript -const transactionDetails = await userOpResponse.wait() -console.log("transaction details below") -console.log(transactionDetails) -``` \ No newline at end of file +const transactionDetails = await userOpResponse.wait(); +console.log("transaction details below"); +console.log(transactionDetails); +``` diff --git a/packages/account/src/BiconomySmartAccount.ts b/packages/account/src/BiconomySmartAccount.ts index 39623c0a1..ff09de4ea 100644 --- a/packages/account/src/BiconomySmartAccount.ts +++ b/packages/account/src/BiconomySmartAccount.ts @@ -1,6 +1,6 @@ -import { JsonRpcProvider } from '@ethersproject/providers' -import { ethers, BigNumberish, BytesLike, BigNumber } from 'ethers' -import { SmartAccount } from './SmartAccount' +import { JsonRpcProvider } from "@ethersproject/providers"; +import { ethers, BigNumberish, BytesLike, BigNumber } from "ethers"; +import { SmartAccount } from "./SmartAccount"; import { Logger, NODE_CLIENT_URL, @@ -8,19 +8,14 @@ import { SmartAccountFactory_v100, getEntryPointContract, getSAFactoryContract, - getSAProxyContract -} from '@biconomy/common' -import { - BiconomySmartAccountConfig, - Overrides, - BiconomyTokenPaymasterRequest, - InitilizationData -} from './utils/Types' -import { UserOperation, Transaction, SmartAccountType } from '@biconomy/core-types' -import NodeClient from '@biconomy/node-client' -import INodeClient from '@biconomy/node-client' -import { IHybridPaymaster, BiconomyPaymaster, SponsorUserOperationDto } from '@biconomy/paymaster' -import { IBiconomySmartAccount } from 'interfaces/IBiconomySmartAccount' + getSAProxyContract, +} from "@biconomy/common"; +import { BiconomySmartAccountConfig, Overrides, BiconomyTokenPaymasterRequest, InitilizationData } from "./utils/Types"; +import { UserOperation, Transaction, SmartAccountType } from "@biconomy/core-types"; +import NodeClient from "@biconomy/node-client"; +import INodeClient from "@biconomy/node-client"; +import { IHybridPaymaster, BiconomyPaymaster, SponsorUserOperationDto } from "@biconomy/paymaster"; +import { IBiconomySmartAccount } from "interfaces/IBiconomySmartAccount"; import { ISmartAccount, SupportedChainsResponse, @@ -29,203 +24,202 @@ import { UsdBalanceResponse, SmartAccountByOwnerDto, SmartAccountsResponse, - SCWTransactionResponse -} from '@biconomy/node-client' -import { - ENTRYPOINT_ADDRESSES, - BICONOMY_FACTORY_ADDRESSES, - BICONOMY_IMPLEMENTATION_ADDRESSES, - DEFAULT_ENTRYPOINT_ADDRESS -} from './utils/Constants' -import { Signer } from 'ethers' + SCWTransactionResponse, +} from "@biconomy/node-client"; +import { ENTRYPOINT_ADDRESSES, BICONOMY_FACTORY_ADDRESSES, BICONOMY_IMPLEMENTATION_ADDRESSES, DEFAULT_ENTRYPOINT_ADDRESS } from "./utils/Constants"; +import { Signer } from "ethers"; export class BiconomySmartAccount extends SmartAccount implements IBiconomySmartAccount { - private factory!: SmartAccountFactory_v100 - private nodeClient: INodeClient - private accountIndex!: number - private address!: string - private smartAccountInfo!: ISmartAccount - private _isInitialised!: boolean + private factory!: SmartAccountFactory_v100; + + private nodeClient: INodeClient; + + private accountIndex!: number; + + private address!: string; + + private smartAccountInfo!: ISmartAccount; + + private _isInitialised!: boolean; constructor(readonly biconomySmartAccountConfig: BiconomySmartAccountConfig) { - const { signer, rpcUrl, entryPointAddress, bundler, paymaster, chainId, nodeClientUrl } = - biconomySmartAccountConfig + const { signer, rpcUrl, entryPointAddress, bundler, paymaster, chainId, nodeClientUrl } = biconomySmartAccountConfig; - const _entryPointAddress = entryPointAddress ?? DEFAULT_ENTRYPOINT_ADDRESS + const _entryPointAddress = entryPointAddress ?? DEFAULT_ENTRYPOINT_ADDRESS; super({ bundler, - entryPointAddress: _entryPointAddress - }) - const _rpcUrl = rpcUrl ?? RPC_PROVIDER_URLS[chainId] + entryPointAddress: _entryPointAddress, + }); + const _rpcUrl = rpcUrl ?? RPC_PROVIDER_URLS[chainId]; if (!_rpcUrl) { throw new Error( - `Chain Id ${chainId} is not supported. Please refer to the following link for supported chains list https://docs.biconomy.io/build-with-biconomy-sdk/gasless-transactions#supported-chains` - ) + `Chain Id ${chainId} is not supported. Please refer to the following link for supported chains list https://docs.biconomy.io/build-with-biconomy-sdk/gasless-transactions#supported-chains`, + ); } - this.provider = new JsonRpcProvider(_rpcUrl) - this.nodeClient = new NodeClient({ txServiceUrl: nodeClientUrl ?? NODE_CLIENT_URL }) - this.signer = signer + this.provider = new JsonRpcProvider(_rpcUrl); + this.nodeClient = new NodeClient({ txServiceUrl: nodeClientUrl ?? NODE_CLIENT_URL }); + this.signer = signer; if (paymaster) { - this.paymaster = paymaster + this.paymaster = paymaster; } - if (bundler) this.bundler = bundler + if (bundler) this.bundler = bundler; } + /** * @description This function will initialise BiconomyAccount class state * @returns Promise */ async init(initilizationData?: InitilizationData): Promise { try { - let _accountIndex, signerAddress + let _accountIndex, signerAddress; if (initilizationData) { - _accountIndex = initilizationData.accountIndex - signerAddress = initilizationData.signerAddress + _accountIndex = initilizationData.accountIndex; + signerAddress = initilizationData.signerAddress; } - if (!_accountIndex) _accountIndex = 0 - this.isProviderDefined() - this.isSignerDefined() + if (!_accountIndex) _accountIndex = 0; + this.isProviderDefined(); + this.isSignerDefined(); if (signerAddress) { - this.owner = signerAddress + this.owner = signerAddress; } else { - this.owner = await this.signer.getAddress() + this.owner = await this.signer.getAddress(); } - this.chainId = await this.provider.getNetwork().then((net) => net.chainId) - await this.initializeAccountAtIndex(_accountIndex) - this._isInitialised = true + this.chainId = await this.provider.getNetwork().then((net) => net.chainId); + await this.initializeAccountAtIndex(_accountIndex); + this._isInitialised = true; } catch (error) { - Logger.error(`Failed to call init: ${error}`) - throw error + Logger.error(`Failed to call init: ${error}`); + throw error; } - return this + return this; } async attachSigner(_signer: Signer): Promise { try { - this.signer = _signer - this.owner = await this.signer.getAddress() + this.signer = _signer; + this.owner = await this.signer.getAddress(); } catch (error) { - throw new Error(`Failed to get signer address`) + throw new Error(`Failed to get signer address`); } } private isInitialized(): boolean { if (!this._isInitialised) throw new Error( - 'BiconomySmartAccount is not initialized. Please call init() on BiconomySmartAccount instance before interacting with any other function' - ) - return true + "BiconomySmartAccount is not initialized. Please call init() on BiconomySmartAccount instance before interacting with any other function", + ); + return true; } private setProxyContractState() { if (!BICONOMY_IMPLEMENTATION_ADDRESSES[this.smartAccountInfo.implementationAddress]) throw new Error( - 'Could not find attached implementation address against your smart account. Please raise an issue on https://github.com/bcnmy/biconomy-client-sdk for further investigation.' - ) + "Could not find attached implementation address against your smart account. Please raise an issue on https://github.com/bcnmy/biconomy-client-sdk for further investigation.", + ); const proxyInstanceDto = { smartAccountType: SmartAccountType.BICONOMY, version: BICONOMY_IMPLEMENTATION_ADDRESSES[this.address], contractAddress: this.address, - provider: this.provider - } - this.proxy = getSAProxyContract(proxyInstanceDto) + provider: this.provider, + }; + this.proxy = getSAProxyContract(proxyInstanceDto); } private setEntryPointContractState() { - const _entryPointAddress = this.smartAccountInfo.entryPointAddress - this.setEntryPointAddress(_entryPointAddress) + const _entryPointAddress = this.smartAccountInfo.entryPointAddress; + this.setEntryPointAddress(_entryPointAddress); if (!ENTRYPOINT_ADDRESSES[_entryPointAddress]) throw new Error( - 'Could not find attached entrypoint address against your smart account. Please raise an issue on https://github.com/bcnmy/biconomy-client-sdk for further investigation.' - ) + "Could not find attached entrypoint address against your smart account. Please raise an issue on https://github.com/bcnmy/biconomy-client-sdk for further investigation.", + ); const entryPointInstanceDto = { smartAccountType: SmartAccountType.BICONOMY, version: ENTRYPOINT_ADDRESSES[_entryPointAddress], contractAddress: _entryPointAddress, - provider: this.provider - } - this.entryPoint = getEntryPointContract(entryPointInstanceDto) + provider: this.provider, + }; + this.entryPoint = getEntryPointContract(entryPointInstanceDto); } private setFactoryContractState() { - const _factoryAddress = this.smartAccountInfo.factoryAddress + const _factoryAddress = this.smartAccountInfo.factoryAddress; if (!BICONOMY_FACTORY_ADDRESSES[_factoryAddress]) throw new Error( - 'Could not find attached factory address against your smart account. Please raise an issue on https://github.com/bcnmy/biconomy-client-sdk for further investigation.' - ) + "Could not find attached factory address against your smart account. Please raise an issue on https://github.com/bcnmy/biconomy-client-sdk for further investigation.", + ); const factoryInstanceDto = { smartAccountType: SmartAccountType.BICONOMY, version: BICONOMY_FACTORY_ADDRESSES[_factoryAddress], contractAddress: _factoryAddress, - provider: this.provider - } - this.factory = getSAFactoryContract(factoryInstanceDto) + provider: this.provider, + }; + this.factory = getSAFactoryContract(factoryInstanceDto); } private async setContractsState() { - this.setProxyContractState() - this.setEntryPointContractState() - this.setFactoryContractState() + this.setProxyContractState(); + this.setEntryPointContractState(); + this.setFactoryContractState(); } async initializeAccountAtIndex(accountIndex: number): Promise { - this.accountIndex = accountIndex - this.address = await this.getSmartAccountAddress(accountIndex) - await this.setContractsState() - await this.setInitCode(this.accountIndex) + this.accountIndex = accountIndex; + this.address = await this.getSmartAccountAddress(accountIndex); + await this.setContractsState(); + await this.setInitCode(this.accountIndex); } async getSmartAccountAddress(accountIndex = 0): Promise { try { - this.isSignerDefined() + this.isSignerDefined(); let smartAccountsList: ISmartAccount[] = ( await this.getSmartAccountsByOwner({ chainId: this.chainId, owner: this.owner, - index: accountIndex + index: accountIndex, }) - ).data + ).data; if (!smartAccountsList) throw new Error( - 'Failed to get smart account address. Please raise an issue on https://github.com/bcnmy/biconomy-client-sdk for further investigation.' - ) + "Failed to get smart account address. Please raise an issue on https://github.com/bcnmy/biconomy-client-sdk for further investigation.", + ); smartAccountsList = smartAccountsList.filter((smartAccount: ISmartAccount) => { - return accountIndex === smartAccount.index - }) + return accountIndex === smartAccount.index; + }); if (smartAccountsList.length === 0) throw new Error( - 'Failed to get smart account address. Please raise an issue on https://github.com/bcnmy/biconomy-client-sdk for further investigation.' - ) - this.smartAccountInfo = smartAccountsList[0] - return this.smartAccountInfo.smartAccountAddress + "Failed to get smart account address. Please raise an issue on https://github.com/bcnmy/biconomy-client-sdk for further investigation.", + ); + this.smartAccountInfo = smartAccountsList[0]; + return this.smartAccountInfo.smartAccountAddress; } catch (error) { - Logger.error(`Failed to get smart account address: ${error}`) - throw error + Logger.error(`Failed to get smart account address: ${error}`); + throw error; } } private async setInitCode(accountIndex = 0): Promise { this.initCode = ethers.utils.hexConcat([ this.factory.address, - this.factory.interface.encodeFunctionData('deployCounterFactualAccount', [ - this.owner, - ethers.BigNumber.from(accountIndex) - ]) - ]) - return this.initCode + this.factory.interface.encodeFunctionData("deployCounterFactualAccount", [this.owner, ethers.BigNumber.from(accountIndex)]), + ]); + return this.initCode; } + /** * @description an overrided function to showcase overriding example * @returns */ nonce(): Promise { - this.isProxyDefined() - return this.proxy.nonce() + this.isProxyDefined(); + return this.proxy.nonce(); } + /** * * @param to { target } address of transaction @@ -234,15 +228,12 @@ export class BiconomySmartAccount extends SmartAccount implements IBiconomySmart * @returns */ getExecuteCallData(to: string, value: BigNumberish, data: BytesLike): string { - this.isInitialized() - this.isProxyDefined() - const executeCallData = this.proxy.interface.encodeFunctionData('executeCall', [ - to, - value, - data - ]) - return executeCallData + this.isInitialized(); + this.isProxyDefined(); + const executeCallData = this.proxy.interface.encodeFunctionData("executeCall", [to, value, data]); + return executeCallData; } + /** * * @param to { target } array of addresses in transaction @@ -250,103 +241,84 @@ export class BiconomySmartAccount extends SmartAccount implements IBiconomySmart * @param data represent array of data associated with each transaction * @returns */ - getExecuteBatchCallData( - to: Array, - value: Array, - data: Array - ): string { - this.isInitialized() - this.isProxyDefined() - const executeBatchCallData = this.proxy.interface.encodeFunctionData('executeBatchCall', [ - to, - value, - data - ]) - return executeBatchCallData + getExecuteBatchCallData(to: Array, value: Array, data: Array): string { + this.isInitialized(); + this.isProxyDefined(); + const executeBatchCallData = this.proxy.interface.encodeFunctionData("executeBatchCall", [to, value, data]); + return executeBatchCallData; } getDummySignature(): string { - return '0x73c3ac716c487ca34bb858247b5ccf1dc354fbaabdd089af3b2ac8e78ba85a4959a2d76250325bd67c11771c31fccda87c33ceec17cc0de912690521bb95ffcb1b' + return "0x73c3ac716c487ca34bb858247b5ccf1dc354fbaabdd089af3b2ac8e78ba85a4959a2d76250325bd67c11771c31fccda87c33ceec17cc0de912690521bb95ffcb1b"; } getDummyPaymasterData(): string { - return '0x' + return "0x"; } - async buildUserOp( - transactions: Transaction[], - overrides?: Overrides, - skipBundlerGasEstimation?: boolean - ): Promise> { - this.isInitialized() + async buildUserOp(transactions: Transaction[], overrides?: Overrides, skipBundlerGasEstimation?: boolean): Promise> { + this.isInitialized(); // TODO: validate to, value and data fields // TODO: validate overrides if supplied - const to = transactions.map((element: Transaction) => element.to) - const data = transactions.map((element: Transaction) => element.data ?? '0x') - const value = transactions.map((element: Transaction) => element.value ?? BigNumber.from('0')) - this.isProxyDefined() + const to = transactions.map((element: Transaction) => element.to); + const data = transactions.map((element: Transaction) => element.data ?? "0x"); + const value = transactions.map((element: Transaction) => element.value ?? BigNumber.from("0")); + this.isProxyDefined(); - let callData = '' + let callData = ""; if (transactions.length === 1) { - callData = this.getExecuteCallData(to[0], value[0], data[0]) + callData = this.getExecuteCallData(to[0], value[0], data[0]); } else { - callData = this.getExecuteBatchCallData(to, value, data) + callData = this.getExecuteBatchCallData(to, value, data); } - let nonce = BigNumber.from(0) + let nonce = BigNumber.from(0); try { - nonce = await this.nonce() + nonce = await this.nonce(); } catch (error) { // Not throwing this error as nonce would be 0 if this.nonce() throw exception, which is expected flow for undeployed account } - let isDeployed = true + let isDeployed = true; if (nonce.eq(0)) { - isDeployed = await this.isAccountDeployed(this.address) + isDeployed = await this.isAccountDeployed(this.address); } let userOp: Partial = { sender: this.address, nonce, - initCode: !isDeployed ? this.initCode : '0x', - callData: callData - } + initCode: !isDeployed ? this.initCode : "0x", + callData: callData, + }; // for this Smart Account dummy ECDSA signature will be used to estimate gas - userOp.signature = this.getDummySignature() + userOp.signature = this.getDummySignature(); - userOp = await this.estimateUserOpGas(userOp, overrides, skipBundlerGasEstimation) - Logger.log('userOp after estimation ', userOp) + userOp = await this.estimateUserOpGas(userOp, overrides, skipBundlerGasEstimation); + Logger.log("userOp after estimation ", userOp); // Do not populate paymasterAndData as part of buildUserOp as it may not have all necessary details - userOp.paymasterAndData = '0x' // await this.getPaymasterAndData(userOp) + userOp.paymasterAndData = "0x"; // await this.getPaymasterAndData(userOp) - return userOp + return userOp; } - private validateUserOpAndRequest( - userOp: Partial, - tokenPaymasterRequest: BiconomyTokenPaymasterRequest - ): void { + private validateUserOpAndRequest(userOp: Partial, tokenPaymasterRequest: BiconomyTokenPaymasterRequest): void { if (!userOp.callData) { - throw new Error('Userop callData cannot be undefined') + throw new Error("Userop callData cannot be undefined"); } - const feeTokenAddress = tokenPaymasterRequest?.feeQuote?.tokenAddress - Logger.log('requested fee token is ', feeTokenAddress) + const feeTokenAddress = tokenPaymasterRequest?.feeQuote?.tokenAddress; + Logger.log("requested fee token is ", feeTokenAddress); if (!feeTokenAddress || feeTokenAddress == ethers.constants.AddressZero) { - throw new Error( - 'Invalid or missing token address. Token address must be part of the feeQuote in tokenPaymasterRequest' - ) + throw new Error("Invalid or missing token address. Token address must be part of the feeQuote in tokenPaymasterRequest"); } - const spender = tokenPaymasterRequest?.spender - Logger.log('fee token approval to be checked and added for spender: ', spender) + const spender = tokenPaymasterRequest?.spender; + Logger.log("fee token approval to be checked and added for spender: ", spender); if (!spender || spender == ethers.constants.AddressZero) { - throw new Error( - 'Invalid or missing spender address. Sepnder address must be part of tokenPaymasterRequest' - ) + throw new Error("Invalid or missing spender address. Sepnder address must be part of tokenPaymasterRequest"); } } @@ -361,78 +333,79 @@ export class BiconomySmartAccount extends SmartAccount implements IBiconomySmart */ async buildTokenPaymasterUserOp( userOp: Partial, - tokenPaymasterRequest: BiconomyTokenPaymasterRequest + tokenPaymasterRequest: BiconomyTokenPaymasterRequest, ): Promise> { - this.validateUserOpAndRequest(userOp, tokenPaymasterRequest) + this.validateUserOpAndRequest(userOp, tokenPaymasterRequest); try { - let batchTo: Array = [] - let batchValue: Array = [] - let batchData: Array = [] + let batchTo: Array = []; + let batchValue: Array = []; + let batchData: Array = []; - let newCallData = userOp.callData - Logger.log('received information about fee token address and quote ', tokenPaymasterRequest) + let newCallData = userOp.callData; + Logger.log("received information about fee token address and quote ", tokenPaymasterRequest); if (this.paymaster && this.paymaster instanceof BiconomyPaymaster) { // Make a call to paymaster.buildTokenApprovalTransaction() with necessary details // Review: might request this form of an array of Transaction - const approvalRequest: Transaction = await ( - this.paymaster as IHybridPaymaster - ).buildTokenApprovalTransaction(tokenPaymasterRequest, this.provider) - Logger.log('approvalRequest is for erc20 token ', approvalRequest.to) - - if (approvalRequest.data == '0x' || approvalRequest.to == ethers.constants.AddressZero) { - return userOp + const approvalRequest: Transaction = await (this.paymaster as IHybridPaymaster).buildTokenApprovalTransaction( + tokenPaymasterRequest, + this.provider, + ); + Logger.log("approvalRequest is for erc20 token ", approvalRequest.to); + + if (approvalRequest.data == "0x" || approvalRequest.to == ethers.constants.AddressZero) { + return userOp; } if (!userOp.callData) { - throw new Error('Userop callData cannot be undefined') + throw new Error("Userop callData cannot be undefined"); } const decodedDataSmartWallet = this.proxy.interface.parseTransaction({ - data: userOp.callData.toString() - }) + data: userOp.callData.toString(), + }); if (!decodedDataSmartWallet) { - throw new Error('Could not parse call data of smart wallet for userOp') + throw new Error("Could not parse call data of smart wallet for userOp"); } - const smartWalletExecFunctionName = decodedDataSmartWallet.name - - if (smartWalletExecFunctionName === 'executeCall') { - Logger.log('originally an executeCall for Biconomy Account') - const methodArgsSmartWalletExecuteCall = decodedDataSmartWallet.args - const toOriginal = methodArgsSmartWalletExecuteCall[0] - const valueOriginal = methodArgsSmartWalletExecuteCall[1] - const dataOriginal = methodArgsSmartWalletExecuteCall[2] - - batchTo.push(toOriginal) - batchValue.push(valueOriginal) - batchData.push(dataOriginal) - } else if (smartWalletExecFunctionName === 'executeBatchCall') { - Logger.log('originally an executeBatchCall for Biconomy Account') - const methodArgsSmartWalletExecuteCall = decodedDataSmartWallet.args - batchTo = methodArgsSmartWalletExecuteCall[0] - batchValue = methodArgsSmartWalletExecuteCall[1] - batchData = methodArgsSmartWalletExecuteCall[2] + const smartWalletExecFunctionName = decodedDataSmartWallet.name; + + if (smartWalletExecFunctionName === "executeCall") { + Logger.log("originally an executeCall for Biconomy Account"); + const methodArgsSmartWalletExecuteCall = decodedDataSmartWallet.args; + const toOriginal = methodArgsSmartWalletExecuteCall[0]; + const valueOriginal = methodArgsSmartWalletExecuteCall[1]; + const dataOriginal = methodArgsSmartWalletExecuteCall[2]; + + batchTo.push(toOriginal); + batchValue.push(valueOriginal); + batchData.push(dataOriginal); + } else if (smartWalletExecFunctionName === "executeBatchCall") { + Logger.log("originally an executeBatchCall for Biconomy Account"); + const methodArgsSmartWalletExecuteCall = decodedDataSmartWallet.args; + batchTo = methodArgsSmartWalletExecuteCall[0]; + batchValue = methodArgsSmartWalletExecuteCall[1]; + batchData = methodArgsSmartWalletExecuteCall[2]; } if (approvalRequest.to && approvalRequest.data && approvalRequest.value) { - batchTo = [approvalRequest.to, ...batchTo] - batchValue = [approvalRequest.value, ...batchValue] - batchData = [approvalRequest.data, ...batchData] + batchTo = [approvalRequest.to, ...batchTo]; + batchValue = [approvalRequest.value, ...batchValue]; + batchData = [approvalRequest.data, ...batchData]; - newCallData = this.getExecuteBatchCallData(batchTo, batchValue, batchData) + newCallData = this.getExecuteBatchCallData(batchTo, batchValue, batchData); } let finalUserOp: Partial = { ...userOp, - callData: newCallData - } + callData: newCallData, + }; // Requesting to update gas limits again (especially callGasLimit needs to be re-calculated) try { - delete finalUserOp.callGasLimit - delete finalUserOp.verificationGasLimit - delete finalUserOp.preVerificationGas + delete finalUserOp.callGasLimit; + delete finalUserOp.verificationGasLimit; + delete finalUserOp.preVerificationGas; // Maybe send paymasterAndData since we know it's for Token paymaster /*finalUserOp.paymasterAndData = @@ -440,57 +413,50 @@ export class BiconomySmartAccount extends SmartAccount implements IBiconomySmart // Review: and handle the case when mock pnd fails with AA31 during simulation. - finalUserOp = await this.estimateUserOpGas(finalUserOp) - const cgl = ethers.BigNumber.from(finalUserOp.callGasLimit) - if (finalUserOp.callGasLimit && cgl.lt(ethers.BigNumber.from('21000'))) { + finalUserOp = await this.estimateUserOpGas(finalUserOp); + const cgl = ethers.BigNumber.from(finalUserOp.callGasLimit); + if (finalUserOp.callGasLimit && cgl.lt(ethers.BigNumber.from("21000"))) { return { ...userOp, - callData: newCallData - } + callData: newCallData, + }; } - Logger.log('userOp after estimation ', finalUserOp) + Logger.log("userOp after estimation ", finalUserOp); } catch (error) { - Logger.error('Failed to estimate gas for userOp with updated callData ', error) - Logger.log( - 'sending updated userOp. calculateGasLimit flag should be sent to the paymaster to be able to update callGasLimit' - ) + Logger.error("Failed to estimate gas for userOp with updated callData ", error); + Logger.log("sending updated userOp. calculateGasLimit flag should be sent to the paymaster to be able to update callGasLimit"); } - return finalUserOp + return finalUserOp; } } catch (error) { - Logger.log('Failed to update userOp. sending back original op') - Logger.error('Failed to update callData with error', error) - return userOp + Logger.log("Failed to update userOp. sending back original op"); + Logger.error("Failed to update callData with error", error); + return userOp; } - return userOp + return userOp; } async getAllTokenBalances(balancesDto: BalancesDto): Promise { - return this.nodeClient.getAllTokenBalances(balancesDto) + return this.nodeClient.getAllTokenBalances(balancesDto); } async getTotalBalanceInUsd(balancesDto: BalancesDto): Promise { - return this.nodeClient.getTotalBalanceInUsd(balancesDto) + return this.nodeClient.getTotalBalanceInUsd(balancesDto); } - async getSmartAccountsByOwner( - smartAccountByOwnerDto: SmartAccountByOwnerDto - ): Promise { - return this.nodeClient.getSmartAccountsByOwner(smartAccountByOwnerDto) + async getSmartAccountsByOwner(smartAccountByOwnerDto: SmartAccountByOwnerDto): Promise { + return this.nodeClient.getSmartAccountsByOwner(smartAccountByOwnerDto); } - async getTransactionsByAddress( - chainId: number, - address: string - ): Promise { - return this.nodeClient.getTransactionByAddress(chainId, address) + async getTransactionsByAddress(chainId: number, address: string): Promise { + return this.nodeClient.getTransactionByAddress(chainId, address); } async getTransactionByHash(txHash: string): Promise { - return this.nodeClient.getTransactionByHash(txHash) + return this.nodeClient.getTransactionByHash(txHash); } async getAllSupportedChains(): Promise { - return this.nodeClient.getAllSupportedChains() + return this.nodeClient.getAllSupportedChains(); } } diff --git a/packages/account/src/SmartAccount.ts b/packages/account/src/SmartAccount.ts index b9a21fe69..8cdd7448d 100644 --- a/packages/account/src/SmartAccount.ts +++ b/packages/account/src/SmartAccount.ts @@ -1,258 +1,238 @@ -import { JsonRpcProvider } from '@ethersproject/providers' -import { BigNumber, Signer, BytesLike } from 'ethers' -import { ISmartAccount } from './interfaces/ISmartAccount' -import { defaultAbiCoder, keccak256, arrayify } from 'ethers/lib/utils' -import { UserOperation, ChainId } from '@biconomy/core-types' -import { calcPreVerificationGas, DefaultGasLimits } from './utils/Preverificaiton' -import { packUserOp } from '@biconomy/common' +import { JsonRpcProvider } from "@ethersproject/providers"; +import { BigNumber, Signer, BytesLike } from "ethers"; +import { ISmartAccount } from "./interfaces/ISmartAccount"; +import { defaultAbiCoder, keccak256, arrayify } from "ethers/lib/utils"; +import { UserOperation, ChainId } from "@biconomy/core-types"; +import { calcPreVerificationGas, DefaultGasLimits } from "./utils/Preverificaiton"; +import { packUserOp } from "@biconomy/common"; -import { IBundler, UserOpResponse } from '@biconomy/bundler' -import { IPaymaster, PaymasterAndDataResponse } from '@biconomy/paymaster' -import { EntryPoint_v100, SmartAccount_v100, Logger } from '@biconomy/common' -import { SmartAccountConfig, Overrides } from './utils/Types' +import { IBundler, UserOpResponse } from "@biconomy/bundler"; +import { IPaymaster, PaymasterAndDataResponse } from "@biconomy/paymaster"; +import { EntryPoint_v100, SmartAccount_v100, Logger } from "@biconomy/common"; +import { SmartAccountConfig, Overrides } from "./utils/Types"; -type UserOperationKey = keyof UserOperation +type UserOperationKey = keyof UserOperation; export abstract class SmartAccount implements ISmartAccount { - bundler!: IBundler - paymaster!: IPaymaster - initCode = '0x' - proxy!: SmartAccount_v100 - owner!: string - provider!: JsonRpcProvider - entryPoint!: EntryPoint_v100 - chainId!: ChainId - signer!: Signer - smartAccountConfig: SmartAccountConfig + bundler!: IBundler; + + paymaster!: IPaymaster; + + initCode = "0x"; + + proxy!: SmartAccount_v100; + + owner!: string; + + provider!: JsonRpcProvider; + + entryPoint!: EntryPoint_v100; + + chainId!: ChainId; + + signer!: Signer; + + smartAccountConfig: SmartAccountConfig; constructor(_smartAccountConfig: SmartAccountConfig) { - this.smartAccountConfig = _smartAccountConfig + this.smartAccountConfig = _smartAccountConfig; } setEntryPointAddress(entryPointAddress: string) { - this.smartAccountConfig.entryPointAddress = entryPointAddress + this.smartAccountConfig.entryPointAddress = entryPointAddress; } - private validateUserOp( - userOp: Partial, - requiredFields: UserOperationKey[] - ): boolean { + private validateUserOp(userOp: Partial, requiredFields: UserOperationKey[]): boolean { for (const field of requiredFields) { if (!userOp[field]) { - throw new Error(`${field} is missing`) + throw new Error(`${field} is missing`); } } - return true + return true; } isProxyDefined(): boolean { - if (!this.proxy) throw new Error('Proxy is undefined') + if (!this.proxy) throw new Error("Proxy is undefined"); - return true + return true; } isSignerDefined(): boolean { - if (!this.signer) throw new Error('Signer is undefined') + if (!this.signer) throw new Error("Signer is undefined"); - return true + return true; } isProviderDefined(): boolean { - if (!this.provider) throw new Error('Provider is undefined') + if (!this.provider) throw new Error("Provider is undefined"); - return true + return true; } - abstract getDummySignature(): string + abstract getDummySignature(): string; async calculateUserOpGasValues(userOp: Partial): Promise> { - if (!this.provider) throw new Error('Provider is not present for making rpc calls') - const feeData = await this.provider.getFeeData() - userOp.maxFeePerGas = - userOp.maxFeePerGas ?? - feeData.maxFeePerGas ?? - feeData.gasPrice ?? - (await this.provider.getGasPrice()) + if (!this.provider) throw new Error("Provider is not present for making rpc calls"); + const feeData = await this.provider.getFeeData(); + userOp.maxFeePerGas = userOp.maxFeePerGas ?? feeData.maxFeePerGas ?? feeData.gasPrice ?? (await this.provider.getGasPrice()); userOp.maxPriorityFeePerGas = - userOp.maxPriorityFeePerGas ?? - feeData.maxPriorityFeePerGas ?? - feeData.gasPrice ?? - (await this.provider.getGasPrice()) + userOp.maxPriorityFeePerGas ?? feeData.maxPriorityFeePerGas ?? feeData.gasPrice ?? (await this.provider.getGasPrice()); if (userOp.initCode) userOp.verificationGasLimit = userOp.verificationGasLimit !== null || userOp.verificationGasLimit !== undefined ? userOp.verificationGasLimit - : await this.getVerificationGasLimit(userOp.initCode) + : await this.getVerificationGasLimit(userOp.initCode); userOp.callGasLimit = userOp.callGasLimit !== null || userOp.callGasLimit !== undefined ? userOp.callGasLimit : await this.provider.estimateGas({ from: this.smartAccountConfig.entryPointAddress, to: userOp.sender, - data: userOp.callData - }) + data: userOp.callData, + }); userOp.preVerificationGas = - userOp.preVerificationGas !== null || userOp.preVerificationGas !== undefined - ? userOp.preVerificationGas - : this.getPreVerificationGas(userOp) - return userOp + userOp.preVerificationGas !== null || userOp.preVerificationGas !== undefined ? userOp.preVerificationGas : this.getPreVerificationGas(userOp); + return userOp; } async estimateUserOpGas( userOp: Partial, overrides?: Overrides, - skipBundlerGasEstimation?: boolean + skipBundlerGasEstimation?: boolean, ): Promise> { - const requiredFields: UserOperationKey[] = ['sender', 'nonce', 'initCode', 'callData'] - this.validateUserOp(userOp, requiredFields) + const requiredFields: UserOperationKey[] = ["sender", "nonce", "initCode", "callData"]; + this.validateUserOp(userOp, requiredFields); - let finalUserOp = userOp - const skipBundlerCall = skipBundlerGasEstimation ?? false + let finalUserOp = userOp; + const skipBundlerCall = skipBundlerGasEstimation ?? false; // Override gas values in userOp if provided in overrides params if (overrides) { - userOp = { ...userOp, ...overrides } + userOp = { ...userOp, ...overrides }; } - Logger.log('userOp in estimation', userOp) + Logger.log("userOp in estimation", userOp); if (!this.bundler || skipBundlerCall) { - if (!this.provider) throw new Error('Provider is not present for making rpc calls') + if (!this.provider) throw new Error("Provider is not present for making rpc calls"); // if no bundler url is provided run offchain logic to assign following values of UserOp // maxFeePerGas, maxPriorityFeePerGas, verificationGasLimit, callGasLimit, preVerificationGas - finalUserOp = await this.calculateUserOpGasValues(userOp) + finalUserOp = await this.calculateUserOpGasValues(userOp); } else { - delete userOp.maxFeePerGas - delete userOp.maxPriorityFeePerGas + delete userOp.maxFeePerGas; + delete userOp.maxPriorityFeePerGas; // Making call to bundler to get gas estimations for userOp - const { - callGasLimit, - verificationGasLimit, - preVerificationGas, - maxFeePerGas, - maxPriorityFeePerGas - } = await this.bundler.estimateUserOpGas(userOp) - if ( - !userOp.maxFeePerGas && - !userOp.maxPriorityFeePerGas && - (!maxFeePerGas || !maxPriorityFeePerGas) - ) { - const feeData = await this.provider.getFeeData() - finalUserOp.maxFeePerGas = - feeData.maxFeePerGas ?? feeData.gasPrice ?? (await this.provider.getGasPrice()) - finalUserOp.maxPriorityFeePerGas = - feeData.maxPriorityFeePerGas ?? feeData.gasPrice ?? (await this.provider.getGasPrice()) + const { callGasLimit, verificationGasLimit, preVerificationGas, maxFeePerGas, maxPriorityFeePerGas } = + await this.bundler.estimateUserOpGas(userOp); + if (!userOp.maxFeePerGas && !userOp.maxPriorityFeePerGas && (!maxFeePerGas || !maxPriorityFeePerGas)) { + const feeData = await this.provider.getFeeData(); + finalUserOp.maxFeePerGas = feeData.maxFeePerGas ?? feeData.gasPrice ?? (await this.provider.getGasPrice()); + finalUserOp.maxPriorityFeePerGas = feeData.maxPriorityFeePerGas ?? feeData.gasPrice ?? (await this.provider.getGasPrice()); } else { - finalUserOp.maxFeePerGas = maxFeePerGas ?? userOp.maxFeePerGas - finalUserOp.maxPriorityFeePerGas = maxPriorityFeePerGas ?? userOp.maxPriorityFeePerGas + finalUserOp.maxFeePerGas = maxFeePerGas ?? userOp.maxFeePerGas; + finalUserOp.maxPriorityFeePerGas = maxPriorityFeePerGas ?? userOp.maxPriorityFeePerGas; } - finalUserOp.verificationGasLimit = verificationGasLimit ?? userOp.verificationGasLimit - finalUserOp.callGasLimit = callGasLimit ?? userOp.callGasLimit - finalUserOp.preVerificationGas = preVerificationGas ?? userOp.preVerificationGas + finalUserOp.verificationGasLimit = verificationGasLimit ?? userOp.verificationGasLimit; + finalUserOp.callGasLimit = callGasLimit ?? userOp.callGasLimit; + finalUserOp.preVerificationGas = preVerificationGas ?? userOp.preVerificationGas; } - return finalUserOp + return finalUserOp; } async isAccountDeployed(address: string): Promise { - this.isProviderDefined() - let contractCode + this.isProviderDefined(); + let contractCode; try { - contractCode = await this.provider.getCode(address) - return contractCode !== '0x' + contractCode = await this.provider.getCode(address); + return contractCode !== "0x"; } catch (error) { - throw error + throw error; } } // Would only be used if paymaster is attached async getPaymasterAndData(userOp: Partial): Promise { if (this.paymaster) { - const paymasterAndDataResponse: PaymasterAndDataResponse = - await this.paymaster.getPaymasterAndData(userOp) - return paymasterAndDataResponse.paymasterAndData + const paymasterAndDataResponse: PaymasterAndDataResponse = await this.paymaster.getPaymasterAndData(userOp); + return paymasterAndDataResponse.paymasterAndData; } - return '0x' + return "0x"; } nonce(): Promise { - this.isProxyDefined() - return this.proxy.nonce() + this.isProxyDefined(); + return this.proxy.nonce(); } async signUserOpHash(userOpHash: string, signer?: Signer): Promise { if (signer) { - return signer.signMessage(arrayify(userOpHash)) + return signer.signMessage(arrayify(userOpHash)); } if (this.signer) { - return this.signer.signMessage(arrayify(userOpHash)) + return this.signer.signMessage(arrayify(userOpHash)); } - throw new Error('No signer provided to sign userOp') + throw new Error("No signer provided to sign userOp"); } getPreVerificationGas(userOp: Partial): BigNumber { - return calcPreVerificationGas(userOp) + return calcPreVerificationGas(userOp); } async getVerificationGasLimit(initCode: BytesLike): Promise { // Verification gas should be max(initGas(wallet deployment) + validateUserOp + validatePaymasterUserOp , postOp) - const initGas = await this.estimateCreationGas(initCode as string) - const validateUserOpGas = BigNumber.from( - DefaultGasLimits.validatePaymasterUserOpGas + DefaultGasLimits.validateUserOpGas - ) - const postOpGas = BigNumber.from(DefaultGasLimits.postOpGas) + const initGas = await this.estimateCreationGas(initCode as string); + const validateUserOpGas = BigNumber.from(DefaultGasLimits.validatePaymasterUserOpGas + DefaultGasLimits.validateUserOpGas); + const postOpGas = BigNumber.from(DefaultGasLimits.postOpGas); - let verificationGasLimit = BigNumber.from(validateUserOpGas).add(initGas) + let verificationGasLimit = BigNumber.from(validateUserOpGas).add(initGas); if (BigNumber.from(postOpGas).gt(verificationGasLimit)) { - verificationGasLimit = postOpGas + verificationGasLimit = postOpGas; } - return verificationGasLimit + return verificationGasLimit; } async getUserOpHash(userOp: Partial): Promise { - const userOpHash = keccak256(packUserOp(userOp, true)) - const enc = defaultAbiCoder.encode( - ['bytes32', 'address', 'uint256'], - [userOpHash, this.entryPoint.address, this.chainId] - ) - return keccak256(enc) + const userOpHash = keccak256(packUserOp(userOp, true)); + const enc = defaultAbiCoder.encode(["bytes32", "address", "uint256"], [userOpHash, this.entryPoint.address, this.chainId]); + return keccak256(enc); } - abstract getSmartAccountAddress(accountIndex: number): Promise + abstract getSmartAccountAddress(accountIndex: number): Promise; async estimateCreationGas(initCode: string): Promise { - if (initCode == null || initCode === '0x') return BigNumber.from('0') - const deployerAddress = initCode.substring(0, 42) - const deployerCallData = '0x' + initCode.substring(42) - return await this.provider.estimateGas({ to: deployerAddress, data: deployerCallData }) + if (initCode == null || initCode === "0x") return BigNumber.from("0"); + const deployerAddress = initCode.substring(0, 42); + const deployerCallData = "0x" + initCode.substring(42); + return this.provider.estimateGas({ to: deployerAddress, data: deployerCallData }); } async signUserOp(userOp: Partial): Promise { const requiredFields: UserOperationKey[] = [ - 'sender', - 'nonce', - 'initCode', - 'callData', - 'callGasLimit', - 'verificationGasLimit', - 'preVerificationGas', - 'maxFeePerGas', - 'maxPriorityFeePerGas', - 'paymasterAndData' - ] - this.validateUserOp(userOp, requiredFields) - const userOpHash = await this.getUserOpHash(userOp) - let signature = await this.signUserOpHash(userOpHash, this.signer) - const potentiallyIncorrectV = parseInt(signature.slice(-2), 16) + "sender", + "nonce", + "initCode", + "callData", + "callGasLimit", + "verificationGasLimit", + "preVerificationGas", + "maxFeePerGas", + "maxPriorityFeePerGas", + "paymasterAndData", + ]; + this.validateUserOp(userOp, requiredFields); + const userOpHash = await this.getUserOpHash(userOp); + let signature = await this.signUserOpHash(userOpHash, this.signer); + const potentiallyIncorrectV = parseInt(signature.slice(-2), 16); if (![27, 28].includes(potentiallyIncorrectV)) { - const correctV = potentiallyIncorrectV + 27 - signature = signature.slice(0, -2) + correctV.toString(16) + const correctV = potentiallyIncorrectV + 27; + signature = signature.slice(0, -2) + correctV.toString(16); } - if (signature.slice(0, 2) !== '0x') { - signature = '0x' + signature + if (signature.slice(0, 2) !== "0x") { + signature = "0x" + signature; } - userOp.signature = signature - return userOp as UserOperation + userOp.signature = signature; + return userOp as UserOperation; } /** @@ -262,11 +242,11 @@ export abstract class SmartAccount implements ISmartAccount { * @returns Promise */ async sendUserOp(userOp: Partial): Promise { - Logger.log('userOp received in base account ', userOp) - delete userOp.signature - const userOperation = await this.signUserOp(userOp) - const bundlerResponse = await this.sendSignedUserOp(userOperation) - return bundlerResponse + Logger.log("userOp received in base account ", userOp); + delete userOp.signature; + const userOperation = await this.signUserOp(userOp); + const bundlerResponse = await this.sendSignedUserOp(userOperation); + return bundlerResponse; } /** @@ -277,23 +257,23 @@ export abstract class SmartAccount implements ISmartAccount { */ async sendSignedUserOp(userOp: UserOperation): Promise { const requiredFields: UserOperationKey[] = [ - 'sender', - 'nonce', - 'initCode', - 'callData', - 'callGasLimit', - 'verificationGasLimit', - 'preVerificationGas', - 'maxFeePerGas', - 'maxPriorityFeePerGas', - 'paymasterAndData', - 'signature' - ] - this.validateUserOp(userOp, requiredFields) - Logger.log('userOp validated') - if (!this.bundler) throw new Error('Bundler is not provided') - Logger.log('userOp being sent to the bundler', userOp) - const bundlerResponse = await this.bundler.sendUserOp(userOp) - return bundlerResponse + "sender", + "nonce", + "initCode", + "callData", + "callGasLimit", + "verificationGasLimit", + "preVerificationGas", + "maxFeePerGas", + "maxPriorityFeePerGas", + "paymasterAndData", + "signature", + ]; + this.validateUserOp(userOp, requiredFields); + Logger.log("userOp validated"); + if (!this.bundler) throw new Error("Bundler is not provided"); + Logger.log("userOp being sent to the bundler", userOp); + const bundlerResponse = await this.bundler.sendUserOp(userOp); + return bundlerResponse; } } diff --git a/packages/account/src/index.ts b/packages/account/src/index.ts index 717f6733e..656b66e41 100644 --- a/packages/account/src/index.ts +++ b/packages/account/src/index.ts @@ -1,5 +1,5 @@ -export * from './interfaces/ISmartAccount' -export * from './utils/Types' -export * from './SmartAccount' -export * from './BiconomySmartAccount' -export * from './utils/Constants' +export * from "./interfaces/ISmartAccount"; +export * from "./utils/Types"; +export * from "./SmartAccount"; +export * from "./BiconomySmartAccount"; +export * from "./utils/Constants"; diff --git a/packages/account/src/interfaces/IBiconomySmartAccount.ts b/packages/account/src/interfaces/IBiconomySmartAccount.ts index f54d1ba74..7ee5c0c49 100644 --- a/packages/account/src/interfaces/IBiconomySmartAccount.ts +++ b/packages/account/src/interfaces/IBiconomySmartAccount.ts @@ -1,4 +1,4 @@ -import { UserOperation, Transaction } from '@biconomy/core-types' +import { UserOperation, Transaction } from "@biconomy/core-types"; import { SupportedChainsResponse, BalancesResponse, @@ -6,30 +6,24 @@ import { UsdBalanceResponse, SmartAccountByOwnerDto, SmartAccountsResponse, - SCWTransactionResponse -} from '@biconomy/node-client' -import { Overrides, InitilizationData } from '../utils/Types' -import { BigNumberish, BytesLike } from 'ethers' -import { ISmartAccount } from './ISmartAccount' -import { Signer } from 'ethers' + SCWTransactionResponse, +} from "@biconomy/node-client"; +import { Overrides, InitilizationData } from "../utils/Types"; +import { BigNumberish, BytesLike } from "ethers"; +import { ISmartAccount } from "./ISmartAccount"; +import { Signer } from "ethers"; export interface IBiconomySmartAccount extends ISmartAccount { - init(initilizationData?: InitilizationData): Promise - initializeAccountAtIndex(accountIndex: number): void - getExecuteCallData(to: string, value: BigNumberish, data: BytesLike): string - getExecuteBatchCallData( - to: Array, - value: Array, - data: Array - ): string - buildUserOp(transactions: Transaction[], overrides?: Overrides): Promise> - getAllTokenBalances(balancesDto: BalancesDto): Promise - getTotalBalanceInUsd(balancesDto: BalancesDto): Promise - getSmartAccountsByOwner( - smartAccountByOwnerDto: SmartAccountByOwnerDto - ): Promise - getTransactionsByAddress(chainId: number, address: string): Promise - getTransactionByHash(txHash: string): Promise - getAllSupportedChains(): Promise - attachSigner(signer: Signer): Promise + init(initilizationData?: InitilizationData): Promise; + initializeAccountAtIndex(accountIndex: number): void; + getExecuteCallData(to: string, value: BigNumberish, data: BytesLike): string; + getExecuteBatchCallData(to: Array, value: Array, data: Array): string; + buildUserOp(transactions: Transaction[], overrides?: Overrides): Promise>; + getAllTokenBalances(balancesDto: BalancesDto): Promise; + getTotalBalanceInUsd(balancesDto: BalancesDto): Promise; + getSmartAccountsByOwner(smartAccountByOwnerDto: SmartAccountByOwnerDto): Promise; + getTransactionsByAddress(chainId: number, address: string): Promise; + getTransactionByHash(txHash: string): Promise; + getAllSupportedChains(): Promise; + attachSigner(signer: Signer): Promise; } diff --git a/packages/account/src/interfaces/ISmartAccount.ts b/packages/account/src/interfaces/ISmartAccount.ts index e1687c2b4..8419cebc5 100644 --- a/packages/account/src/interfaces/ISmartAccount.ts +++ b/packages/account/src/interfaces/ISmartAccount.ts @@ -1,8 +1,8 @@ -import { UserOperation } from '@biconomy/core-types' -import { UserOpResponse } from '@biconomy/bundler' +import { UserOperation } from "@biconomy/core-types"; +import { UserOpResponse } from "@biconomy/bundler"; export interface ISmartAccount { - getSmartAccountAddress(accountIndex: number): Promise - signUserOp(userOperation: UserOperation): Promise - sendUserOp(userOperation: UserOperation): Promise - sendSignedUserOp(userOperation: UserOperation): Promise + getSmartAccountAddress(accountIndex: number): Promise; + signUserOp(userOperation: UserOperation): Promise; + sendUserOp(userOperation: UserOperation): Promise; + sendSignedUserOp(userOperation: UserOperation): Promise; } diff --git a/packages/account/src/utils/Constants.ts b/packages/account/src/utils/Constants.ts index 649f22670..faea0f8fd 100644 --- a/packages/account/src/utils/Constants.ts +++ b/packages/account/src/utils/Constants.ts @@ -1,24 +1,24 @@ -import { ChainId } from '@biconomy/core-types' -import { EntrypointAddresses, BiconomyFactories, BiconomyImplementation } from './Types' +import { ChainId } from "@biconomy/core-types"; +import { EntrypointAddresses, BiconomyFactories, BiconomyImplementation } from "./Types"; // will always be latest entrypoint address -export const DEFAULT_ENTRYPOINT_ADDRESS = '0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789' +export const DEFAULT_ENTRYPOINT_ADDRESS = "0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789"; export const ENTRYPOINT_ADDRESSES: EntrypointAddresses = { - '0x27a4db290b89ae3373ce4313cbeae72112ae7da9': 'V0_0_5', - '0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789': 'V0_0_6' -} + "0x27a4db290b89ae3373ce4313cbeae72112ae7da9": "V0_0_5", + "0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789": "V0_0_6", +}; // will always be latest factory address -export const DEFAULT_BICONOMY_FACTORY_ADDRESS = '0x000000f9ee1842bb72f6bbdd75e6d3d4e3e9594c' +export const DEFAULT_BICONOMY_FACTORY_ADDRESS = "0x000000f9ee1842bb72f6bbdd75e6d3d4e3e9594c"; export const BICONOMY_FACTORY_ADDRESSES: BiconomyFactories = { - '0x000000f9ee1842bb72f6bbdd75e6d3d4e3e9594c': 'V1_0_0' -} + "0x000000f9ee1842bb72f6bbdd75e6d3d4e3e9594c": "V1_0_0", +}; export const BICONOMY_IMPLEMENTATION_ADDRESSES: BiconomyImplementation = { - '0x00006b7e42e01957da540dc6a8f7c30c4d816af5': 'V1_0_0' -} + "0x00006b7e42e01957da540dc6a8f7c30c4d816af5": "V1_0_0", +}; // will always be latest implementation address -export const DEFAULT_BICONOMY_IMPLEMENTATION_ADDRESS = '0x00006b7e42e01957da540dc6a8f7c30c4d816af5' +export const DEFAULT_BICONOMY_IMPLEMENTATION_ADDRESS = "0x00006b7e42e01957da540dc6a8f7c30c4d816af5"; -export const EIP1559_UNSUPPORTED_NETWORKS: Array = [97, 56, 1442, 1101] +export const EIP1559_UNSUPPORTED_NETWORKS: Array = [97, 56, 1442, 1101]; diff --git a/packages/account/src/utils/Preverificaiton.ts b/packages/account/src/utils/Preverificaiton.ts index 94b0575e3..9c8cd3618 100644 --- a/packages/account/src/utils/Preverificaiton.ts +++ b/packages/account/src/utils/Preverificaiton.ts @@ -1,44 +1,44 @@ -import { UserOperation } from '@biconomy/core-types' -import { NotPromise, packUserOp } from '@biconomy/common' // '@account-abstraction/utils' -import { arrayify, hexlify } from 'ethers/lib/utils' -import { BigNumber } from 'ethers' +import { UserOperation } from "@biconomy/core-types"; +import { NotPromise, packUserOp } from "@biconomy/common"; // '@account-abstraction/utils' +import { arrayify, hexlify } from "ethers/lib/utils"; +import { BigNumber } from "ethers"; export interface GasOverheads { /** * fixed overhead for entire handleOp bundle. */ - fixed: number + fixed: number; /** * per userOp overhead, added on top of the above fixed per-bundle. */ - perUserOp: number + perUserOp: number; /** * overhead for userOp word (32 bytes) block */ - perUserOpWord: number + perUserOpWord: number; // perCallDataWord: number /** * zero byte cost, for calldata gas cost calculations */ - zeroByte: number + zeroByte: number; /** * non-zero byte cost, for calldata gas cost calculations */ - nonZeroByte: number + nonZeroByte: number; /** * expected bundle size, to split per-bundle overhead between all ops. */ - bundleSize: number + bundleSize: number; /** * expected length of the userOp signature. */ - sigSize: number + sigSize: number; } export interface VerificationGasLimits { @@ -47,21 +47,21 @@ export interface VerificationGasLimits { * called from entrypoint to the account * should consider max execution */ - validateUserOpGas: number + validateUserOpGas: number; /** * per userOp gasLimit for validatePaymasterUserOp() * called from entrypoint to the paymaster * should consider max execution */ - validatePaymasterUserOpGas: number + validatePaymasterUserOpGas: number; /** * per userOp gasLimit for postOp() * called from entrypoint to the paymaster * should consider max execution for paymaster/s this account may use */ - postOpGas: number + postOpGas: number; } export const DefaultGasOverheads: GasOverheads = { @@ -71,14 +71,14 @@ export const DefaultGasOverheads: GasOverheads = { zeroByte: 4, nonZeroByte: 16, bundleSize: 1, - sigSize: 65 -} + sigSize: 65, +}; export const DefaultGasLimits: VerificationGasLimits = { validateUserOpGas: 100000, validatePaymasterUserOpGas: 100000, - postOpGas: 10877 -} + postOpGas: 10877, +}; /** * calculate the preVerificationGas of the given UserOperation @@ -87,22 +87,19 @@ export const DefaultGasLimits: VerificationGasLimits = { * @param userOp filled userOp to calculate. The only possible missing fields can be the signature and preVerificationGas itself * @param overheads gas overheads to use, to override the default values */ -export function calcPreVerificationGas( - userOp: Partial>, - overheads?: Partial -): BigNumber { - const ov = { ...DefaultGasOverheads, ...(overheads ?? {}) } +export function calcPreVerificationGas(userOp: Partial>, overheads?: Partial): BigNumber { + const ov = { ...DefaultGasOverheads, ...(overheads ?? {}) }; /* eslint-disable @typescript-eslint/no-explicit-any */ const p: NotPromise = { // dummy values, in case the UserOp is incomplete. - paymasterAndData: '0x', + paymasterAndData: "0x", preVerificationGas: BigNumber.from(21000), // dummy value, just for calldata cost signature: hexlify(Buffer.alloc(ov.sigSize, 1)), // dummy signature - ...userOp - } as any + ...userOp, + } as any; - const packed = arrayify(packUserOp(p, false)) - const lengthInWord = (packed.length + 31) / 32 + const packed = arrayify(packUserOp(p, false)); + const lengthInWord = (packed.length + 31) / 32; /** * general explanation * 21000 base gas @@ -111,11 +108,7 @@ export function calcPreVerificationGas( * plus any gas overhead that can't be tracked on-chain * (if bundler needs to charge the premium one way is to increase this value for ops to sign) */ - const callDataCost = packed - .map((x) => (x === 0 ? ov.zeroByte : ov.nonZeroByte)) - .reduce((sum, x) => sum + x) - const ret = Math.round( - callDataCost + ov.fixed / ov.bundleSize + ov.perUserOp + ov.perUserOpWord * lengthInWord - ) - return BigNumber.from(ret) + const callDataCost = packed.map((x) => (x === 0 ? ov.zeroByte : ov.nonZeroByte)).reduce((sum, x) => sum + x); + const ret = Math.round(callDataCost + ov.fixed / ov.bundleSize + ov.perUserOp + ov.perUserOpWord * lengthInWord); + return BigNumber.from(ret); } diff --git a/packages/account/src/utils/Types.ts b/packages/account/src/utils/Types.ts index 14609d68a..1ddab6f85 100644 --- a/packages/account/src/utils/Types.ts +++ b/packages/account/src/utils/Types.ts @@ -1,53 +1,53 @@ -import { Signer } from 'ethers' -import { ChainId } from '@biconomy/core-types' -import { BigNumberish } from 'ethers' -import { IBundler } from '@biconomy/bundler' -import { IPaymaster, PaymasterFeeQuote } from '@biconomy/paymaster' +import { Signer } from "ethers"; +import { ChainId } from "@biconomy/core-types"; +import { BigNumberish } from "ethers"; +import { IBundler } from "@biconomy/bundler"; +import { IPaymaster, PaymasterFeeQuote } from "@biconomy/paymaster"; export type EntrypointAddresses = { - [address: string]: string -} + [address: string]: string; +}; export type BiconomyFactories = { - [address: string]: string -} + [address: string]: string; +}; export type BiconomyImplementation = { - [address: string]: string -} + [address: string]: string; +}; export type SmartAccountConfig = { - entryPointAddress: string - bundler?: IBundler -} + entryPointAddress: string; + bundler?: IBundler; +}; export type BiconomyTokenPaymasterRequest = { - feeQuote: PaymasterFeeQuote - spender: string - maxApproval?: boolean -} + feeQuote: PaymasterFeeQuote; + spender: string; + maxApproval?: boolean; +}; export type BiconomySmartAccountConfig = { - signer: Signer - rpcUrl?: string - chainId: ChainId - entryPointAddress?: string - bundler?: IBundler - paymaster?: IPaymaster - nodeClientUrl?: string -} + signer: Signer; + rpcUrl?: string; + chainId: ChainId; + entryPointAddress?: string; + bundler?: IBundler; + paymaster?: IPaymaster; + nodeClientUrl?: string; +}; export type Overrides = { - callGasLimit?: BigNumberish - verificationGasLimit?: BigNumberish - preVerificationGas?: BigNumberish - maxFeePerGas?: BigNumberish - maxPriorityFeePerGas?: BigNumberish - paymasterData?: string - signature?: string -} + callGasLimit?: BigNumberish; + verificationGasLimit?: BigNumberish; + preVerificationGas?: BigNumberish; + maxFeePerGas?: BigNumberish; + maxPriorityFeePerGas?: BigNumberish; + paymasterData?: string; + signature?: string; +}; export type InitilizationData = { - accountIndex?: number - signerAddress?: string -} + accountIndex?: number; + signerAddress?: string; +}; diff --git a/packages/account/tests/account.spec.ts b/packages/account/tests/account.spec.ts index e51e8332d..d86ce1ff7 100644 --- a/packages/account/tests/account.spec.ts +++ b/packages/account/tests/account.spec.ts @@ -1,6 +1,5 @@ -describe('Account Tests', () => { - it('should have a basic test', () => { - expect(true).toBe(true); - }); +describe("Account Tests", () => { + it("should have a basic test", () => { + expect(true).toBe(true); }); - \ No newline at end of file +}); diff --git a/packages/account/tsconfig.json b/packages/account/tsconfig.json index a31c33fe3..3dc5293ed 100644 --- a/packages/account/tsconfig.json +++ b/packages/account/tsconfig.json @@ -5,7 +5,7 @@ "outDir": "dist", "baseUrl": "src", "resolveJsonModule": true, - "esModuleInterop": true, + "esModuleInterop": true }, "include": ["src", "src/**/*.json"] } diff --git a/packages/bundler/CHANGELOG.md b/packages/bundler/CHANGELOG.md index 5b9211860..2278f7e1c 100644 --- a/packages/bundler/CHANGELOG.md +++ b/packages/bundler/CHANGELOG.md @@ -9,33 +9,20 @@ Modular SDK - consists stable version of below updates done in Alphas. ### Features -* base mainnet integration ([c17f5d6](https://github.com/bcnmy/biconomy-client-sdk/commit/c17f5d6c2fe34b106e6d9755f54fab2493db6fbe)) - - - - +- base mainnet integration ([c17f5d6](https://github.com/bcnmy/biconomy-client-sdk/commit/c17f5d6c2fe34b106e6d9755f54fab2493db6fbe)) ## 3.0.0-alpha.0 (2023-08-02) VERSION bump only - - - # 3.1.0-alpha.0 (2023-07-24) - ### Features -* chain integration ([738556e](https://github.com/bcnmy/biconomy-client-sdk/commit/738556efcfda70fedc652befc0b35f8835c5e360)) - - - - +- chain integration ([738556e](https://github.com/bcnmy/biconomy-client-sdk/commit/738556efcfda70fedc652befc0b35f8835c5e360)) ## 3.0.0-alpha.0 (2023-07-12) - ### Bug Fixes -* linting ([563befe](https://github.com/bcnmy/biconomy-client-sdk/commit/563befedcc37aee4c531e01809b47e559a33f526)) +- linting ([563befe](https://github.com/bcnmy/biconomy-client-sdk/commit/563befedcc37aee4c531e01809b47e559a33f526)) diff --git a/packages/bundler/Readme.md b/packages/bundler/Readme.md index d550aa1e2..ef4ad69be 100644 --- a/packages/bundler/Readme.md +++ b/packages/bundler/Readme.md @@ -1,6 +1,6 @@ ### Bundler -In the context of (ERC4337), A bundler plays a main role in the infrastructure. This concept is integral to the operation of account abstraction across any network that utilizes the Ethereum Virtual Machine (EVM). +In the context of (ERC4337), A bundler plays a main role in the infrastructure. This concept is integral to the operation of account abstraction across any network that utilizes the Ethereum Virtual Machine (EVM). ## Installation @@ -19,35 +19,35 @@ yarn add @biconomy/bundler ``` ## configuration -| Key | Description | -| -------------------| ------------- | -| bundlerUrl | Represent ERC4337 spec implemented bundler url. you can get one from biconomy dashboard. Alternatively you can supply any of your preferred| -| chainId | This represents the network your smart wallet transactions will be conducted on. Take a look following Link for supported chain id's | -| entryPointAddress | Since entrypoint can have different addresses you can call getSupportedEntryPoints() on bundler instance for supported addresses list| + +| Key | Description | +| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| bundlerUrl | Represent ERC4337 spec implemented bundler url. you can get one from biconomy dashboard. Alternatively you can supply any of your preferred | +| chainId | This represents the network your smart wallet transactions will be conducted on. Take a look following Link for supported chain id's | +| entryPointAddress | Since entrypoint can have different addresses you can call getSupportedEntryPoints() on bundler instance for supported addresses list | ```typescript // This is how you create bundler instance in your dapp's -import { IBundler, Bundler } from '@biconomy/bundler' +import { IBundler, Bundler } from "@biconomy/bundler"; // Make use of core-types package import { ChainId } from "@biconomy/core-types"; const bundler: IBundler = new Bundler({ - bundlerUrl: '', - chainId: ChainId.POLYGON_MAINNET, - entryPointAddress: '', - }) + bundlerUrl: "", + chainId: ChainId.POLYGON_MAINNET, + entryPointAddress: "", +}); ``` + Following are the methods that can be call on bundler instance ```typescript export interface IBundler { - estimateUserOpGas( - userOp: Partial - ): Promise - sendUserOp(userOp: UserOperation): Promise - getUserOpReceipt(userOpHash: string): Promise - getUserOpByHash(userOpHash: string): Promise + estimateUserOpGas(userOp: Partial): Promise; + sendUserOp(userOp: UserOperation): Promise; + getUserOpReceipt(userOpHash: string): Promise; + getUserOpByHash(userOpHash: string): Promise; } ``` @@ -59,7 +59,7 @@ Estimate the gas values for a UserOperation. Given UserOperation optionally with **preVerificationGas** gas overhead of this UserOperation **verificationGasLimit** actual gas used by the validation of this UserOperation **callGasLimit** limit used to execute userop.callData called from EntryPoint to the Smart Account - + -------------------------------- **sendUserOp** @@ -72,14 +72,13 @@ If the UserOperation is valid, the client MUST return the calculated userOpHash -------------------------------- - **getUserOpByHash** Return a UserOperation based on a hash (userOpHash) returned by sendUserOp (eth_sendUserOperation) **Return Values** null in case the UserOperation is not yet included in a block, or a full UserOperation, with the addition of entryPoint, blockNumber, blockHash and transactionHash - + -------------------------------- **getUserOpReceipt** @@ -100,10 +99,5 @@ null in case the UserOperation is not yet included in a block, or: **reason** in case of revert, this is the revert reason **logs** the logs generated by this UserOperation (not including logs of other UserOperations in the same bundle) **receipt** the TransactionReceipt object. Note that the returned TransactionReceipt is for the entire bundle, not only for this UserOperation. - - -------------------------------- - - - - + -------------------------------- diff --git a/packages/bundler/package.json b/packages/bundler/package.json index cd88e8b85..98072dfef 100644 --- a/packages/bundler/package.json +++ b/packages/bundler/package.json @@ -22,7 +22,7 @@ "start:ganache": "ganache -m 'direct buyer cliff train rice spirit census refuse glare expire innocent quote'", "format": "prettier --write \"{src,tests}/**/*.ts\"", "lint": "tslint -p tsconfig.json" - }, + }, "author": "talhamalik883 ", "repository": { "type": "git", diff --git a/packages/bundler/src/Bundler.ts b/packages/bundler/src/Bundler.ts index 539fc70bf..ea5a96952 100644 --- a/packages/bundler/src/Bundler.ts +++ b/packages/bundler/src/Bundler.ts @@ -1,5 +1,5 @@ -import { IBundler } from './interfaces/IBundler' -import { UserOperation, ChainId } from '@biconomy/core-types' +import { IBundler } from "./interfaces/IBundler"; +import { UserOperation, ChainId } from "@biconomy/core-types"; import { GetUserOperationResponse, GetUserOpByHashResponse, @@ -9,20 +9,13 @@ import { UserOpReceipt, SendUserOpResponse, UserOpGasResponse, - UserOpByHashResponse -} from './utils/Types' -import { resolveProperties } from 'ethers/lib/utils' -import { - deepHexlify, - sendRequest, - getTimestampInSeconds, - HttpMethod, - Logger, - RPC_PROVIDER_URLS -} from '@biconomy/common' -import { transformUserOP } from './utils/HelperFunction' -import { UserOpReceiptIntervals } from './utils/Constants' -import { JsonRpcProvider } from '@ethersproject/providers' + UserOpByHashResponse, +} from "./utils/Types"; +import { resolveProperties } from "ethers/lib/utils"; +import { deepHexlify, sendRequest, getTimestampInSeconds, HttpMethod, Logger, RPC_PROVIDER_URLS } from "@biconomy/common"; +import { transformUserOP } from "./utils/HelperFunction"; +import { UserOpReceiptIntervals } from "./utils/Constants"; +import { JsonRpcProvider } from "@ethersproject/providers"; /** * This class implements IBundler interface. @@ -30,16 +23,17 @@ import { JsonRpcProvider } from '@ethersproject/providers' * Checkout the proposal for more details on Bundlers. */ export class Bundler implements IBundler { - UserOpReceiptIntervals: { [key in ChainId]?: number } + UserOpReceiptIntervals: { [key in ChainId]?: number }; + constructor(readonly bundlerConfig: Bundlerconfig) { this.UserOpReceiptIntervals = { ...UserOpReceiptIntervals, - ...bundlerConfig.userOpReceiptIntervals - } + ...bundlerConfig.userOpReceiptIntervals, + }; } private getBundlerUrl(): string { - return `${this.bundlerConfig.bundlerUrl}` + return `${this.bundlerConfig.bundlerUrl}`; } /** @@ -51,31 +45,32 @@ export class Bundler implements IBundler { async estimateUserOpGas(userOp: UserOperation): Promise { // expected dummySig and possibly dummmy paymasterAndData should be provided by the caller // bundler doesn't know account and paymaster implementation - userOp = transformUserOP(userOp) - Logger.log('userOp sending for fee estimate ', userOp) + userOp = transformUserOP(userOp); + Logger.log("userOp sending for fee estimate ", userOp); - const bundlerUrl = this.getBundlerUrl() + const bundlerUrl = this.getBundlerUrl(); const response: EstimateUserOpGasResponse = await sendRequest({ url: bundlerUrl, method: HttpMethod.Post, body: { - method: 'eth_estimateUserOperationGas', + method: "eth_estimateUserOperationGas", params: [userOp, this.bundlerConfig.entryPointAddress], id: getTimestampInSeconds(), - jsonrpc: '2.0' - } - }) + jsonrpc: "2.0", + }, + }); - const userOpGasResponse = response.result + const userOpGasResponse = response.result; for (const key in userOpGasResponse) { - if (key === 'maxFeePerGas' || key === 'maxPriorityFeePerGas') continue + if (key === "maxFeePerGas" || key === "maxPriorityFeePerGas") continue; if (!userOpGasResponse[key as keyof UserOpGasResponse]) { - throw new Error(`Got undefined ${key} from bundler`) + throw new Error(`Got undefined ${key} from bundler`); } } - return userOpGasResponse + return userOpGasResponse; } + /** * * @param userOp @@ -83,51 +78,51 @@ export class Bundler implements IBundler { * @returns Promise */ async sendUserOp(userOp: UserOperation): Promise { - const chainId = this.bundlerConfig.chainId + const chainId = this.bundlerConfig.chainId; // transformUserOP will convert all bigNumber values to string - userOp = transformUserOP(userOp) - const hexifiedUserOp = deepHexlify(await resolveProperties(userOp)) - const params = [hexifiedUserOp, this.bundlerConfig.entryPointAddress] - const bundlerUrl = this.getBundlerUrl() + userOp = transformUserOP(userOp); + const hexifiedUserOp = deepHexlify(await resolveProperties(userOp)); + const params = [hexifiedUserOp, this.bundlerConfig.entryPointAddress]; + const bundlerUrl = this.getBundlerUrl(); const sendUserOperationResponse: SendUserOpResponse = await sendRequest({ url: bundlerUrl, method: HttpMethod.Post, body: { - method: 'eth_sendUserOperation', + method: "eth_sendUserOperation", params: params, id: getTimestampInSeconds(), - jsonrpc: '2.0' - } - }) + jsonrpc: "2.0", + }, + }); const response: UserOpResponse = { userOpHash: sendUserOperationResponse.result, wait: (confirmations?: number): Promise => { - const provider = new JsonRpcProvider(RPC_PROVIDER_URLS[chainId]) + const provider = new JsonRpcProvider(RPC_PROVIDER_URLS[chainId]); return new Promise(async (resolve, reject) => { const intervalId = setInterval(async () => { try { - const userOpResponse = await this.getUserOpReceipt(sendUserOperationResponse.result) + const userOpResponse = await this.getUserOpReceipt(sendUserOperationResponse.result); if (userOpResponse && userOpResponse.receipt && userOpResponse.receipt.blockNumber) { if (confirmations) { - const latestBlock = await provider.getBlockNumber() - const confirmedBlocks = latestBlock - userOpResponse.receipt.blockNumber + const latestBlock = await provider.getBlockNumber(); + const confirmedBlocks = latestBlock - userOpResponse.receipt.blockNumber; if (confirmations >= confirmedBlocks) { - clearInterval(intervalId) - resolve(userOpResponse) + clearInterval(intervalId); + resolve(userOpResponse); } } - clearInterval(intervalId) - resolve(userOpResponse) + clearInterval(intervalId); + resolve(userOpResponse); } } catch (error) { - clearInterval(intervalId) - reject(error) + clearInterval(intervalId); + reject(error); } - }, this.UserOpReceiptIntervals[chainId]) - }) - } - } - return response + }, this.UserOpReceiptIntervals[chainId]); + }); + }, + }; + return response; } /** @@ -137,20 +132,21 @@ export class Bundler implements IBundler { * @returns Promise */ async getUserOpReceipt(userOpHash: string): Promise { - const bundlerUrl = this.getBundlerUrl() + const bundlerUrl = this.getBundlerUrl(); const response: GetUserOperationResponse = await sendRequest({ url: bundlerUrl, method: HttpMethod.Post, body: { - method: 'eth_getUserOperationReceipt', + method: "eth_getUserOperationReceipt", params: [userOpHash], id: getTimestampInSeconds(), - jsonrpc: '2.0' - } - }) - const userOpReceipt: UserOpReceipt = response.result - return userOpReceipt + jsonrpc: "2.0", + }, + }); + const userOpReceipt: UserOpReceipt = response.result; + return userOpReceipt; } + /** * * @param userOpHash @@ -159,18 +155,18 @@ export class Bundler implements IBundler { * @returns Promise */ async getUserOpByHash(userOpHash: string): Promise { - const bundlerUrl = this.getBundlerUrl() + const bundlerUrl = this.getBundlerUrl(); const response: GetUserOpByHashResponse = await sendRequest({ url: bundlerUrl, method: HttpMethod.Post, body: { - method: 'eth_getUserOperationByHash', + method: "eth_getUserOperationByHash", params: [userOpHash], id: getTimestampInSeconds(), - jsonrpc: '2.0' - } - }) - const userOpByHashResponse: UserOpByHashResponse = response.result - return userOpByHashResponse + jsonrpc: "2.0", + }, + }); + const userOpByHashResponse: UserOpByHashResponse = response.result; + return userOpByHashResponse; } } diff --git a/packages/bundler/src/index.ts b/packages/bundler/src/index.ts index 1b7123a95..2cb31e82e 100644 --- a/packages/bundler/src/index.ts +++ b/packages/bundler/src/index.ts @@ -1,3 +1,3 @@ -export * from './interfaces/IBundler' -export * from './Bundler' -export * from './utils/Types' +export * from "./interfaces/IBundler"; +export * from "./Bundler"; +export * from "./utils/Types"; diff --git a/packages/bundler/src/interfaces/IBundler.ts b/packages/bundler/src/interfaces/IBundler.ts index 8ae72622c..5178f4113 100644 --- a/packages/bundler/src/interfaces/IBundler.ts +++ b/packages/bundler/src/interfaces/IBundler.ts @@ -1,14 +1,9 @@ -import { - UserOpResponse, - UserOpGasResponse, - UserOpReceipt, - UserOpByHashResponse -} from '../utils/Types' -import { UserOperation } from '@biconomy/core-types' +import { UserOpResponse, UserOpGasResponse, UserOpReceipt, UserOpByHashResponse } from "../utils/Types"; +import { UserOperation } from "@biconomy/core-types"; export interface IBundler { - estimateUserOpGas(userOp: Partial): Promise - sendUserOp(userOp: UserOperation): Promise - getUserOpReceipt(userOpHash: string): Promise - getUserOpByHash(userOpHash: string): Promise + estimateUserOpGas(userOp: Partial): Promise; + sendUserOp(userOp: UserOperation): Promise; + getUserOpReceipt(userOpHash: string): Promise; + getUserOpByHash(userOpHash: string): Promise; } diff --git a/packages/bundler/src/utils/Constants.ts b/packages/bundler/src/utils/Constants.ts index 49adce848..5f4c74c7a 100644 --- a/packages/bundler/src/utils/Constants.ts +++ b/packages/bundler/src/utils/Constants.ts @@ -1,4 +1,4 @@ -import { ChainId } from '@biconomy/core-types' +import { ChainId } from "@biconomy/core-types"; export const UserOpReceiptIntervals: { [key in ChainId]?: number } = { [ChainId.MAINNET]: 10000, @@ -19,5 +19,5 @@ export const UserOpReceiptIntervals: { [key in ChainId]?: number } = { [ChainId.MOONBEAM_MAINNET]: 5000, [ChainId.BASE_GOERLI_TESTNET]: 5000, [ChainId.BASE_MAINNET]: 5000, - [ChainId.LINEA_TESTNET]: 5000 -} + [ChainId.LINEA_TESTNET]: 5000, +}; diff --git a/packages/bundler/src/utils/HelperFunction.ts b/packages/bundler/src/utils/HelperFunction.ts index 574b1273d..bd76158ed 100644 --- a/packages/bundler/src/utils/HelperFunction.ts +++ b/packages/bundler/src/utils/HelperFunction.ts @@ -1,25 +1,25 @@ -import { UserOperation } from '@biconomy/core-types' -import { BigNumber } from 'ethers' +import { UserOperation } from "@biconomy/core-types"; +import { BigNumber } from "ethers"; export const transformUserOP = (userOp: UserOperation): UserOperation => { try { - const userOperation = { ...userOp } + const userOperation = { ...userOp }; const keys: (keyof UserOperation)[] = [ - 'nonce', - 'callGasLimit', - 'verificationGasLimit', - 'preVerificationGas', - 'maxFeePerGas', - 'maxPriorityFeePerGas' - ] + "nonce", + "callGasLimit", + "verificationGasLimit", + "preVerificationGas", + "maxFeePerGas", + "maxPriorityFeePerGas", + ]; for (const key of keys) { - if (userOperation[key] && userOperation[key] !== '0') { - userOperation[key] = BigNumber.from(userOp[key]).toHexString() + if (userOperation[key] && userOperation[key] !== "0") { + userOperation[key] = BigNumber.from(userOp[key]).toHexString(); } } - return userOperation + return userOperation; } catch (error) { - console.error(`Failed to transform user operation: ${error}`) - throw error + console.error(`Failed to transform user operation: ${error}`); + throw error; } -} +}; diff --git a/packages/bundler/src/utils/Types.ts b/packages/bundler/src/utils/Types.ts index b18588526..329c16838 100644 --- a/packages/bundler/src/utils/Types.ts +++ b/packages/bundler/src/utils/Types.ts @@ -1,82 +1,82 @@ -import { ethers, BigNumber } from 'ethers' -import { ChainId, UserOperation } from '@biconomy/core-types' +import { ethers, BigNumber } from "ethers"; +import { ChainId, UserOperation } from "@biconomy/core-types"; export type Bundlerconfig = { - bundlerUrl: string - entryPointAddress?: string - chainId: ChainId - userOpReceiptIntervals?: { [key in ChainId]?: number } -} + bundlerUrl: string; + entryPointAddress?: string; + chainId: ChainId; + userOpReceiptIntervals?: { [key in ChainId]?: number }; +}; export type UserOpReceipt = { - userOpHash: string - entryPoint: string - sender: string - nonce: number - paymaster: string - actualGasCost: BigNumber - actualGasUsed: BigNumber - success: boolean - reason: string - logs: Array // The logs generated by this UserOperation (not including logs of other UserOperations in the same bundle) - receipt: ethers.providers.TransactionReceipt -} + userOpHash: string; + entryPoint: string; + sender: string; + nonce: number; + paymaster: string; + actualGasCost: BigNumber; + actualGasUsed: BigNumber; + success: boolean; + reason: string; + logs: Array; // The logs generated by this UserOperation (not including logs of other UserOperations in the same bundle) + receipt: ethers.providers.TransactionReceipt; +}; // Converted to JsonRpcResponse with strict type export type GetUserOperationResponse = { - jsonrpc: string - id: number - result: UserOpReceipt - error?: JsonRpcError -} + jsonrpc: string; + id: number; + result: UserOpReceipt; + error?: JsonRpcError; +}; // Converted to JsonRpcResponse with strict type export type SendUserOpResponse = { - jsonrpc: string - id: number - result: string - error?: JsonRpcError -} + jsonrpc: string; + id: number; + result: string; + error?: JsonRpcError; +}; export type UserOpResponse = { - userOpHash: string - wait(confirmations?: number): Promise -} + userOpHash: string; + wait(confirmations?: number): Promise; +}; // Converted to JsonRpcResponse with strict type export type EstimateUserOpGasResponse = { - jsonrpc: string - id: number - result: UserOpGasResponse - error?: JsonRpcError -} + jsonrpc: string; + id: number; + result: UserOpGasResponse; + error?: JsonRpcError; +}; export type UserOpGasResponse = { - preVerificationGas: string - verificationGasLimit: string - callGasLimit: string - maxPriorityFeePerGas: string - maxFeePerGas: string -} + preVerificationGas: string; + verificationGasLimit: string; + callGasLimit: string; + maxPriorityFeePerGas: string; + maxFeePerGas: string; +}; // Converted to JsonRpcResponse with strict type export type GetUserOpByHashResponse = { - jsonrpc: string - id: number - result: UserOpByHashResponse - error?: JsonRpcError -} + jsonrpc: string; + id: number; + result: UserOpByHashResponse; + error?: JsonRpcError; +}; // TODO: need to verify this type from infinitism bundler, stackup export type UserOpByHashResponse = UserOperation & { - transactionHash: string - blockNumber: number - blockHash: string - entryPoint: string -} + transactionHash: string; + blockNumber: number; + blockHash: string; + entryPoint: string; +}; /* eslint-disable @typescript-eslint/no-explicit-any */ export type JsonRpcError = { - code: string - message: string - data: any -} + code: string; + message: string; + data: any; +}; diff --git a/packages/bundler/tests/bundler.spec.ts b/packages/bundler/tests/bundler.spec.ts index 754026ccf..3c8a14354 100644 --- a/packages/bundler/tests/bundler.spec.ts +++ b/packages/bundler/tests/bundler.spec.ts @@ -1,6 +1,5 @@ -describe('Bundler Tests', () => { - it('should have a basic test', () => { - expect(true).toBe(true); - }); +describe("Bundler Tests", () => { + it("should have a basic test", () => { + expect(true).toBe(true); }); - \ No newline at end of file +}); diff --git a/packages/bundler/tsconfig.json b/packages/bundler/tsconfig.json index a31c33fe3..3dc5293ed 100644 --- a/packages/bundler/tsconfig.json +++ b/packages/bundler/tsconfig.json @@ -5,7 +5,7 @@ "outDir": "dist", "baseUrl": "src", "resolveJsonModule": true, - "esModuleInterop": true, + "esModuleInterop": true }, "include": ["src", "src/**/*.json"] } diff --git a/packages/common/CHANGELOG.md b/packages/common/CHANGELOG.md index 898d94ef4..9fc9269ab 100644 --- a/packages/common/CHANGELOG.md +++ b/packages/common/CHANGELOG.md @@ -5,75 +5,53 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline ## 3.0.0 (2023-08-28) - ### Features -* base mainnet integration ([c17f5d6](https://github.com/bcnmy/biconomy-client-sdk/commit/c17f5d6c2fe34b106e6d9755f54fab2493db6fbe)) - +- base mainnet integration ([c17f5d6](https://github.com/bcnmy/biconomy-client-sdk/commit/c17f5d6c2fe34b106e6d9755f54fab2493db6fbe)) ## 3.0.0-alpha.0 (2023-08-02) ### Features -* Add logger for jsonRpc request([0c40641])(https://github.com/bcnmy/biconomy-client-sdk/commit/39a92fde78033e8dd850596a8a2ae7fc7bda0040) - - - +- Add logger for jsonRpc request([0c40641])(https://github.com/bcnmy/biconomy-client-sdk/commit/39a92fde78033e8dd850596a8a2ae7fc7bda0040) # 3.1.0-alpha.0 (2023-07-24) ### Features -* chain integration ([738556e](https://github.com/bcnmy/biconomy-client-sdk/commit/738556efcfda70fedc652befc0b35f8835c5e360)) - - +- chain integration ([738556e](https://github.com/bcnmy/biconomy-client-sdk/commit/738556efcfda70fedc652befc0b35f8835c5e360)) ## 3.0.0-alpha.0 (2023-07-12) - ### Bug Fixes -* comment out hardcoded gas limit in any case + fix value for estimate smart-account deployment + dev notes ([df48ec3](https://github.com/bcnmy/biconomy-client-sdk/commit/df48ec3c04cf44a8f64eb302217655076c6304a4)) -* linting ([563befe](https://github.com/bcnmy/biconomy-client-sdk/commit/563befedcc37aee4c531e01809b47e559a33f526)) -* linting ([d2f5f1a](https://github.com/bcnmy/biconomy-client-sdk/commit/d2f5f1afadc2a561c4ef01c0821a25b9d7fe776e)) - - +- comment out hardcoded gas limit in any case + fix value for estimate smart-account deployment + dev notes ([df48ec3](https://github.com/bcnmy/biconomy-client-sdk/commit/df48ec3c04cf44a8f64eb302217655076c6304a4)) +- linting ([563befe](https://github.com/bcnmy/biconomy-client-sdk/commit/563befedcc37aee4c531e01809b47e559a33f526)) +- linting ([d2f5f1a](https://github.com/bcnmy/biconomy-client-sdk/commit/d2f5f1afadc2a561c4ef01c0821a25b9d7fe776e)) ## 2.0.2 (2023-06-10) - ### Bug Fixes -* update Types ([df48ec3](https://github.com/bcnmy/biconomy-client-sdk/commit/df48ec3c04cf44a8f64eb302217655076c6304a4)) - +- update Types ([df48ec3](https://github.com/bcnmy/biconomy-client-sdk/commit/df48ec3c04cf44a8f64eb302217655076c6304a4)) ## 2.0.1 (2023-05-18) - ### Bug Fixes -* build changes related to scw changes ([940d464](https://github.com/bcnmy/biconomy-client-sdk/commit/940d464ee2693cb6478d785564a141441e8e3676)) - - - +- build changes related to scw changes ([940d464](https://github.com/bcnmy/biconomy-client-sdk/commit/940d464ee2693cb6478d785564a141441e8e3676)) ## 2.0.0 (2023-04-07) - ### Bug Fixes -* error handling ([637bb67](https://github.com/bcnmy/biconomy-client-sdk/commit/637bb67b9390e39b4571374108bc70447a531963)) -* undefined log issue ([42f3f70](https://github.com/bcnmy/biconomy-client-sdk/commit/42f3f7040c96ff5ac57459224b09a25f95d2cd8c)) - +- error handling ([637bb67](https://github.com/bcnmy/biconomy-client-sdk/commit/637bb67b9390e39b4571374108bc70447a531963)) +- undefined log issue ([42f3f70](https://github.com/bcnmy/biconomy-client-sdk/commit/42f3f7040c96ff5ac57459224b09a25f95d2cd8c)) ### Features -* improve logs ([fb15af3](https://github.com/bcnmy/biconomy-client-sdk/commit/fb15af3af48ccf50101fedd7f9bb44ee97c747c4)) -* sdk test spec improvement ([fd80048](https://github.com/bcnmy/biconomy-client-sdk/commit/fd80048db7a60d34412dcb00f6dd8bb202f41ad3)) - - - - +- improve logs ([fb15af3](https://github.com/bcnmy/biconomy-client-sdk/commit/fb15af3af48ccf50101fedd7f9bb44ee97c747c4)) +- sdk test spec improvement ([fd80048](https://github.com/bcnmy/biconomy-client-sdk/commit/fd80048db7a60d34412dcb00f6dd8bb202f41ad3)) ## 1.0.0 (2023-01-03) diff --git a/packages/common/src/Constants.ts b/packages/common/src/Constants.ts index a8ffd9651..17745f6cd 100644 --- a/packages/common/src/Constants.ts +++ b/packages/common/src/Constants.ts @@ -1,25 +1,25 @@ -import { ChainId } from '@biconomy/core-types' +import { ChainId } from "@biconomy/core-types"; -export const NODE_CLIENT_URL = 'https://sdk-backend.prod.biconomy.io/v1' +export const NODE_CLIENT_URL = "https://sdk-backend.prod.biconomy.io/v1"; export const RPC_PROVIDER_URLS: { [key in ChainId]?: string } = { - [ChainId.MAINNET]: 'https://rpc.ankr.com/eth', - [ChainId.GOERLI]: 'https://rpc.ankr.com/eth_goerli', - [ChainId.POLYGON_MUMBAI]: 'https://rpc.ankr.com/polygon_mumbai', - [ChainId.POLYGON_MAINNET]: 'https://rpc.ankr.com/polygon', - [ChainId.BSC_TESTNET]: 'https://endpoints.omniatech.io/v1/bsc/testnet/public', - [ChainId.BSC_MAINNET]: 'https://rpc.ankr.com/bsc', - [ChainId.POLYGON_ZKEVM_TESTNET]: 'https://rpc.public.zkevm-test.net', - [ChainId.POLYGON_ZKEVM_MAINNET]: 'https://rpc.ankr.com/polygon_zkevm', - [ChainId.ARBITRUM_GOERLI_TESTNET]: 'https://goerli-rollup.arbitrum.io/rpc', - [ChainId.ARBITRUM_ONE_MAINNET]: 'https://rpc.ankr.com/arbitrum', - [ChainId.ARBITRUM_NOVA_MAINNET]: 'https://nova.arbitrum.io/rpc', - [ChainId.OPTIMISM_MAINNET]: 'https://mainnet.optimism.io', - [ChainId.OPTIMISM_GOERLI_TESTNET]: 'https://goerli.optimism.io', - [ChainId.AVALANCHE_MAINNET]: 'https://api.avax.network/ext/bc/C/rpc', - [ChainId.AVALANCHE_TESTNET]: 'https://api.avax-test.network/ext/bc/C/rpc', - [ChainId.MOONBEAM_MAINNET]: 'https://rpc.api.moonbeam.network', - [ChainId.BASE_GOERLI_TESTNET]: 'https://goerli.base.org', - [ChainId.BASE_MAINNET]: 'https://developer-access-mainnet.base.org', - [ChainId.LINEA_TESTNET]: 'https://rpc.goerli.linea.build' -} + [ChainId.MAINNET]: "https://rpc.ankr.com/eth", + [ChainId.GOERLI]: "https://rpc.ankr.com/eth_goerli", + [ChainId.POLYGON_MUMBAI]: "https://rpc.ankr.com/polygon_mumbai", + [ChainId.POLYGON_MAINNET]: "https://rpc.ankr.com/polygon", + [ChainId.BSC_TESTNET]: "https://endpoints.omniatech.io/v1/bsc/testnet/public", + [ChainId.BSC_MAINNET]: "https://rpc.ankr.com/bsc", + [ChainId.POLYGON_ZKEVM_TESTNET]: "https://rpc.public.zkevm-test.net", + [ChainId.POLYGON_ZKEVM_MAINNET]: "https://rpc.ankr.com/polygon_zkevm", + [ChainId.ARBITRUM_GOERLI_TESTNET]: "https://goerli-rollup.arbitrum.io/rpc", + [ChainId.ARBITRUM_ONE_MAINNET]: "https://rpc.ankr.com/arbitrum", + [ChainId.ARBITRUM_NOVA_MAINNET]: "https://nova.arbitrum.io/rpc", + [ChainId.OPTIMISM_MAINNET]: "https://mainnet.optimism.io", + [ChainId.OPTIMISM_GOERLI_TESTNET]: "https://goerli.optimism.io", + [ChainId.AVALANCHE_MAINNET]: "https://api.avax.network/ext/bc/C/rpc", + [ChainId.AVALANCHE_TESTNET]: "https://api.avax-test.network/ext/bc/C/rpc", + [ChainId.MOONBEAM_MAINNET]: "https://rpc.api.moonbeam.network", + [ChainId.BASE_GOERLI_TESTNET]: "https://goerli.base.org", + [ChainId.BASE_MAINNET]: "https://developer-access-mainnet.base.org", + [ChainId.LINEA_TESTNET]: "https://rpc.goerli.linea.build", +}; diff --git a/packages/common/src/ContractsInstances.ts b/packages/common/src/ContractsInstances.ts index f080d5f6f..11a2c2a53 100644 --- a/packages/common/src/ContractsInstances.ts +++ b/packages/common/src/ContractsInstances.ts @@ -1,65 +1,61 @@ -import { SmartAccountType } from '@biconomy/core-types' -import { JsonRpcProvider } from '@ethersproject/providers' +import { SmartAccountType } from "@biconomy/core-types"; +import { JsonRpcProvider } from "@ethersproject/providers"; import { EntryPoint_v100, EntryPoint_v100__factory, SmartAccount_v100, SmartAccountFactory_v100, SmartAccountFactory_v100__factory, - SmartAccount_v100__factory -} from './typechain' + SmartAccount_v100__factory, +} from "./typechain"; export type GetContractInstanceDto = { - smartAccountType: SmartAccountType - version: string - contractAddress: string - provider: JsonRpcProvider -} + smartAccountType: SmartAccountType; + version: string; + contractAddress: string; + provider: JsonRpcProvider; +}; export function getSAProxyContract(contractInstanceDto: GetContractInstanceDto): SmartAccount_v100 { - const { smartAccountType, version, contractAddress, provider } = contractInstanceDto + const { smartAccountType, version, contractAddress, provider } = contractInstanceDto; switch (version) { - case 'V1_0_0': + case "V1_0_0": if (smartAccountType === SmartAccountType.BICONOMY) { - return SmartAccount_v100__factory.connect(contractAddress, provider) + return SmartAccount_v100__factory.connect(contractAddress, provider); } - break + break; default: - return SmartAccount_v100__factory.connect(contractAddress, provider) + return SmartAccount_v100__factory.connect(contractAddress, provider); } - throw new Error('Invalid version or smartAccountType provided for proxy contract instance') + throw new Error("Invalid version or smartAccountType provided for proxy contract instance"); } -export function getSAFactoryContract( - contractInstanceDto: GetContractInstanceDto -): SmartAccountFactory_v100 { - const { smartAccountType, version, contractAddress, provider } = contractInstanceDto +export function getSAFactoryContract(contractInstanceDto: GetContractInstanceDto): SmartAccountFactory_v100 { + const { smartAccountType, version, contractAddress, provider } = contractInstanceDto; switch (version) { - case 'V1_0_0': + case "V1_0_0": if (smartAccountType === SmartAccountType.BICONOMY) { - return SmartAccountFactory_v100__factory.connect(contractAddress, provider) + return SmartAccountFactory_v100__factory.connect(contractAddress, provider); } - break + break; default: - return SmartAccountFactory_v100__factory.connect(contractAddress, provider) + return SmartAccountFactory_v100__factory.connect(contractAddress, provider); } - throw new Error('Invalid version or smartAccountType provided for factory contract instance') + throw new Error("Invalid version or smartAccountType provided for factory contract instance"); } -export function getEntryPointContract( - contractInstanceDto: GetContractInstanceDto -): EntryPoint_v100 { - const { smartAccountType, version, contractAddress, provider } = contractInstanceDto +export function getEntryPointContract(contractInstanceDto: GetContractInstanceDto): EntryPoint_v100 { + const { smartAccountType, version, contractAddress, provider } = contractInstanceDto; switch (version) { - case 'V0_0_5': + case "V0_0_5": if (smartAccountType === SmartAccountType.BICONOMY) { - return EntryPoint_v100__factory.connect(contractAddress, provider) + return EntryPoint_v100__factory.connect(contractAddress, provider); } - break + break; default: - return EntryPoint_v100__factory.connect(contractAddress, provider) + return EntryPoint_v100__factory.connect(contractAddress, provider); } - throw new Error('Invalid version or smartAccountType provided for entrypoint contract instance') + throw new Error("Invalid version or smartAccountType provided for entrypoint contract instance"); } diff --git a/packages/common/src/ERC4337Utils.ts b/packages/common/src/ERC4337Utils.ts index e72622885..435e82746 100644 --- a/packages/common/src/ERC4337Utils.ts +++ b/packages/common/src/ERC4337Utils.ts @@ -1,19 +1,19 @@ -import { defaultAbiCoder, hexConcat, hexlify, keccak256 } from 'ethers/lib/utils' -import { ethers } from 'ethers' -import Debug from 'debug' -import { ChainId, UserOperation } from '@biconomy/core-types' +import { defaultAbiCoder, hexConcat, hexlify, keccak256 } from "ethers/lib/utils"; +import { ethers } from "ethers"; +import Debug from "debug"; +import { ChainId, UserOperation } from "@biconomy/core-types"; -const debug = Debug('aa.utils') +const debug = Debug("aa.utils"); -export const AddressZero = ethers.constants.AddressZero +export const AddressZero = ethers.constants.AddressZero; -export const EIP1559_UNSUPPORTED_NETWORKS: Array = [97, 56, 1442, 1101] +export const EIP1559_UNSUPPORTED_NETWORKS: Array = [97, 56, 1442, 1101]; // reverse "Deferrable" or "PromiseOrValue" fields /* eslint-disable @typescript-eslint/no-explicit-any */ export type NotPromise = { - [P in keyof T]: Exclude> -} + [P in keyof T]: Exclude>; +}; // function encode(typevalues: Array<{ type: string; val: any }>, forSignature: boolean): string { // const types = typevalues.map((typevalue) => @@ -32,23 +32,11 @@ export type NotPromise = { * "false" to pack entire UserOp, for calculating the calldata cost of putting it on-chain. */ export function packUserOp(op: Partial, forSignature = true): string { - if (!op.initCode || !op.callData || !op.paymasterAndData) - throw new Error('Missing userOp properties') + if (!op.initCode || !op.callData || !op.paymasterAndData) throw new Error("Missing userOp properties"); if (forSignature) { return defaultAbiCoder.encode( - [ - 'address', - 'uint256', - 'bytes32', - 'bytes32', - 'uint256', - 'uint256', - 'uint256', - 'uint256', - 'uint256', - 'bytes32' - ], + ["address", "uint256", "bytes32", "bytes32", "uint256", "uint256", "uint256", "uint256", "uint256", "bytes32"], [ op.sender, op.nonce, @@ -59,25 +47,13 @@ export function packUserOp(op: Partial, forSignature = true): str op.preVerificationGas, op.maxFeePerGas, op.maxPriorityFeePerGas, - keccak256(op.paymasterAndData) - ] - ) + keccak256(op.paymasterAndData), + ], + ); } else { // for the purpose of calculating gas cost encode also signature (and no keccak of bytes) return defaultAbiCoder.encode( - [ - 'address', - 'uint256', - 'bytes', - 'bytes', - 'uint256', - 'uint256', - 'uint256', - 'uint256', - 'uint256', - 'bytes', - 'bytes' - ], + ["address", "uint256", "bytes", "bytes", "uint256", "uint256", "uint256", "uint256", "uint256", "bytes", "bytes"], [ op.sender, op.nonce, @@ -89,9 +65,9 @@ export function packUserOp(op: Partial, forSignature = true): str op.maxFeePerGas, op.maxPriorityFeePerGas, op.paymasterAndData, - op.signature - ] - ) + op.signature, + ], + ); } } @@ -104,56 +80,46 @@ export function packUserOp(op: Partial, forSignature = true): str * @param entryPoint * @param chainId */ -export function getUserOpHash( - op: Partial, - entryPoint: string, - chainId: number -): string { - const userOpHash = keccak256(packUserOp(op, true)) - const enc = defaultAbiCoder.encode( - ['bytes32', 'address', 'uint256'], - [userOpHash, entryPoint, chainId] - ) - return keccak256(enc) +export function getUserOpHash(op: Partial, entryPoint: string, chainId: number): string { + const userOpHash = keccak256(packUserOp(op, true)); + const enc = defaultAbiCoder.encode(["bytes32", "address", "uint256"], [userOpHash, entryPoint, chainId]); + return keccak256(enc); } -const ErrorSig = keccak256(Buffer.from('Error(string)')).slice(0, 10) // 0x08c379a0 -const FailedOpSig = keccak256(Buffer.from('FailedOp(uint256,address,string)')).slice(0, 10) // 0x00fa072b +const ErrorSig = keccak256(Buffer.from("Error(string)")).slice(0, 10); // 0x08c379a0 +const FailedOpSig = keccak256(Buffer.from("FailedOp(uint256,address,string)")).slice(0, 10); // 0x00fa072b interface DecodedError { - message: string - opIndex?: number - paymaster?: string + message: string; + opIndex?: number; + paymaster?: string; } /** * decode bytes thrown by revert as Error(message) or FailedOp(opIndex,paymaster,message) */ export function decodeErrorReason(error: string): DecodedError | undefined { - debug('decoding', error) + debug("decoding", error); if (error.startsWith(ErrorSig)) { - const [message] = defaultAbiCoder.decode(['string'], '0x' + error.substring(10)) - return { message } + const [message] = defaultAbiCoder.decode(["string"], "0x" + error.substring(10)); + return { message }; } else if (error.startsWith(FailedOpSig)) { - const resultSet = defaultAbiCoder.decode( - ['uint256', 'address', 'string'], - '0x' + error.substring(10) - ) - let [paymaster, message] = resultSet - const [opIndex] = resultSet - message = `FailedOp: ${message as string}` + const resultSet = defaultAbiCoder.decode(["uint256", "address", "string"], "0x" + error.substring(10)); + let [paymaster, message] = resultSet; + const [opIndex] = resultSet; + message = `FailedOp: ${message as string}`; if (paymaster.toString() !== ethers.constants.AddressZero) { - message = `${message as string} (paymaster ${paymaster as string})` + message = `${message as string} (paymaster ${paymaster as string})`; } else { - paymaster = undefined + paymaster = undefined; } return { message, opIndex, - paymaster - } + paymaster, + }; } - return undefined + return undefined; } /** @@ -163,31 +129,27 @@ export function decodeErrorReason(error: string): DecodedError | undefined { * usage: entryPoint.handleOps().catch(decodeError) */ export function rethrowError(e: any): any { - let error = e - let parent = e + let error = e; + let parent = e; if (error?.error != null) { - error = error.error + error = error.error; } while (error?.data != null) { - parent = error - error = error.data + parent = error; + error = error.data; } - const decoded = - typeof error === 'string' && error.length > 2 ? decodeErrorReason(error) : undefined + const decoded = typeof error === "string" && error.length > 2 ? decodeErrorReason(error) : undefined; if (decoded != null) { - e.message = decoded.message + e.message = decoded.message; if (decoded.opIndex != null) { // helper for chai: convert our FailedOp error into "Error(msg)" - const errorWithMsg = hexConcat([ - ErrorSig, - defaultAbiCoder.encode(['string'], [decoded.message]) - ]) + const errorWithMsg = hexConcat([ErrorSig, defaultAbiCoder.encode(["string"], [decoded.message])]); // modify in-place the error object: - parent.data = errorWithMsg + parent.data = errorWithMsg; } } - throw e + throw e; } /** @@ -195,22 +157,22 @@ export function rethrowError(e: any): any { * @param obj */ export function deepHexlify(obj: any): any { - if (typeof obj === 'function') { - return undefined + if (typeof obj === "function") { + return undefined; } - if (obj == null || typeof obj === 'string' || typeof obj === 'boolean') { - return obj - } else if (obj._isBigNumber != null || typeof obj !== 'object') { - return hexlify(obj).replace(/^0x0/, '0x') + if (obj == null || typeof obj === "string" || typeof obj === "boolean") { + return obj; + } else if (obj._isBigNumber != null || typeof obj !== "object") { + return hexlify(obj).replace(/^0x0/, "0x"); } if (Array.isArray(obj)) { - return obj.map((member) => deepHexlify(member)) + return obj.map((member) => deepHexlify(member)); } return Object.keys(obj).reduce( (set, key) => ({ ...set, - [key]: deepHexlify(obj[key]) + [key]: deepHexlify(obj[key]), }), - {} - ) + {}, + ); } diff --git a/packages/common/src/Logger.ts b/packages/common/src/Logger.ts index 531608eb4..c2489d631 100644 --- a/packages/common/src/Logger.ts +++ b/packages/common/src/Logger.ts @@ -5,12 +5,7 @@ */ class Logger { // By default, the logger is not in debug mode. - static isDebug: boolean = - process.env.BICONOMY_SDK_DEBUG === 'true' - ? true - : process.env.REACT_APP_BICONOMY_SDK_DEBUG === 'true' - ? true - : false + static isDebug: boolean = process.env.BICONOMY_SDK_DEBUG === "true" ? true : process.env.REACT_APP_BICONOMY_SDK_DEBUG === "true" ? true : false; /** * \x1b[0m is an escape sequence to reset the color of the text @@ -21,31 +16,33 @@ class Logger { */ /* eslint-disable @typescript-eslint/no-explicit-any */ static log(message: string, value?: any): void { - const timestamp = new Date().toISOString() - const logMessage = `\x1b[35m[${timestamp}]\x1b[0m \x1b[36m${message}\x1b[0m:` + const timestamp = new Date().toISOString(); + const logMessage = `\x1b[35m[${timestamp}]\x1b[0m \x1b[36m${message}\x1b[0m:`; if (Logger.isDebug) { - console.log(logMessage, value === undefined ? '' : value) + console.log(logMessage, value === undefined ? "" : value); } } + /* eslint-disable @typescript-eslint/no-explicit-any */ static warn(message: string, value?: any): void { - const timestamp = new Date().toISOString() - const warnMessage = `\x1b[35m[${timestamp}]\x1b[0m \x1b[33mWARN\x1b[0m: \x1b[36m${message}\x1b[0m` + const timestamp = new Date().toISOString(); + const warnMessage = `\x1b[35m[${timestamp}]\x1b[0m \x1b[33mWARN\x1b[0m: \x1b[36m${message}\x1b[0m`; if (Logger.isDebug) { - console.warn(warnMessage, value === undefined ? '' : value) + console.warn(warnMessage, value === undefined ? "" : value); } } + /* eslint-disable @typescript-eslint/no-explicit-any */ static error(message: string, value?: any): void { - const timestamp = new Date().toISOString() - const errorMessage = `\x1b[35m[${timestamp}]\x1b[0m \x1b[31mERROR\x1b[0m: \x1b[36m${message}\x1b[0m` + const timestamp = new Date().toISOString(); + const errorMessage = `\x1b[35m[${timestamp}]\x1b[0m \x1b[31mERROR\x1b[0m: \x1b[36m${message}\x1b[0m`; if (Logger.isDebug) { - console.error(errorMessage, value === undefined ? '' : value) + console.error(errorMessage, value === undefined ? "" : value); } } } -export { Logger } +export { Logger }; diff --git a/packages/common/src/Utils.ts b/packages/common/src/Utils.ts index d9aeceea9..b6f5568d2 100644 --- a/packages/common/src/Utils.ts +++ b/packages/common/src/Utils.ts @@ -3,5 +3,5 @@ * @returns Number */ export const getTimestampInSeconds = (): number => { - return Math.floor(Date.now() / 1000) -} + return Math.floor(Date.now() / 1000); +}; diff --git a/packages/common/src/httpRequests.ts b/packages/common/src/httpRequests.ts index 8bb71211e..b2d81b1b3 100644 --- a/packages/common/src/httpRequests.ts +++ b/packages/common/src/httpRequests.ts @@ -1,75 +1,73 @@ -import fetch from 'node-fetch' -import { Logger } from './Logger' +import fetch from "node-fetch"; +import { Logger } from "./Logger"; export enum HttpMethod { - Get = 'get', - Post = 'post', - Delete = 'delete' + Get = "get", + Post = "post", + Delete = "delete", } /* eslint-disable @typescript-eslint/no-explicit-any */ interface HttpRequest { - url: string - method: HttpMethod - body?: Record - headers?: object + url: string; + method: HttpMethod; + body?: Record; + headers?: object; } export async function sendRequest({ url, method, body, headers = {} }: HttpRequest): Promise { - Logger.log('jsonRpc request body ', JSON.stringify(body)) + Logger.log("jsonRpc request body ", JSON.stringify(body)); const response = await fetch(url, { method, headers: { ...headers, - Accept: 'application/json', - 'Content-Type': 'application/json' + Accept: "application/json", + "Content-Type": "application/json", }, - body: JSON.stringify(body) - }) + body: JSON.stringify(body), + }); - let jsonResponse + let jsonResponse; try { - jsonResponse = await response.json() + jsonResponse = await response.json(); } catch (error) { if (!response.ok) { - throw new Error(response.statusText) + throw new Error(response.statusText); } } - Logger.log('jsonRpc response ', jsonResponse) + Logger.log("jsonRpc response ", jsonResponse); if (response.ok) { - if (jsonResponse && jsonResponse.hasOwnProperty('result')) { - return jsonResponse as T + if (jsonResponse && jsonResponse.hasOwnProperty("result")) { + return jsonResponse as T; } // else } - const errorObject = { code: response.status, message: response.statusText, data: undefined } + const errorObject = { code: response.status, message: response.statusText, data: undefined }; if (jsonResponse?.error) { - if (typeof jsonResponse.error === 'string') { - const error = jsonResponse.error - errorObject.code = response.status - errorObject.message = error - delete errorObject.data - throw errorObject - } else if (typeof jsonResponse.error === 'object') { - const error = jsonResponse.error - errorObject.code = error?.code - errorObject.message = error?.message - errorObject.data = error?.handleOpsCallData - throw errorObject + if (typeof jsonResponse.error === "string") { + const error = jsonResponse.error; + errorObject.code = response.status; + errorObject.message = error; + delete errorObject.data; + throw errorObject; + } else if (typeof jsonResponse.error === "object") { + const error = jsonResponse.error; + errorObject.code = error?.code; + errorObject.message = error?.message; + errorObject.data = error?.handleOpsCallData; + throw errorObject; } } if (jsonResponse?.message) { - errorObject.message = jsonResponse.message - throw errorObject + errorObject.message = jsonResponse.message; + throw errorObject; } if (jsonResponse?.msg) { - errorObject.message = jsonResponse.msg - throw errorObject + errorObject.message = jsonResponse.msg; + throw errorObject; } - throw new Error( - 'Unknown Error: Raise an issue here https://github.com/bcnmy/biconomy-client-sdk/issues with reproduction steps' - ) + throw new Error("Unknown Error: Raise an issue here https://github.com/bcnmy/biconomy-client-sdk/issues with reproduction steps"); } diff --git a/packages/common/src/index.ts b/packages/common/src/index.ts index 83e650ce7..a23afa8c6 100644 --- a/packages/common/src/index.ts +++ b/packages/common/src/index.ts @@ -1,7 +1,7 @@ -export * from './ERC4337Utils' -export * from './Logger' -export * from './httpRequests' -export * from './typechain/index' -export * from './Utils' -export * from './Constants' -export * from './ContractsInstances' +export * from "./ERC4337Utils"; +export * from "./Logger"; +export * from "./httpRequests"; +export * from "./typechain/index"; +export * from "./Utils"; +export * from "./Constants"; +export * from "./ContractsInstances"; diff --git a/packages/common/tests/ERC4337Utils.spec.ts b/packages/common/tests/ERC4337Utils.spec.ts index 911800886..b7a6af546 100644 --- a/packages/common/tests/ERC4337Utils.spec.ts +++ b/packages/common/tests/ERC4337Utils.spec.ts @@ -1,44 +1,44 @@ -import { expect } from 'chai' -import { packUserOp } from '../src/ERC4337Utils' +import { expect } from "chai"; +import { packUserOp } from "../src/ERC4337Utils"; -describe('packUserOp', () => { - it('should pack a UserOperationStruct object', () => { +describe("packUserOp", () => { + it("should pack a UserOperationStruct object", () => { const userOp = { - sender: '0x1234567890123456789012345678901234567890', + sender: "0x1234567890123456789012345678901234567890", nonce: 1, - initCode: '0x0987654321098765432109876543210987654321', - callData: '0x', + initCode: "0x0987654321098765432109876543210987654321", + callData: "0x", callGasLimit: 1000000, verificationGasLimit: 1000000, preVerificationGas: 1000000, maxFeePerGas: 10, maxPriorityFeePerGas: 1, - paymasterAndData: '0x0987654321098765432109876543210987654321', - signature: '0x' - } - const packedUserOp = packUserOp(userOp, false) + paymasterAndData: "0x0987654321098765432109876543210987654321", + signature: "0x", + }; + const packedUserOp = packUserOp(userOp, false); expect(packedUserOp).to.equal( - '0x00000000000000000000000012345678901234567890123456789012345678900000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000f4240000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001409876543210987654321098765432109876543210000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001409876543210987654321098765432109876543210000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' - ) - }) + "0x00000000000000000000000012345678901234567890123456789012345678900000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000f4240000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001409876543210987654321098765432109876543210000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001409876543210987654321098765432109876543210000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + ); + }); - it('should pack a UserOperationStruct object for signature', () => { + it("should pack a UserOperationStruct object for signature", () => { const userOp = { - sender: '0x1234567890123456789012345678901234567890', + sender: "0x1234567890123456789012345678901234567890", nonce: 1, - initCode: '0x0987654321098765432109876543210987654321', - callData: '0x', + initCode: "0x0987654321098765432109876543210987654321", + callData: "0x", callGasLimit: 1000000, verificationGasLimit: 1000000, preVerificationGas: 1000000, maxFeePerGas: 10, maxPriorityFeePerGas: 1, - paymasterAndData: '0x0987654321098765432109876543210987654321', - signature: '0x' - } - const packedUserOp = packUserOp(userOp, true) + paymasterAndData: "0x0987654321098765432109876543210987654321", + signature: "0x", + }; + const packedUserOp = packUserOp(userOp, true); expect(packedUserOp).to.equal( - '0x00000000000000000000000012345678901234567890123456789012345678900000000000000000000000000000000000000000000000000000000000000001a04121637443bf141af4dc01872f24d6933dd1e67581bd12f805a945888da6b0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47000000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000f4240000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000001a04121637443bf141af4dc01872f24d6933dd1e67581bd12f805a945888da6b0' - ) - }) -}) + "0x00000000000000000000000012345678901234567890123456789012345678900000000000000000000000000000000000000000000000000000000000000001a04121637443bf141af4dc01872f24d6933dd1e67581bd12f805a945888da6b0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47000000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000f4240000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000001a04121637443bf141af4dc01872f24d6933dd1e67581bd12f805a945888da6b0", + ); + }); +}); diff --git a/packages/common/tsconfig.json b/packages/common/tsconfig.json index f8295f226..7584e7676 100644 --- a/packages/common/tsconfig.json +++ b/packages/common/tsconfig.json @@ -1,10 +1,9 @@ { - "extends": "../../tsconfig.settings.json", - "compilerOptions": { - "composite": true, - "outDir": "dist", - "baseUrl": "src" - }, - "include": ["./**/*.ts"] + "extends": "../../tsconfig.settings.json", + "compilerOptions": { + "composite": true, + "outDir": "dist", + "baseUrl": "src" + }, + "include": ["./**/*.ts"] } - \ No newline at end of file diff --git a/packages/core-types/CHANGELOG.md b/packages/core-types/CHANGELOG.md index 7af82ce71..c2f72016b 100644 --- a/packages/core-types/CHANGELOG.md +++ b/packages/core-types/CHANGELOG.md @@ -5,78 +5,56 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline ## 3.0.0 (2023-08-28) - ### Features -* base mainnet integration ([c17f5d6](https://github.com/bcnmy/biconomy-client-sdk/commit/c17f5d6c2fe34b106e6d9755f54fab2493db6fbe)) - - +- base mainnet integration ([c17f5d6](https://github.com/bcnmy/biconomy-client-sdk/commit/c17f5d6c2fe34b106e6d9755f54fab2493db6fbe)) ## 3.0.0-alpha.0 (2023-08-02) VERSION bump only - - # 3.1.0-alpha.0 (2023-07-24) - - ### Features -* chain integration ([738556e](https://github.com/bcnmy/biconomy-client-sdk/commit/738556efcfda70fedc652befc0b35f8835c5e360)) - - +- chain integration ([738556e](https://github.com/bcnmy/biconomy-client-sdk/commit/738556efcfda70fedc652befc0b35f8835c5e360)) ## 3.0.0-alpha.0 (2023-07-12) - ### Bug Fixes -* bundler sync changes ([eb9b30d](https://github.com/bcnmy/biconomy-client-sdk/commit/eb9b30d786820b4c9a6a18c72481d0ed3782a22e)) - +- bundler sync changes ([eb9b30d](https://github.com/bcnmy/biconomy-client-sdk/commit/eb9b30d786820b4c9a6a18c72481d0ed3782a22e)) ## 2.0.2 (2023-06-10) -* smart account state types to have factory address added - +- smart account state types to have factory address added ## 2.0.1 (2023-05-18) - ### Bug Fixes -* logic update ([41c4aec](https://github.com/bcnmy/biconomy-client-sdk/commit/41c4aec8ab5012b7ad362b2870966bd607e38636)) -* fix build issue in angular for relative path (https://github.com/bcnmy/biconomy-client-sdk/commit/eb9b30d786820b4c9a6a18c72481d0ed3782a22e) - +- logic update ([41c4aec](https://github.com/bcnmy/biconomy-client-sdk/commit/41c4aec8ab5012b7ad362b2870966bd607e38636)) +- fix build issue in angular for relative path (https://github.com/bcnmy/biconomy-client-sdk/commit/eb9b30d786820b4c9a6a18c72481d0ed3782a22e) ### Features -* chain integrations ([9af2da0](https://github.com/bcnmy/biconomy-client-sdk/commit/9af2da03820a26ac7d21301c32de041ced6c5e43)) -* Type added for PaymasterServiceData + reordering of params ([fae8b3a](https://github.com/bcnmy/biconomy-client-sdk/commit/fae8b3a02a5e810a9a40674d27f389b89199bb62)) -* logic changed to accept paymasterServiceData ([6daaf37](https://github.com/bcnmy/biconomy-client-sdk/commit/6daaf37855a13fa6e12fdbab16a7e980b4631475)) -* UserOpGasFields for fetching gas and gas prices from bundler (https://github.com/bcnmy/biconomy-client-sdk/commit/a0c070b04bb6e249388a7d304dad7d08e97810e1) -* skipEstimation added in dto update CreateUserPaidTransactionDto ([487f3ae](https://github.com/bcnmy/biconomy-client-sdk/commit/487f3aefe21b2dd4fd46e18bef7168eae3c1ecc1)) -* fetching gas prices from bundler ([a0c070b](https://github.com/bcnmy/biconomy-client-sdk/commit/a0c070b04bb6e249388a7d304dad7d08e97810e1)) - - - - - +- chain integrations ([9af2da0](https://github.com/bcnmy/biconomy-client-sdk/commit/9af2da03820a26ac7d21301c32de041ced6c5e43)) +- Type added for PaymasterServiceData + reordering of params ([fae8b3a](https://github.com/bcnmy/biconomy-client-sdk/commit/fae8b3a02a5e810a9a40674d27f389b89199bb62)) +- logic changed to accept paymasterServiceData ([6daaf37](https://github.com/bcnmy/biconomy-client-sdk/commit/6daaf37855a13fa6e12fdbab16a7e980b4631475)) +- UserOpGasFields for fetching gas and gas prices from bundler (https://github.com/bcnmy/biconomy-client-sdk/commit/a0c070b04bb6e249388a7d304dad7d08e97810e1) +- skipEstimation added in dto update CreateUserPaidTransactionDto ([487f3ae](https://github.com/bcnmy/biconomy-client-sdk/commit/487f3aefe21b2dd4fd46e18bef7168eae3c1ecc1)) +- fetching gas prices from bundler ([a0c070b](https://github.com/bcnmy/biconomy-client-sdk/commit/a0c070b04bb6e249388a7d304dad7d08e97810e1)) ## 2.0.0 (2023-04-07) - ### Bug Fixes -* backend contract address ([e81188d](https://github.com/bcnmy/biconomy-client-sdk/commit/e81188d454eb42ab581078d218d86571d724fa2d)) -* multisend bundle ([5f55587](https://github.com/bcnmy/biconomy-client-sdk/commit/5f55587b63c82a30652843fe619d8b891e495399)) -* optional sign flag ([0d689d2](https://github.com/bcnmy/biconomy-client-sdk/commit/0d689d214fc7abf32f4f2deabcce61041b73d642)) - +- backend contract address ([e81188d](https://github.com/bcnmy/biconomy-client-sdk/commit/e81188d454eb42ab581078d218d86571d724fa2d)) +- multisend bundle ([5f55587](https://github.com/bcnmy/biconomy-client-sdk/commit/5f55587b63c82a30652843fe619d8b891e495399)) +- optional sign flag ([0d689d2](https://github.com/bcnmy/biconomy-client-sdk/commit/0d689d214fc7abf32f4f2deabcce61041b73d642)) ## 1.0.0 (2023-01-03) - ### Bug Fixes -* optional sign flag ([0d689d2](https://github.com/bcnmy/biconomy-client-sdk/commit/0d689d214fc7abf32f4f2deabcce61041b73d642)) +- optional sign flag ([0d689d2](https://github.com/bcnmy/biconomy-client-sdk/commit/0d689d214fc7abf32f4f2deabcce61041b73d642)) diff --git a/packages/core-types/README.md b/packages/core-types/README.md index b5da5589f..4fcf8c7bf 100644 --- a/packages/core-types/README.md +++ b/packages/core-types/README.md @@ -9,10 +9,5 @@ Common types in the [Biconomy SDK](https://github.com/bcnmy/biconomy-client-sdk) for example ```typescript -import { - SmartAccountState, - SmartAccountVersion, - GasLimit, - ChainId -} from "@biconomy/core-types"; -``` \ No newline at end of file +import { SmartAccountState, SmartAccountVersion, GasLimit, ChainId } from "@biconomy/core-types"; +``` diff --git a/packages/core-types/src/BundlerTypes.ts b/packages/core-types/src/BundlerTypes.ts index 3e62520a9..9397dc7fd 100644 --- a/packages/core-types/src/BundlerTypes.ts +++ b/packages/core-types/src/BundlerTypes.ts @@ -1,8 +1,8 @@ export type UserOpGasFields = { - maxPriorityFeePerGas: string | null - maxFeePerGas: string | null - gasPrice: string | null - callGasLimit: number - verificationGasLimit: number - preVerificationGas: number -} + maxPriorityFeePerGas: string | null; + maxFeePerGas: string | null; + gasPrice: string | null; + callGasLimit: number; + verificationGasLimit: number; + preVerificationGas: number; +}; diff --git a/packages/core-types/src/ChainsTypes.ts b/packages/core-types/src/ChainsTypes.ts index 4f51a47cb..f8d931af3 100644 --- a/packages/core-types/src/ChainsTypes.ts +++ b/packages/core-types/src/ChainsTypes.ts @@ -1,28 +1,28 @@ export enum ChainNames { - Mainnet = 'mainnet', - Ropsten = 'ropsten', - Rinkeby = 'rinkeby', - Goerli = 'goerli', - Kovan = 'kovan', - Xdai = 'xdai', - Bsc = 'bsc', - BscTest = 'bscTest', - Fantom = 'fantom', - FantomTest = 'fantomTest', - Matic = 'matic', - Mumbai = 'mumbai', - Aurora = 'aurora', - AuroraTest = 'auroraTest', - Avalanche = 'avalanche', - Fuji = 'fuji', - Optimism = 'optimism', - OptimismKovan = 'optimismKovan', - Arbitrum = 'arbitrum', - ArbitrumTest = 'arbitrumTest', - Moonbeam = 'moonbeam', - Moonbase = 'moonbase', - Celo = 'celo', - CeloTest = 'celoTest' + Mainnet = "mainnet", + Ropsten = "ropsten", + Rinkeby = "rinkeby", + Goerli = "goerli", + Kovan = "kovan", + Xdai = "xdai", + Bsc = "bsc", + BscTest = "bscTest", + Fantom = "fantom", + FantomTest = "fantomTest", + Matic = "matic", + Mumbai = "mumbai", + Aurora = "aurora", + AuroraTest = "auroraTest", + Avalanche = "avalanche", + Fuji = "fuji", + Optimism = "optimism", + OptimismKovan = "optimismKovan", + Arbitrum = "arbitrum", + ArbitrumTest = "arbitrumTest", + Moonbeam = "moonbeam", + Moonbase = "moonbase", + Celo = "celo", + CeloTest = "celoTest", } // NOTE: Update chainId for networks we're planning to support @@ -47,5 +47,5 @@ export enum ChainId { BASE_GOERLI_TESTNET = 84531, BASE_MAINNET = 8453, LINEA_TESTNET = 59140, - GANACHE = 1337 //Temp + GANACHE = 1337, //Temp } diff --git a/packages/core-types/src/PaymasterServiceTypes.ts b/packages/core-types/src/PaymasterServiceTypes.ts index d0535e8db..c5d3f4bb5 100644 --- a/packages/core-types/src/PaymasterServiceTypes.ts +++ b/packages/core-types/src/PaymasterServiceTypes.ts @@ -1,6 +1,6 @@ export type PaymasterServiceDataType = { webhookData?: { // eslint-disable-next-line @typescript-eslint/no-explicit-any - [key: string]: any - } -} + [key: string]: any; + }; +}; diff --git a/packages/core-types/src/Types.ts b/packages/core-types/src/Types.ts index 90f7512d0..529102c99 100644 --- a/packages/core-types/src/Types.ts +++ b/packages/core-types/src/Types.ts @@ -1,27 +1,27 @@ -import { BigNumberish, BytesLike } from 'ethers' +import { BigNumberish, BytesLike } from "ethers"; -export type SmartAccountVersion = '1.0.1' | '1.0.0' | '1.0.2' +export type SmartAccountVersion = "1.0.1" | "1.0.0" | "1.0.2"; export type Transaction = { - to: string - value?: BigNumberish - data?: string -} + to: string; + value?: BigNumberish; + data?: string; +}; export type UserOperation = { - sender: string - nonce: BigNumberish - initCode: BytesLike - callData: BytesLike - callGasLimit: BigNumberish - verificationGasLimit: BigNumberish - preVerificationGas: BigNumberish - maxFeePerGas: BigNumberish - maxPriorityFeePerGas: BigNumberish - paymasterAndData: BytesLike - signature: BytesLike -} + sender: string; + nonce: BigNumberish; + initCode: BytesLike; + callData: BytesLike; + callGasLimit: BigNumberish; + verificationGasLimit: BigNumberish; + preVerificationGas: BigNumberish; + maxFeePerGas: BigNumberish; + maxPriorityFeePerGas: BigNumberish; + paymasterAndData: BytesLike; + signature: BytesLike; +}; export enum SmartAccountType { - BICONOMY + BICONOMY, } diff --git a/packages/core-types/src/index.ts b/packages/core-types/src/index.ts index 8daec190e..dffce0c18 100644 --- a/packages/core-types/src/index.ts +++ b/packages/core-types/src/index.ts @@ -1,2 +1,2 @@ -export * from './Types' -export * from './ChainsTypes' +export * from "./Types"; +export * from "./ChainsTypes"; diff --git a/packages/core-types/tests/core-types.spec.ts b/packages/core-types/tests/core-types.spec.ts index efbe0face..3f9a6a4bb 100644 --- a/packages/core-types/tests/core-types.spec.ts +++ b/packages/core-types/tests/core-types.spec.ts @@ -1,6 +1,5 @@ -describe('Core Types Tests', () => { - it('should have a basic test', () => { - expect(true).toBe(true); - }); +describe("Core Types Tests", () => { + it("should have a basic test", () => { + expect(true).toBe(true); }); - \ No newline at end of file +}); diff --git a/packages/node-client/CHANGELOG.md b/packages/node-client/CHANGELOG.md index 097a81214..b24e05ebe 100644 --- a/packages/node-client/CHANGELOG.md +++ b/packages/node-client/CHANGELOG.md @@ -5,37 +5,23 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline # 3.0.0 (2023-08-28) - - - ## 3.0.0-alpha.0 (2023-07-12) - - - - ## 2.0.1 (2023-05-18) - ### Features -* skipEstimation flag for gas ([487f3ae](https://github.com/bcnmy/biconomy-client-sdk/commit/487f3aefe21b2dd4fd46e18bef7168eae3c1ecc1)) - - +- skipEstimation flag for gas ([487f3ae](https://github.com/bcnmy/biconomy-client-sdk/commit/487f3aefe21b2dd4fd46e18bef7168eae3c1ecc1)) ## 2.0.0 (2023-04-07) - ### Bug Fixes -* backend contract address ([e81188d](https://github.com/bcnmy/biconomy-client-sdk/commit/e81188d454eb42ab581078d218d86571d724fa2d)) -* smart account response type ([f457f79](https://github.com/bcnmy/biconomy-client-sdk/commit/f457f794e27999ccc069c4afb7eb7644e224b61e)) - - +- backend contract address ([e81188d](https://github.com/bcnmy/biconomy-client-sdk/commit/e81188d454eb42ab581078d218d86571d724fa2d)) +- smart account response type ([f457f79](https://github.com/bcnmy/biconomy-client-sdk/commit/f457f794e27999ccc069c4afb7eb7644e224b61e)) ## 1.0.0 (2023-01-03) - ### Bug Fixes -* smart account response type ([f457f79](https://github.com/bcnmy/biconomy-client-sdk/commit/f457f794e27999ccc069c4afb7eb7644e224b61e)) +- smart account response type ([f457f79](https://github.com/bcnmy/biconomy-client-sdk/commit/f457f794e27999ccc069c4afb7eb7644e224b61e)) diff --git a/packages/node-client/README.md b/packages/node-client/README.md index 4daf72a90..f77c33226 100644 --- a/packages/node-client/README.md +++ b/packages/node-client/README.md @@ -4,14 +4,13 @@ Node Client is the api client package that communicate with [Biconomy SDK](https://github.com/bcnmy/biconomy-client-sdk) backend node to fetch needed smart contract wallet data i.e supported chains list, transaction history, balances e.t.c - ## Installation -```yarn add @biconomy/node-client``` +`yarn add @biconomy/node-client` OR -```npm install @biconomy/node-client ``` +`npm install @biconomy/node-client ` ## Usage @@ -48,7 +47,6 @@ const trxDetail = await nodeClient.getTransactionByHash(txHash) console.log('trxDetail ', trxDetail) ``` - # Get Smart Contract Wallet Balances ``` @@ -68,7 +66,7 @@ const balanceParams: BalancesDto = // If empty string you receive balances of all tokens watched by Indexer // you can only whitelist token addresses that are listed in token respository // specified above ^ - tokenAddresses: [], + tokenAddresses: [], }; const balFromSdk = await nodeClient.getAlltokenBalances(balanceParams); @@ -76,4 +74,4 @@ console.info("balFromSdk ", balFromSdk); const usdBalFromSdk = await nodeClient.getTotalBalanceInUsd(balanceParams); console.info("usdBalFromSdk ", usdBalFromSdk) -``` \ No newline at end of file +``` diff --git a/packages/node-client/package.json b/packages/node-client/package.json index 00528d813..cfac5e97f 100644 --- a/packages/node-client/package.json +++ b/packages/node-client/package.json @@ -19,7 +19,7 @@ "test:file": "jest --config=../../jest.config.js --runInBand", "test:concurrently": "concurrently -k --success first 'yarn start:ganache > /dev/null'", "start:ganache": "ganache -m 'direct buyer cliff train rice spirit census refuse glare expire innocent quote'" - }, + }, "author": "Biconomy (https://biconomy.io)", "license": "MIT", "files": [ diff --git a/packages/node-client/src/INodeClient.ts b/packages/node-client/src/INodeClient.ts index b1216b1fd..cdf0d9214 100644 --- a/packages/node-client/src/INodeClient.ts +++ b/packages/node-client/src/INodeClient.ts @@ -12,8 +12,8 @@ import { BalancesDto, UsdBalanceResponse, SCWTransactionResponse, - WhiteListSignatureResponse -} from './types/NodeClientTypes' + WhiteListSignatureResponse, +} from "./types/NodeClientTypes"; interface INodeClient { // 1. Chain Apis @@ -21,13 +21,13 @@ interface INodeClient { /** * Get all supported chains by backend node configuration */ - getAllSupportedChains(): Promise + getAllSupportedChains(): Promise; /** * Get ChainConfig for requested chainId * @param chainId */ - getChainById(chainId: number): Promise + getChainById(chainId: number): Promise; // 2. Token APIs @@ -35,27 +35,25 @@ interface INodeClient { * Get prices for configured tokens from backend node API * @param chainId */ - getTokenPricesByChainId(chainId: number): Promise + getTokenPricesByChainId(chainId: number): Promise; /** * Get all supported tokens */ // review - getAllTokens(): Promise + getAllTokens(): Promise; /** * Get TokenInfo for requested chainId * @param chainId */ - getTokensByChainId(chainId: number): Promise + getTokensByChainId(chainId: number): Promise; /** * Get TokenInfo by address and chainId * @param tokenByChainIdAndAddressDto */ - getTokenByChainIdAndAddress( - tokenByChainIdAndAddressDto: TokenByChainIdAndAddressDto - ): Promise + getTokenByChainIdAndAddress(tokenByChainIdAndAddressDto: TokenByChainIdAndAddressDto): Promise; // 3. Smart Account Endpoints @@ -63,9 +61,7 @@ interface INodeClient { * Get information of all smart accounts deployed for particular eoa owner for any version and index * @param smartAccountByOwnerDto */ - getSmartAccountsByOwner( - smartAccountByOwnerDto: SmartAccountByOwnerDto - ): Promise + getSmartAccountsByOwner(smartAccountByOwnerDto: SmartAccountByOwnerDto): Promise; // 4. Balances Endpoints @@ -74,13 +70,13 @@ interface INodeClient { * address could be EOA or SmartAccount * @param balancesDto */ - getAllTokenBalances(balancesDto: BalancesDto): Promise + getAllTokenBalances(balancesDto: BalancesDto): Promise; /** * * @param balancesDto Get total USD balance */ - getTotalBalanceInUsd(balancesDto: BalancesDto): Promise + getTotalBalanceInUsd(balancesDto: BalancesDto): Promise; /** * @@ -88,11 +84,11 @@ interface INodeClient { * About: Whitelist domain by passing the origin domain * Purpose: Returns the signature used in init */ - whitelistUrl(origin: string): Promise + whitelistUrl(origin: string): Promise; - getTransactionByHash(txHash: string): Promise + getTransactionByHash(txHash: string): Promise; - getTransactionByAddress(chainId: number, address: string): Promise + getTransactionByAddress(chainId: number, address: string): Promise; } -export default INodeClient +export default INodeClient; diff --git a/packages/node-client/src/NodeClient.ts b/packages/node-client/src/NodeClient.ts index f658a4b8e..a2df00662 100644 --- a/packages/node-client/src/NodeClient.ts +++ b/packages/node-client/src/NodeClient.ts @@ -1,4 +1,4 @@ -import INodeClient from './INodeClient' +import INodeClient from "./INodeClient"; import { SmartAccountByOwnerDto, TokenByChainIdAndAddressDto, @@ -12,20 +12,20 @@ import { BalancesResponse, UsdBalanceResponse, SCWTransactionResponse, - WhiteListSignatureResponse -} from './types/NodeClientTypes' -import { getTxServiceBaseUrl } from './utils' -import { HttpMethod, sendRequest } from './utils/HttpRequests' + WhiteListSignatureResponse, +} from "./types/NodeClientTypes"; +import { getTxServiceBaseUrl } from "./utils"; +import { HttpMethod, sendRequest } from "./utils/HttpRequests"; export interface NodeClientConfig { /** txServiceUrl - Safe Transaction Service URL */ - txServiceUrl: string + txServiceUrl: string; } class NodeClient implements INodeClient { - #txServiceBaseUrl: string + #txServiceBaseUrl: string; constructor({ txServiceUrl }: NodeClientConfig) { - this.#txServiceBaseUrl = getTxServiceBaseUrl(txServiceUrl) + this.#txServiceBaseUrl = getTxServiceBaseUrl(txServiceUrl); } /** @@ -35,9 +35,10 @@ class NodeClient implements INodeClient { async getAllSupportedChains(): Promise { return sendRequest({ url: `${this.#txServiceBaseUrl}/chains/`, - method: HttpMethod.Get - }) + method: HttpMethod.Get, + }); } + /** * * @param chainId @@ -47,8 +48,8 @@ class NodeClient implements INodeClient { async getChainById(chainId: number): Promise { return sendRequest({ url: `${this.#txServiceBaseUrl}/chains/${chainId}`, - method: HttpMethod.Get - }) + method: HttpMethod.Get, + }); } /** @@ -60,60 +61,54 @@ class NodeClient implements INodeClient { async getTokenPricesByChainId(chainId: number): Promise { return sendRequest({ url: `${this.#txServiceBaseUrl}/chains/chainId/${chainId}/price`, - method: HttpMethod.Get - }) + method: HttpMethod.Get, + }); } async getAllTokens(): Promise { return sendRequest({ url: `${this.#txServiceBaseUrl}/tokens/`, - method: HttpMethod.Get - }) + method: HttpMethod.Get, + }); } async getTokensByChainId(chainId: number): Promise { return sendRequest({ url: `${this.#txServiceBaseUrl}/tokens/chainId/${chainId}`, - method: HttpMethod.Get - }) + method: HttpMethod.Get, + }); } - async getTokenByChainIdAndAddress( - tokenByChainIdAndAddressDto: TokenByChainIdAndAddressDto - ): Promise { - const { chainId, tokenAddress } = tokenByChainIdAndAddressDto + async getTokenByChainIdAndAddress(tokenByChainIdAndAddressDto: TokenByChainIdAndAddressDto): Promise { + const { chainId, tokenAddress } = tokenByChainIdAndAddressDto; return sendRequest({ url: `${this.#txServiceBaseUrl}/tokens/chainId/${chainId}/address/${tokenAddress}`, - method: HttpMethod.Get - }) + method: HttpMethod.Get, + }); } - async getSmartAccountsByOwner( - smartAccountByOwnerDto: SmartAccountByOwnerDto - ): Promise { - const { chainId, owner, index } = smartAccountByOwnerDto + async getSmartAccountsByOwner(smartAccountByOwnerDto: SmartAccountByOwnerDto): Promise { + const { chainId, owner, index } = smartAccountByOwnerDto; return sendRequest({ - url: `${ - this.#txServiceBaseUrl - }/smart-accounts/chainId/${chainId}/owner/${owner}/index/${index}`, - method: HttpMethod.Get - }) + url: `${this.#txServiceBaseUrl}/smart-accounts/chainId/${chainId}/owner/${owner}/index/${index}`, + method: HttpMethod.Get, + }); } async getAllTokenBalances(balancesDto: BalancesDto): Promise { return sendRequest({ url: `${this.#txServiceBaseUrl}/smart-accounts/balances`, method: HttpMethod.Post, - body: balancesDto - }) + body: balancesDto, + }); } async getTotalBalanceInUsd(balancesDto: BalancesDto): Promise { return sendRequest({ url: `${this.#txServiceBaseUrl}/smart-accounts/balance`, method: HttpMethod.Post, - body: balancesDto - }) + body: balancesDto, + }); } /** @@ -127,24 +122,24 @@ class NodeClient implements INodeClient { url: `${this.#txServiceBaseUrl}/whitelist`, method: HttpMethod.Post, body: { - origin - } - }) + origin, + }, + }); } getTransactionByAddress(chainId: number, address: string): Promise { return sendRequest({ url: `${this.#txServiceBaseUrl}/transactions/chainId/${chainId}/address/${address}`, - method: HttpMethod.Get - }) + method: HttpMethod.Get, + }); } getTransactionByHash(txHash: string): Promise { return sendRequest({ url: `${this.#txServiceBaseUrl}/transactions/txHash/${txHash}`, - method: HttpMethod.Get - }) + method: HttpMethod.Get, + }); } } -export default NodeClient +export default NodeClient; diff --git a/packages/node-client/src/index.ts b/packages/node-client/src/index.ts index a332b2f1c..708fd7c83 100644 --- a/packages/node-client/src/index.ts +++ b/packages/node-client/src/index.ts @@ -1,5 +1,5 @@ -import NodeClient, { NodeClientConfig } from './NodeClient' +import NodeClient, { NodeClientConfig } from "./NodeClient"; -export * from './types/NodeClientTypes' -export default NodeClient -export { NodeClientConfig } +export * from "./types/NodeClientTypes"; +export default NodeClient; +export { NodeClientConfig }; diff --git a/packages/node-client/src/types/NodeClientTypes.ts b/packages/node-client/src/types/NodeClientTypes.ts index fffcd1de1..f105883dd 100644 --- a/packages/node-client/src/types/NodeClientTypes.ts +++ b/packages/node-client/src/types/NodeClientTypes.ts @@ -1,225 +1,225 @@ -import { ChainId, SmartAccountVersion } from '@biconomy/core-types' +import { ChainId, SmartAccountVersion } from "@biconomy/core-types"; export type SmartAccountInfoResponse = { - readonly name: string - readonly version: string - readonly api_version: string - readonly secure: boolean + readonly name: string; + readonly version: string; + readonly api_version: string; + readonly secure: boolean; readonly settings: { - readonly AWS_CONFIGURED: boolean - readonly AWS_S3_CUSTOM_DOMAIN: string - readonly ETHEREUM_NODE_URL: string - readonly ETHEREUM_TRACING_NODE_URL: string - readonly ETH_INTERNAL_TXS_BLOCK_PROCESS_LIMIT: number - readonly ETH_INTERNAL_NO_FILTER: boolean - readonly ETH_REORG_BLOCKS: number - readonly TOKENS_LOGO_BASE_URI: string - readonly TOKENS_LOGO_EXTENSION: string - } -} + readonly AWS_CONFIGURED: boolean; + readonly AWS_S3_CUSTOM_DOMAIN: string; + readonly ETHEREUM_NODE_URL: string; + readonly ETHEREUM_TRACING_NODE_URL: string; + readonly ETH_INTERNAL_TXS_BLOCK_PROCESS_LIMIT: number; + readonly ETH_INTERNAL_NO_FILTER: boolean; + readonly ETH_REORG_BLOCKS: number; + readonly TOKENS_LOGO_BASE_URI: string; + readonly TOKENS_LOGO_EXTENSION: string; + }; +}; // Review export type SCWTransactionResponse = { - symbol: string - tokenAddress: string - scwAddress: string - txHash: string - blockNumber: number - payment: number - gasLimit: number - gasUsage: number - gasPrice: number - chainId: number - fromAddress: string - toAddress: string - amount: number - type: string - txStatus: string - createdAt: number - updatedAt: number -} + symbol: string; + tokenAddress: string; + scwAddress: string; + txHash: string; + blockNumber: number; + payment: number; + gasLimit: number; + gasUsage: number; + gasPrice: number; + chainId: number; + fromAddress: string; + toAddress: string; + amount: number; + type: string; + txStatus: string; + createdAt: number; + updatedAt: number; +}; export type BalancesDto = { - chainId: number - eoaAddress: string - tokenAddresses: string[] -} + chainId: number; + eoaAddress: string; + tokenAddresses: string[]; +}; export type WhiteListSignatureResponse = { - code: number - message: string - data: string -} + code: number; + message: string; + data: string; +}; export type SmartAccountByOwnerDto = { - chainId: number - owner: string - index: number -} + chainId: number; + owner: string; + index: number; +}; export type TokenByChainIdAndAddressDto = { - chainId: number - tokenAddress: string -} + chainId: number; + tokenAddress: string; +}; export type ContractDetails = { - version: SmartAccountVersion + version: SmartAccountVersion; - address: string + address: string; - abi: string -} + abi: string; +}; export type ChainConfig = { - chainId: ChainId - name: string - symbol: string - isL2: boolean - isMainnet: boolean - description: string - blockExplorerUriTemplate: BlockExplorerConfig - ensRegistryAddress: string - walletFactory: ContractDetails[] - multiSend: ContractDetails[] - multiSendCall: ContractDetails[] - wallet: ContractDetails[] // base wallet - entryPoint: ContractDetails[] //should make this address var - fallBackHandler: ContractDetails[] //should make this address var - fallBackGasTankAddress: string - relayerURL: string - providerUrl: string - indexerUrl: string - backendNodeUrl: string - createdAt: Date - updatedAt: Date - token: TokenInfo -} + chainId: ChainId; + name: string; + symbol: string; + isL2: boolean; + isMainnet: boolean; + description: string; + blockExplorerUriTemplate: BlockExplorerConfig; + ensRegistryAddress: string; + walletFactory: ContractDetails[]; + multiSend: ContractDetails[]; + multiSendCall: ContractDetails[]; + wallet: ContractDetails[]; // base wallet + entryPoint: ContractDetails[]; //should make this address var + fallBackHandler: ContractDetails[]; //should make this address var + fallBackGasTankAddress: string; + relayerURL: string; + providerUrl: string; + indexerUrl: string; + backendNodeUrl: string; + createdAt: Date; + updatedAt: Date; + token: TokenInfo; +}; export type MasterCopyResponse = { - address: string - version: string - deployer: string - deployedBlockNumber: number - lastIndexedBlockNumber: number -} + address: string; + version: string; + deployer: string; + deployedBlockNumber: number; + lastIndexedBlockNumber: number; +}; export type SafeInfoResponse = { - readonly address: string - readonly nonce: number - readonly threshold: number - readonly owners: string[] - readonly masterCopy: string - readonly modules: string[] - readonly fallbackHandler: string - readonly version: string -} + readonly address: string; + readonly nonce: number; + readonly threshold: number; + readonly owners: string[]; + readonly masterCopy: string; + readonly modules: string[]; + readonly fallbackHandler: string; + readonly version: string; +}; export type BlockExplorerConfig = { - address: string - txHash: string - api: string -} + address: string; + txHash: string; + api: string; +}; export type TokenInfo = { - id: number - name: string - symbol: string - blockChain: number - ercType?: string - decimals: number - logoUri: string - address: string - isNativeToken: boolean - isEnabled: boolean - cmcId: number //Verify - price: number //Verify - createdAt: Date - updatedAt: Date -} + id: number; + name: string; + symbol: string; + blockChain: number; + ercType?: string; + decimals: number; + logoUri: string; + address: string; + isNativeToken: boolean; + isEnabled: boolean; + cmcId: number; //Verify + price: number; //Verify + createdAt: Date; + updatedAt: Date; +}; export type ISmartAccount = { - version: SmartAccountVersion - smartAccountAddress: string - isDeployed: boolean - chainId: ChainId - eoaAddress: string - entryPointAddress: string - handlerAddress: string - index: number - implementationAddress: string - fallBackHandlerAddress: string - owner: string - factoryAddress: string - createdAt: number - updatedAt: number -} + version: SmartAccountVersion; + smartAccountAddress: string; + isDeployed: boolean; + chainId: ChainId; + eoaAddress: string; + entryPointAddress: string; + handlerAddress: string; + index: number; + implementationAddress: string; + fallBackHandlerAddress: string; + owner: string; + factoryAddress: string; + createdAt: number; + updatedAt: number; +}; export type IBalances = { - contract_decimals: number - contract_name: string - contract_ticker_symbol: string - contract_address: string - supports_erc: string | null - logo_url: string | null - last_transferred_at: string | null - type: string - balance: number - balance_24h: number - quote_rate: number - quote_rate_24h: number - nft_data: string | null -} + contract_decimals: number; + contract_name: string; + contract_ticker_symbol: string; + contract_address: string; + supports_erc: string | null; + logo_url: string | null; + last_transferred_at: string | null; + type: string; + balance: number; + balance_24h: number; + quote_rate: number; + quote_rate_24h: number; + nft_data: string | null; +}; export type SupportedChainsResponse = { - message: string - code: number - data: ChainConfig[] -} + message: string; + code: number; + data: ChainConfig[]; +}; export type IndividualChainResponse = { - message: string - code: number - data: ChainConfig -} + message: string; + code: number; + data: ChainConfig; +}; export type TokenPriceResponse = { - price: number -} + price: number; +}; export type SupportedTokensResponse = { - message: string - code: number - data: TokenInfo[] -} + message: string; + code: number; + data: TokenInfo[]; +}; export type IndividualTokenResponse = { - message: string - code: number - data: TokenInfo -} + message: string; + code: number; + data: TokenInfo; +}; export type SmartAccountsResponse = { - message: string - code: number - data: ISmartAccount[] -} + message: string; + code: number; + data: ISmartAccount[]; +}; export type BalancesResponse = { - message: string - code: number - data: IBalances[] -} + message: string; + code: number; + data: IBalances[]; +}; export type UsdBalanceResponse = { - message: string - code: number + message: string; + code: number; data: { - totalBalance: number - } -} + totalBalance: number; + }; +}; export type EstimateGasResponse = { - message: string - code: number + message: string; + code: number; data: { - gas: number - txBaseGas?: number - } -} + gas: number; + txBaseGas?: number; + }; +}; diff --git a/packages/node-client/src/utils/HttpRequests.ts b/packages/node-client/src/utils/HttpRequests.ts index 6e6c79fad..49cbb7340 100644 --- a/packages/node-client/src/utils/HttpRequests.ts +++ b/packages/node-client/src/utils/HttpRequests.ts @@ -1,63 +1,63 @@ -import fetch from 'node-fetch' +import fetch from "node-fetch"; export enum HttpMethod { - Get = 'get', - Post = 'post', - Delete = 'delete' + Get = "get", + Post = "post", + Delete = "delete", } /* eslint-disable @typescript-eslint/no-explicit-any */ interface HttpRequest { - url: string - method: HttpMethod - body?: Record + url: string; + method: HttpMethod; + body?: Record; } export async function sendRequest({ url, method, body }: HttpRequest): Promise { const response = await fetch(url, { method, headers: { - Accept: 'application/json', - 'Content-Type': 'application/json' + Accept: "application/json", + "Content-Type": "application/json", }, - body: JSON.stringify(body) - }) + body: JSON.stringify(body), + }); - let jsonResponse + let jsonResponse; try { - jsonResponse = await response.json() + jsonResponse = await response.json(); } catch (error) { if (!response.ok) { - throw new Error(response.statusText) + throw new Error(response.statusText); } } if (response.ok) { - return jsonResponse as T + return jsonResponse as T; } if (jsonResponse.error) { - throw new Error(jsonResponse.error) + throw new Error(jsonResponse.error); } if (jsonResponse.message) { - throw new Error(jsonResponse.message) + throw new Error(jsonResponse.message); } if (jsonResponse.msg) { - throw new Error(jsonResponse.msg) + throw new Error(jsonResponse.msg); } if (jsonResponse.data) { - throw new Error(jsonResponse.data) + throw new Error(jsonResponse.data); } if (jsonResponse.detail) { - throw new Error(jsonResponse.detail) + throw new Error(jsonResponse.detail); } if (jsonResponse.message) { - throw new Error(jsonResponse.message) + throw new Error(jsonResponse.message); } if (jsonResponse.nonFieldErrors) { - throw new Error(jsonResponse.nonFieldErrors) + throw new Error(jsonResponse.nonFieldErrors); } if (jsonResponse.delegate) { - throw new Error(jsonResponse.delegate) + throw new Error(jsonResponse.delegate); } - throw new Error(response.statusText) + throw new Error(response.statusText); } diff --git a/packages/node-client/src/utils/index.ts b/packages/node-client/src/utils/index.ts index d1017f5a3..94b8829fe 100644 --- a/packages/node-client/src/utils/index.ts +++ b/packages/node-client/src/utils/index.ts @@ -1,3 +1,3 @@ export function getTxServiceBaseUrl(txServiceUrl: string): string { - return `${txServiceUrl}` + return `${txServiceUrl}`; } diff --git a/packages/node-client/tests/node-client.spec.ts b/packages/node-client/tests/node-client.spec.ts index 14492cdd4..7a3fd84a6 100644 --- a/packages/node-client/tests/node-client.spec.ts +++ b/packages/node-client/tests/node-client.spec.ts @@ -1,6 +1,6 @@ -import { Signer as AbstractSigner } from 'ethers'; -import { Web3Provider } from '@ethersproject/providers'; -import NodeClient from '../dist/src'; +import { Signer as AbstractSigner } from "ethers"; +import { Web3Provider } from "@ethersproject/providers"; +import NodeClient from "../dist/src"; // import { EstimateRequiredTxGasDto } from '../src/types/NodeClientTypes' @@ -10,21 +10,18 @@ type EthereumInstance = { signer?: AbstractSigner; }; - -describe('Node Client tests', function () { - const ethnode: EthereumInstance = {} - let nodeClient: NodeClient - let gasUsed: number +describe("Node Client tests", function () { + const ethnode: EthereumInstance = {}; + let nodeClient: NodeClient; + let gasUsed: number; // TODO: Add test cases for other environments (QA, DEV) beforeAll(async () => { - nodeClient = new NodeClient({ txServiceUrl: 'https://sdk-backend.staging.biconomy.io/v1' }) + nodeClient = new NodeClient({ txServiceUrl: "https://sdk-backend.staging.biconomy.io/v1" }); }); - describe('Gas Estimation Endpoints', () => { - it("Empty test to remove warning", () => { - - }); + describe("Gas Estimation Endpoints", () => { + it("Empty test to remove warning", () => {}); // it('Should estimateRequiredTxGas accurately', async () => { // // Wallet - deployed, Tx - approve USDC + Hyphen LP token // // Multisend - 0xcc8386d4b97515b75a76afea0604b0f7ca055eaf @@ -92,5 +89,5 @@ describe('Node Client tests', function () { // console.log(response) // expect(response.code).to.be.equal(200) // }) - }) -}) + }); +}); diff --git a/packages/particle-auth/CHANGELOG.md b/packages/particle-auth/CHANGELOG.md index 51e115db6..819c8f084 100644 --- a/packages/particle-auth/CHANGELOG.md +++ b/packages/particle-auth/CHANGELOG.md @@ -5,30 +5,20 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline # 3.0.0 (2023-08-28) - ### Features -* particle auth integration ([7b8fb1d](https://github.com/bcnmy/biconomy-client-sdk/commit/7b8fb1d05e3cc0196bc15806fa48100701af181e)) - - - - +- particle auth integration ([7b8fb1d](https://github.com/bcnmy/biconomy-client-sdk/commit/7b8fb1d05e3cc0196bc15806fa48100701af181e)) ## 3.0.0-alpha.0 (2023-07-12) - - - - ## 2.0.1 (2023-06-10) - ### Bug Fixes -* typo ([0a63ff1](https://github.com/bcnmy/biconomy-client-sdk/commit/0a63ff17bb38b1bc2fd68669b74c2efd5a959d31)) - +- typo ([0a63ff1](https://github.com/bcnmy/biconomy-client-sdk/commit/0a63ff17bb38b1bc2fd68669b74c2efd5a959d31)) ## 2.0.0 (2023-30-05) ### Features -* particle-auth ([7b8fb1d](https://github.com/bcnmy/biconomy-client-sdk/commit/7b8fb1d05e3cc0196bc15806fa48100701af181e)) + +- particle-auth ([7b8fb1d](https://github.com/bcnmy/biconomy-client-sdk/commit/7b8fb1d05e3cc0196bc15806fa48100701af181e)) diff --git a/packages/particle-auth/README.md b/packages/particle-auth/README.md index b167b8bdc..fabfcc5dc 100644 --- a/packages/particle-auth/README.md +++ b/packages/particle-auth/README.md @@ -15,20 +15,24 @@ const particle = new ParticleNetwork({ appId: "xx", chainName: "Ethereum", //optional: current chain name, default Ethereum. chainId: 1, //optional: current chain id, default 1. - wallet: { //optional: by default, the wallet entry is displayed in the bottom right corner of the webpage. - displayWalletEntry: true, //show wallet entry when connect particle. + wallet: { + //optional: by default, the wallet entry is displayed in the bottom right corner of the webpage. + displayWalletEntry: true, //show wallet entry when connect particle. defaultWalletEntryPosition: WalletEntryPosition.BR, //wallet entry position - uiMode: "dark", //optional: light or dark, if not set, the default is the same as web auth. - supportChains: [{ id: 1, name: "Ethereum"}, { id: 5, name: "Ethereum"}], // optional: web wallet support chains. + uiMode: "dark", //optional: light or dark, if not set, the default is the same as web auth. + supportChains: [ + { id: 1, name: "Ethereum" }, + { id: 5, name: "Ethereum" }, + ], // optional: web wallet support chains. customStyle: {}, //optional: custom wallet style - } + }, }); const particleProvider = new ParticleProvider(particle.auth); //if you use web3.js window.web3 = new Web3(particleProvider); -window.web3.currentProvider.isParticleNetwork // => true +window.web3.currentProvider.isParticleNetwork; // => true //if you use ethers.js import { ethers } from "ethers"; diff --git a/packages/particle-auth/src/index.ts b/packages/particle-auth/src/index.ts index fd073876e..1d3b6a0ff 100644 --- a/packages/particle-auth/src/index.ts +++ b/packages/particle-auth/src/index.ts @@ -1,10 +1,5 @@ -import * as ParticleAuth from '@particle-network/auth' -import * as BiconomyAccount from '@particle-network/biconomy' -import { ParticleProvider, ParticleDelegateProvider } from '@particle-network/provider' +import * as ParticleAuth from "@particle-network/auth"; +import * as BiconomyAccount from "@particle-network/biconomy"; +import { ParticleProvider, ParticleDelegateProvider } from "@particle-network/provider"; -export { - ParticleAuth as ParticleAuthModule, - BiconomyAccount as BiconomyAccountModule, - ParticleProvider, - ParticleDelegateProvider -} +export { ParticleAuth as ParticleAuthModule, BiconomyAccount as BiconomyAccountModule, ParticleProvider, ParticleDelegateProvider }; diff --git a/packages/particle-auth/tests/particle-auth.spec.ts b/packages/particle-auth/tests/particle-auth.spec.ts index db61fac7e..97866f6b6 100644 --- a/packages/particle-auth/tests/particle-auth.spec.ts +++ b/packages/particle-auth/tests/particle-auth.spec.ts @@ -1,6 +1,5 @@ -describe('Particle Auth Tests', () => { - it('should have a basic test', () => { - expect(true).toBe(true); - }); +describe("Particle Auth Tests", () => { + it("should have a basic test", () => { + expect(true).toBe(true); }); - \ No newline at end of file +}); diff --git a/packages/particle-auth/tsconfig.json b/packages/particle-auth/tsconfig.json index 2a945f000..3dc5293ed 100644 --- a/packages/particle-auth/tsconfig.json +++ b/packages/particle-auth/tsconfig.json @@ -5,10 +5,7 @@ "outDir": "dist", "baseUrl": "src", "resolveJsonModule": true, - "esModuleInterop": true, + "esModuleInterop": true }, - "include": [ - "src", - "src/**/*.json" - ] -} \ No newline at end of file + "include": ["src", "src/**/*.json"] +} diff --git a/packages/paymaster/CHANGELOG.md b/packages/paymaster/CHANGELOG.md index 3080fe39e..137e7a3d1 100644 --- a/packages/paymaster/CHANGELOG.md +++ b/packages/paymaster/CHANGELOG.md @@ -7,37 +7,30 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline Modular SDK - consists stable version of below updates done in Alphas. - - ## 3.0.0-alpha.0 (2023-08-02) ### Features -* letting maxFee and maxPriority not be undefined([46b985c](https://github.com/bcnmy/biconomy-client-sdk/commit/46b985c75fd135f151c9ac4380a65438cccc6f39)) -* passing on paymasterAndData([ae267f1])(https://github.com/bcnmy/biconomy-client-sdk/commit/ae267f1a103f37856eb233a38db7063bfcc4cb45) -* handle undefined values([e53d4a7])(https://github.com/bcnmy/biconomy-client-sdk/commit/e53d4a78aded8c8802786173daf12b27d445d4a0) -* handling userOp null values([c89ac42])(https://github.com/bcnmy/biconomy-client-sdk/commit/c89ac42ae1d7fd985ef2396d925cc63ec5cf926b) -* using signature provided by userop([0c40641])(https://github.com/bcnmy/biconomy-client-sdk/commit/0c40641e4cd6133f7348bb3e3022f8ab78fe299b) - - +- letting maxFee and maxPriority not be undefined([46b985c](https://github.com/bcnmy/biconomy-client-sdk/commit/46b985c75fd135f151c9ac4380a65438cccc6f39)) +- passing on paymasterAndData([ae267f1])(https://github.com/bcnmy/biconomy-client-sdk/commit/ae267f1a103f37856eb233a38db7063bfcc4cb45) +- handle undefined values([e53d4a7])(https://github.com/bcnmy/biconomy-client-sdk/commit/e53d4a78aded8c8802786173daf12b27d445d4a0) +- handling userOp null values([c89ac42])(https://github.com/bcnmy/biconomy-client-sdk/commit/c89ac42ae1d7fd985ef2396d925cc63ec5cf926b) +- using signature provided by userop([0c40641])(https://github.com/bcnmy/biconomy-client-sdk/commit/0c40641e4cd6133f7348bb3e3022f8ab78fe299b) # 3.1.0-alpha.0 (2023-07-24) VERSION bump only - ## 3.0.0-alpha.0 (2023-07-12) - ### Bug Fixes -* linting ([563befe](https://github.com/bcnmy/biconomy-client-sdk/commit/563befedcc37aee4c531e01809b47e559a33f526)) -* linting ([d2f5f1a](https://github.com/bcnmy/biconomy-client-sdk/commit/d2f5f1afadc2a561c4ef01c0821a25b9d7fe776e)) - +- linting ([563befe](https://github.com/bcnmy/biconomy-client-sdk/commit/563befedcc37aee4c531e01809b47e559a33f526)) +- linting ([d2f5f1a](https://github.com/bcnmy/biconomy-client-sdk/commit/d2f5f1afadc2a561c4ef01c0821a25b9d7fe776e)) ### Features -* covert gas limits to numbers for making pm service call ([b1fe96f](https://github.com/bcnmy/biconomy-client-sdk/commit/b1fe96f7a312ceaf7aa689939b7c69718c710dd1)) -* get fee quote or data method in biconomy paymaster ([47748a6](https://github.com/bcnmy/biconomy-client-sdk/commit/47748a6384c2b74e1d9be4d570554098e1ac02e7)) -* update responses to support calculateGasLimits flag + update interfaces ([55bbd38](https://github.com/bcnmy/biconomy-client-sdk/commit/55bbd38b4ef8acaf8da1d52e36846557b134aba4)) -* using hybrid paymaster interface ([5fc56a7](https://github.com/bcnmy/biconomy-client-sdk/commit/5fc56a7db2de4a3f4bb87cd4d75584e79010b206)) +- covert gas limits to numbers for making pm service call ([b1fe96f](https://github.com/bcnmy/biconomy-client-sdk/commit/b1fe96f7a312ceaf7aa689939b7c69718c710dd1)) +- get fee quote or data method in biconomy paymaster ([47748a6](https://github.com/bcnmy/biconomy-client-sdk/commit/47748a6384c2b74e1d9be4d570554098e1ac02e7)) +- update responses to support calculateGasLimits flag + update interfaces ([55bbd38](https://github.com/bcnmy/biconomy-client-sdk/commit/55bbd38b4ef8acaf8da1d52e36846557b134aba4)) +- using hybrid paymaster interface ([5fc56a7](https://github.com/bcnmy/biconomy-client-sdk/commit/5fc56a7db2de4a3f4bb87cd4d75584e79010b206)) diff --git a/packages/paymaster/Readme.md b/packages/paymaster/Readme.md index 249e4ebd9..8b91b80a7 100644 --- a/packages/paymaster/Readme.md +++ b/packages/paymaster/Readme.md @@ -22,60 +22,48 @@ yarn add @biconomy/paymaster ```typescript // This is how you create paymaster instance in your dapp's -import { IPaymaster, BiconomyPaymaster } from '@biconomy/paymaster' +import { IPaymaster, BiconomyPaymaster } from "@biconomy/paymaster"; // Currently this package only exports Biconomy Paymaster which acts as a Hybrid paymaster for gas abstraction. You can sponsor user transactions but can also make users pay gas in supported ERC20 tokens. - const paymaster = new BiconomyPaymaster({ - paymasterUrl: '' // you can get this value from biconomy dashboard. https://dashboard.biconomy.io - }) +const paymaster = new BiconomyPaymaster({ + paymasterUrl: "", // you can get this value from biconomy dashboard. https://dashboard.biconomy.io +}); ``` **paymasterUrl** you can get this value from biconomy dashboard. -Following are the methods that can be called on paymaster instance +Following are the methods that can be called on paymaster instance ```typescript export interface IHybridPaymaster extends IPaymaster { - getPaymasterAndData( - userOp: Partial, - paymasterServiceData?: T - ): Promise - buildTokenApprovalTransaction( - tokenPaymasterRequest: BiconomyTokenPaymasterRequest, - provider: Provider - ): Promise - getPaymasterFeeQuotesOrData( - userOp: Partial, - paymasterServiceData: FeeQuotesOrDataDto - ): Promise + getPaymasterAndData(userOp: Partial, paymasterServiceData?: T): Promise; + buildTokenApprovalTransaction(tokenPaymasterRequest: BiconomyTokenPaymasterRequest, provider: Provider): Promise; + getPaymasterFeeQuotesOrData(userOp: Partial, paymasterServiceData: FeeQuotesOrDataDto): Promise; } - ``` -One can also build their own Paymaster API class and submit a PR or just provide instance of it in the account package / use standalone to generate paymasterAndData -It should follow below Interface. +One can also build their own Paymaster API class and submit a PR or just provide instance of it in the account package / use standalone to generate paymasterAndData +It should follow below Interface. ```typescript export interface IPaymaster { // Implementing class may add extra parameter (for example paymasterServiceData with it's own type) in below function signature - getPaymasterAndData(userOp: Partial): Promise - getDummyPaymasterAndData(userOp: Partial): Promise + getPaymasterAndData(userOp: Partial): Promise; + getDummyPaymasterAndData(userOp: Partial): Promise; } ``` - - ### Below API methods can be used for Biconomy Hybrid paymaster **getPaymasterAndData** -This function accepts a **`Partial`** object that includes all properties of **`userOp`** except for the **`signature`** and **`paymasterAndData`** field. It returns **`paymasterAndData`** as part of the **`PaymasterAndDataResponse`** +This function accepts a **`Partial`** object that includes all properties of **`userOp`** except for the **`signature`** and **`paymasterAndData`** field. It returns **`paymasterAndData`** as part of the **`PaymasterAndDataResponse`** **buildTokenApprovalTransaction** -This function is specifically used for token paymaster sponsorship. The primary purpose of this function is to create an approve transaction for paymaster that gets batched with the rest of your transactions. +This function is specifically used for token paymaster sponsorship. The primary purpose of this function is to create an approve transaction for paymaster that gets batched with the rest of your transactions. Note: You don't need to call this function. It will automatically get called as part of the **`buildTokenPaymasterUserOp`** function call. diff --git a/packages/paymaster/package.json b/packages/paymaster/package.json index 606fa581c..406ea497a 100644 --- a/packages/paymaster/package.json +++ b/packages/paymaster/package.json @@ -22,7 +22,7 @@ "test:file": "jest --config=../../jest.config.js --runInBand", "test:concurrently": "concurrently -k --success first 'yarn start:ganache > /dev/null'", "start:ganache": "ganache -m 'direct buyer cliff train rice spirit census refuse glare expire innocent quote'" - }, + }, "author": "talhamalik883 ", "repository": { "type": "git", diff --git a/packages/paymaster/src/BiconomyPaymaster.ts b/packages/paymaster/src/BiconomyPaymaster.ts index c70594b16..cb361bb0a 100644 --- a/packages/paymaster/src/BiconomyPaymaster.ts +++ b/packages/paymaster/src/BiconomyPaymaster.ts @@ -1,7 +1,7 @@ -import { Logger, sendRequest, HttpMethod, getTimestampInSeconds } from '@biconomy/common' -import { resolveProperties } from '@ethersproject/properties' -import { UserOperation, Transaction } from '@biconomy/core-types' -import { Provider } from '@ethersproject/abstract-provider' +import { Logger, sendRequest, HttpMethod, getTimestampInSeconds } from "@biconomy/common"; +import { resolveProperties } from "@ethersproject/properties"; +import { UserOperation, Transaction } from "@biconomy/core-types"; +import { Provider } from "@ethersproject/abstract-provider"; import { PaymasterFeeQuote, PaymasterConfig, @@ -11,27 +11,28 @@ import { JsonRpcResponse, BiconomyTokenPaymasterRequest, PaymasterMode, - PaymasterAndDataResponse -} from './utils/Types' -import { BigNumberish, BigNumber, ethers } from 'ethers' -import { ERC20_ABI } from './constants' -import { IHybridPaymaster } from './interfaces/IHybridPaymaster' + PaymasterAndDataResponse, +} from "./utils/Types"; +import { BigNumberish, BigNumber, ethers } from "ethers"; +import { ERC20_ABI } from "./constants"; +import { IHybridPaymaster } from "./interfaces/IHybridPaymaster"; const defaultPaymasterConfig: PaymasterConfig = { - paymasterUrl: '', - strictMode: true // Set your desired default value for strictMode here -} + paymasterUrl: "", + strictMode: true, // Set your desired default value for strictMode here +}; /** * @dev Hybrid - Generic Gas Abstraction paymaster */ export class BiconomyPaymaster implements IHybridPaymaster { - paymasterConfig: PaymasterConfig + paymasterConfig: PaymasterConfig; + constructor(config: PaymasterConfig) { const mergedConfig: PaymasterConfig = { ...defaultPaymasterConfig, - ...config - } - this.paymasterConfig = mergedConfig + ...config, + }; + this.paymasterConfig = mergedConfig; } /** @@ -39,28 +40,26 @@ export class BiconomyPaymaster implements IHybridPaymaster - ): Promise> { + private async prepareUserOperation(userOp: Partial): Promise> { // Review - userOp = await resolveProperties(userOp) + userOp = await resolveProperties(userOp); if (userOp.nonce !== null || userOp.nonce !== undefined) { - userOp.nonce = BigNumber.from(userOp.nonce).toHexString() + userOp.nonce = BigNumber.from(userOp.nonce).toHexString(); } if (userOp.callGasLimit !== null || userOp.callGasLimit !== undefined) { - userOp.callGasLimit = BigNumber.from(userOp.callGasLimit).toString() + userOp.callGasLimit = BigNumber.from(userOp.callGasLimit).toString(); } if (userOp.verificationGasLimit !== null || userOp.verificationGasLimit !== undefined) { - userOp.verificationGasLimit = BigNumber.from(userOp.verificationGasLimit).toString() + userOp.verificationGasLimit = BigNumber.from(userOp.verificationGasLimit).toString(); } if (userOp.preVerificationGas !== null || userOp.preVerificationGas !== undefined) { - userOp.preVerificationGas = BigNumber.from(userOp.preVerificationGas).toString() + userOp.preVerificationGas = BigNumber.from(userOp.preVerificationGas).toString(); } - userOp.maxFeePerGas = BigNumber.from(userOp.maxFeePerGas).toHexString() - userOp.maxPriorityFeePerGas = BigNumber.from(userOp.maxPriorityFeePerGas).toHexString() - userOp.signature = userOp.signature || '0x' - userOp.paymasterAndData = userOp.paymasterAndData || '0x' - return userOp + userOp.maxFeePerGas = BigNumber.from(userOp.maxFeePerGas).toHexString(); + userOp.maxPriorityFeePerGas = BigNumber.from(userOp.maxPriorityFeePerGas).toHexString(); + userOp.signature = userOp.signature || "0x"; + userOp.paymasterAndData = userOp.paymasterAndData || "0x"; + return userOp; } /** @@ -69,40 +68,34 @@ export class BiconomyPaymaster implements IHybridPaymaster { - const feeTokenAddress: string = tokenPaymasterRequest.feeQuote.tokenAddress - Logger.log('erc20 fee token address ', feeTokenAddress) + async buildTokenApprovalTransaction(tokenPaymasterRequest: BiconomyTokenPaymasterRequest, provider?: Provider): Promise { + const feeTokenAddress: string = tokenPaymasterRequest.feeQuote.tokenAddress; + Logger.log("erc20 fee token address ", feeTokenAddress); - const spender = tokenPaymasterRequest.spender - Logger.log('spender address ', spender) + const spender = tokenPaymasterRequest.spender; + Logger.log("spender address ", spender); // logging provider object isProvider - Logger.log('provider object passed - is provider', provider?._isProvider) + Logger.log("provider object passed - is provider", provider?._isProvider); // TODO move below notes to separate method // Note: should also check in caller if the approval is already given, if yes return object with address or data 0 // Note: we would need userOp here to get the account/owner info to check allowance - let requiredApproval: BigNumberish = BigNumber.from(0).toString() + let requiredApproval: BigNumberish = BigNumber.from(0).toString(); if (tokenPaymasterRequest.maxApproval && tokenPaymasterRequest.maxApproval == true) { - requiredApproval = ethers.constants.MaxUint256 + requiredApproval = ethers.constants.MaxUint256; } else { - requiredApproval = Math.ceil( - tokenPaymasterRequest.feeQuote.maxGasFee * - Math.pow(10, tokenPaymasterRequest.feeQuote.decimal) - ).toString() + requiredApproval = Math.ceil(tokenPaymasterRequest.feeQuote.maxGasFee * Math.pow(10, tokenPaymasterRequest.feeQuote.decimal)).toString(); } - Logger.log('required approval for erc20 token ', requiredApproval) + Logger.log("required approval for erc20 token ", requiredApproval); - const erc20Interface = new ethers.utils.Interface(JSON.stringify(ERC20_ABI)) + const erc20Interface = new ethers.utils.Interface(JSON.stringify(ERC20_ABI)); try { - const data = erc20Interface.encodeFunctionData('approve', [spender, requiredApproval]) + const data = erc20Interface.encodeFunctionData("approve", [spender, requiredApproval]); // TODO? // Note: For some tokens we may need to set allowance to 0 first so that would return batch of transactions and changes the return type to Transaction[] @@ -118,11 +111,11 @@ export class BiconomyPaymaster implements IHybridPaymaster, - paymasterServiceData: FeeQuotesOrDataDto - ): Promise { + async getPaymasterFeeQuotesOrData(userOp: Partial, paymasterServiceData: FeeQuotesOrDataDto): Promise { try { - userOp = await this.prepareUserOperation(userOp) + userOp = await this.prepareUserOperation(userOp); } catch (err) { - Logger.log('Error in prepareUserOperation ', err) - throw err + Logger.log("Error in prepareUserOperation ", err); + throw err; } - let mode = null - let expiryDuration = null - const calculateGasLimits = paymasterServiceData.calculateGasLimits - ? paymasterServiceData.calculateGasLimits - : false - Logger.log('calculateGasLimits is ', calculateGasLimits) - let preferredToken = null - let feeTokensArray: string[] = [] + let mode = null; + let expiryDuration = null; + const calculateGasLimits = paymasterServiceData.calculateGasLimits ? paymasterServiceData.calculateGasLimits : false; + Logger.log("calculateGasLimits is ", calculateGasLimits); + let preferredToken = null; + let feeTokensArray: string[] = []; // could make below null let smartAccountInfo = { - name: 'BICONOMY', - version: '1.0.0' - } - let webhookData = null + name: "BICONOMY", + version: "1.0.0", + }; + let webhookData = null; if (paymasterServiceData.mode) { - Logger.log('Requested mode is ', paymasterServiceData.mode) - mode = paymasterServiceData.mode + Logger.log("Requested mode is ", paymasterServiceData.mode); + mode = paymasterServiceData.mode; // Validation on the mode passed / define allowed enums } if (paymasterServiceData.expiryDuration) { - Logger.log('Requested expiryDuration is ', paymasterServiceData.expiryDuration) - expiryDuration = paymasterServiceData.expiryDuration + Logger.log("Requested expiryDuration is ", paymasterServiceData.expiryDuration); + expiryDuration = paymasterServiceData.expiryDuration; } - preferredToken = paymasterServiceData?.preferredToken - ? paymasterServiceData?.preferredToken - : preferredToken + preferredToken = paymasterServiceData?.preferredToken ? paymasterServiceData?.preferredToken : preferredToken; - Logger.log('userop is ', userOp) + Logger.log("userop is ", userOp); - feeTokensArray = ( - paymasterServiceData?.tokenList?.length !== 0 - ? paymasterServiceData?.tokenList - : feeTokensArray - ) as string[] + feeTokensArray = (paymasterServiceData?.tokenList?.length !== 0 ? paymasterServiceData?.tokenList : feeTokensArray) as string[]; - webhookData = paymasterServiceData?.webhookData ?? webhookData + webhookData = paymasterServiceData?.webhookData ?? webhookData; - smartAccountInfo = paymasterServiceData?.smartAccountInfo ?? smartAccountInfo + smartAccountInfo = paymasterServiceData?.smartAccountInfo ?? smartAccountInfo; try { const response: JsonRpcResponse = await sendRequest({ url: `${this.paymasterConfig.paymasterUrl}`, method: HttpMethod.Post, body: { - method: 'pm_getFeeQuoteOrData', + method: "pm_getFeeQuoteOrData", params: [ userOp, { @@ -199,68 +181,67 @@ export class BiconomyPaymaster implements IHybridPaymaster = response.result.feeQuotes - const paymasterAddress: string = response.result.paymasterAddress + const feeQuotesResponse: Array = response.result.feeQuotes; + const paymasterAddress: string = response.result.paymasterAddress; // check all objects iterate and populate below calculation for all tokens - return { feeQuotes: feeQuotesResponse, tokenPaymasterAddress: paymasterAddress } + return { feeQuotes: feeQuotesResponse, tokenPaymasterAddress: paymasterAddress }; } else if (response.result.mode == PaymasterMode.SPONSORED) { - const paymasterAndData: string = response.result.paymasterAndData - const preVerificationGas = response.result.preVerificationGas - const verificationGasLimit = response.result.verificationGasLimit - const callGasLimit = response.result.callGasLimit + const paymasterAndData: string = response.result.paymasterAndData; + const preVerificationGas = response.result.preVerificationGas; + const verificationGasLimit = response.result.verificationGasLimit; + const callGasLimit = response.result.callGasLimit; return { paymasterAndData: paymasterAndData, preVerificationGas: preVerificationGas, verificationGasLimit: verificationGasLimit, - callGasLimit: callGasLimit - } + callGasLimit: callGasLimit, + }; } else { const errorObject = { code: 417, - message: 'Expectation Failed: Invalid mode in Paymaster service response' - } - throw errorObject + message: "Expectation Failed: Invalid mode in Paymaster service response", + }; + throw errorObject; } } } catch (error: any) { - Logger.log(error.message) - Logger.error('Failed to fetch Fee Quotes or Paymaster data - reason: ', JSON.stringify(error)) + Logger.log(error.message); + Logger.error("Failed to fetch Fee Quotes or Paymaster data - reason: ", JSON.stringify(error)); // Note: we may not throw if we include strictMode off and return paymasterData '0x'. if ( !this.paymasterConfig.strictMode && paymasterServiceData.mode == PaymasterMode.SPONSORED && - (error?.message.includes('Smart contract data not found') || - error?.message.includes('No policies were set')) + (error?.message.includes("Smart contract data not found") || error?.message.includes("No policies were set")) // can also check based on error.code being -32xxx ) { - Logger.log(`Strict mode is ${this.paymasterConfig.strictMode}. sending paymasterAndData 0x`) + Logger.log(`Strict mode is ${this.paymasterConfig.strictMode}. sending paymasterAndData 0x`); return { - paymasterAndData: '0x', + paymasterAndData: "0x", // send below values same as userOp gasLimits preVerificationGas: userOp.preVerificationGas, verificationGasLimit: userOp.verificationGasLimit, - callGasLimit: userOp.callGasLimit - } + callGasLimit: userOp.callGasLimit, + }; } - throw error + throw error; } - throw new Error('Failed to fetch feeQuote or paymaster data') + throw new Error("Failed to fetch feeQuote or paymaster data"); } /** @@ -271,52 +252,47 @@ export class BiconomyPaymaster implements IHybridPaymaster, - paymasterServiceData?: SponsorUserOperationDto // mode is necessary. partial context of token paymaster or verifying + paymasterServiceData?: SponsorUserOperationDto, // mode is necessary. partial context of token paymaster or verifying ): Promise { // TODO try { - userOp = await this.prepareUserOperation(userOp) + userOp = await this.prepareUserOperation(userOp); } catch (err) { - Logger.log('Error in prepareUserOperation ', err) - throw err + Logger.log("Error in prepareUserOperation ", err); + throw err; } if (paymasterServiceData?.mode === undefined) { - throw new Error('mode is required in paymasterServiceData') + throw new Error("mode is required in paymasterServiceData"); } - const mode = paymasterServiceData.mode - Logger.log('requested mode is ', mode) + const mode = paymasterServiceData.mode; + Logger.log("requested mode is ", mode); - const calculateGasLimits = paymasterServiceData?.calculateGasLimits - ? paymasterServiceData.calculateGasLimits - : false - Logger.log('calculateGasLimits is ', calculateGasLimits) + const calculateGasLimits = paymasterServiceData?.calculateGasLimits ? paymasterServiceData.calculateGasLimits : false; + Logger.log("calculateGasLimits is ", calculateGasLimits); - let tokenInfo = null - let expiryDuration = null + let tokenInfo = null; + let expiryDuration = null; // could make below null let smartAccountInfo = { - name: 'BICONOMY', - version: '1.0.0' - } - let webhookData = null + name: "BICONOMY", + version: "1.0.0", + }; + let webhookData = null; if (mode === PaymasterMode.ERC20) { - if ( - !paymasterServiceData?.feeTokenAddress && - paymasterServiceData?.feeTokenAddress === ethers.constants.AddressZero - ) { - throw new Error('feeTokenAddress is required and should be non-zero') + if (!paymasterServiceData?.feeTokenAddress && paymasterServiceData?.feeTokenAddress === ethers.constants.AddressZero) { + throw new Error("feeTokenAddress is required and should be non-zero"); } tokenInfo = { - feeTokenAddress: paymasterServiceData.feeTokenAddress - } + feeTokenAddress: paymasterServiceData.feeTokenAddress, + }; } - webhookData = paymasterServiceData?.webhookData ?? webhookData - smartAccountInfo = paymasterServiceData?.smartAccountInfo ?? smartAccountInfo - expiryDuration = paymasterServiceData?.expiryDuration ?? expiryDuration + webhookData = paymasterServiceData?.webhookData ?? webhookData; + smartAccountInfo = paymasterServiceData?.smartAccountInfo ?? smartAccountInfo; + expiryDuration = paymasterServiceData?.expiryDuration ?? expiryDuration; // Note: The idea is before calling this below rpc, userOp values presense and types should be in accordance with how we call eth_estimateUseropGas on the bundler @@ -325,7 +301,7 @@ export class BiconomyPaymaster implements IHybridPaymaster, - paymasterServiceData?: SponsorUserOperationDto // mode is necessary. partial context of token paymaster or verifying + paymasterServiceData?: SponsorUserOperationDto, // mode is necessary. partial context of token paymaster or verifying ): Promise { - Logger.log('userOp is ', userOp) - Logger.log('paymasterServiceData is ', paymasterServiceData) - return '0x' + Logger.log("userOp is ", userOp); + Logger.log("paymasterServiceData is ", paymasterServiceData); + return "0x"; } } diff --git a/packages/paymaster/src/constants.ts b/packages/paymaster/src/constants.ts index 90a5c7067..d0efbcfe2 100644 --- a/packages/paymaster/src/constants.ts +++ b/packages/paymaster/src/constants.ts @@ -1,11 +1,11 @@ -export const ENTRYPOINT_ADDRESS = '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789' +export const ENTRYPOINT_ADDRESS = "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; // export const ERC20_PAYMASTER_ADDRESS = '0xE9f6Ffc87cac92bc94f704AE017e85cB83DBe4EC' // likely to be same address on all chains export const ERC20_ABI = [ - 'function transfer(address to, uint256 value) external returns (bool)', - 'function transferFrom(address from, address to, uint256 value) external returns (bool)', - 'function approve(address spender, uint256 value) external returns (bool)', - 'function allowance(address owner, address spender) external view returns (uint256)', - 'function balanceOf(address owner) external view returns (uint256)' -] + "function transfer(address to, uint256 value) external returns (bool)", + "function transferFrom(address from, address to, uint256 value) external returns (bool)", + "function approve(address spender, uint256 value) external returns (bool)", + "function allowance(address owner, address spender) external view returns (uint256)", + "function balanceOf(address owner) external view returns (uint256)", +]; diff --git a/packages/paymaster/src/index.ts b/packages/paymaster/src/index.ts index 5b8b403f7..fc7dd0950 100644 --- a/packages/paymaster/src/index.ts +++ b/packages/paymaster/src/index.ts @@ -1,4 +1,4 @@ -export * from './interfaces/IPaymaster' -export * from './interfaces/IHybridPaymaster' -export * from './utils/Types' -export * from './BiconomyPaymaster' +export * from "./interfaces/IPaymaster"; +export * from "./interfaces/IHybridPaymaster"; +export * from "./utils/Types"; +export * from "./BiconomyPaymaster"; diff --git a/packages/paymaster/src/interfaces/IHybridPaymaster.ts b/packages/paymaster/src/interfaces/IHybridPaymaster.ts index 213505994..886741ef4 100644 --- a/packages/paymaster/src/interfaces/IHybridPaymaster.ts +++ b/packages/paymaster/src/interfaces/IHybridPaymaster.ts @@ -1,29 +1,12 @@ -import { UserOperation } from '@biconomy/core-types' -import { - FeeQuotesOrDataResponse, - BiconomyTokenPaymasterRequest, - FeeQuotesOrDataDto, - PaymasterAndDataResponse -} from '../utils/Types' -import { Transaction } from '@biconomy/core-types' -import { Provider } from '@ethersproject/abstract-provider' -import { IPaymaster } from './IPaymaster' +import { UserOperation } from "@biconomy/core-types"; +import { FeeQuotesOrDataResponse, BiconomyTokenPaymasterRequest, FeeQuotesOrDataDto, PaymasterAndDataResponse } from "../utils/Types"; +import { Transaction } from "@biconomy/core-types"; +import { Provider } from "@ethersproject/abstract-provider"; +import { IPaymaster } from "./IPaymaster"; export interface IHybridPaymaster extends IPaymaster { - getPaymasterAndData( - userOp: Partial, - paymasterServiceData?: T - ): Promise - getDummyPaymasterAndData( - userOp: Partial, - paymasterServiceData?: T - ): Promise - buildTokenApprovalTransaction( - tokenPaymasterRequest: BiconomyTokenPaymasterRequest, - provider: Provider - ): Promise - getPaymasterFeeQuotesOrData( - userOp: Partial, - paymasterServiceData: FeeQuotesOrDataDto - ): Promise + getPaymasterAndData(userOp: Partial, paymasterServiceData?: T): Promise; + getDummyPaymasterAndData(userOp: Partial, paymasterServiceData?: T): Promise; + buildTokenApprovalTransaction(tokenPaymasterRequest: BiconomyTokenPaymasterRequest, provider: Provider): Promise; + getPaymasterFeeQuotesOrData(userOp: Partial, paymasterServiceData: FeeQuotesOrDataDto): Promise; } diff --git a/packages/paymaster/src/interfaces/IPaymaster.ts b/packages/paymaster/src/interfaces/IPaymaster.ts index 53101c7de..354409fb7 100644 --- a/packages/paymaster/src/interfaces/IPaymaster.ts +++ b/packages/paymaster/src/interfaces/IPaymaster.ts @@ -1,8 +1,8 @@ -import { UserOperation } from '@biconomy/core-types' -import { PaymasterAndDataResponse } from '../utils/Types' +import { UserOperation } from "@biconomy/core-types"; +import { PaymasterAndDataResponse } from "../utils/Types"; export interface IPaymaster { // Implementing class may add extra parameter (for example paymasterServiceData with it's own type) in below function signature - getPaymasterAndData(userOp: Partial): Promise - getDummyPaymasterAndData(userOp: Partial): Promise + getPaymasterAndData(userOp: Partial): Promise; + getDummyPaymasterAndData(userOp: Partial): Promise; } diff --git a/packages/paymaster/src/utils/Types.ts b/packages/paymaster/src/utils/Types.ts index c4a527c1f..b73a80c13 100644 --- a/packages/paymaster/src/utils/Types.ts +++ b/packages/paymaster/src/utils/Types.ts @@ -1,118 +1,118 @@ -import { BigNumberish } from 'ethers' +import { BigNumberish } from "ethers"; export type PaymasterServiceErrorResponse = { - jsonrpc: string - id: number - error: JsonRpcError -} + jsonrpc: string; + id: number; + error: JsonRpcError; +}; // Generic /* eslint-disable @typescript-eslint/no-explicit-any */ export type JsonRpcResponse = { - jsonrpc: string - id: number - result?: any - error?: JsonRpcError -} + jsonrpc: string; + id: number; + result?: any; + error?: JsonRpcError; +}; /* eslint-disable @typescript-eslint/no-explicit-any */ export type JsonRpcError = { - code: string - message: string - data: any -} + code: string; + message: string; + data: any; +}; export type PaymasterConfig = { - paymasterUrl: string - strictMode?: boolean -} + paymasterUrl: string; + strictMode?: boolean; +}; // review types and naming convention // meant for pm_sponsorUserOperation export type SponsorUserOperationDto = { - mode: PaymasterMode - calculateGasLimits?: boolean - expiryDuration?: number + mode: PaymasterMode; + calculateGasLimits?: boolean; + expiryDuration?: number; webhookData?: { // eslint-disable-next-line @typescript-eslint/no-explicit-any - [key: string]: any - } - smartAccountInfo?: SmartAccountData - feeTokenAddress?: string -} + [key: string]: any; + }; + smartAccountInfo?: SmartAccountData; + feeTokenAddress?: string; +}; // review types and naming convention // meant for pm_getFeeQuoteOrData export type FeeQuotesOrDataDto = { - mode?: PaymasterMode - expiryDuration?: number - calculateGasLimits?: boolean - tokenList?: string[] - preferredToken?: string + mode?: PaymasterMode; + expiryDuration?: number; + calculateGasLimits?: boolean; + tokenList?: string[]; + preferredToken?: string; webhookData?: { // eslint-disable-next-line @typescript-eslint/no-explicit-any - [key: string]: any - } - smartAccountInfo?: SmartAccountData -} + [key: string]: any; + }; + smartAccountInfo?: SmartAccountData; +}; export type FeeQuoteParams = { - tokenList?: string[] - preferredToken?: string -} + tokenList?: string[]; + preferredToken?: string; +}; export type FeeTokenInfo = { - feeTokenAddress: string -} + feeTokenAddress: string; +}; export type SponsorpshipInfo = { webhookData?: { // eslint-disable-next-line @typescript-eslint/no-explicit-any - [key: string]: any - } - smartAccountInfo: SmartAccountData -} + [key: string]: any; + }; + smartAccountInfo: SmartAccountData; +}; export type SmartAccountData = { - name: string - version: string -} + name: string; + version: string; +}; export type PaymasterFeeQuote = { - symbol: string - tokenAddress: string - decimal: number - logoUrl?: string - maxGasFee: number - maxGasFeeUSD?: number - usdPayment?: number - premiumPercentage: number - validUntil?: number -} + symbol: string; + tokenAddress: string; + decimal: number; + logoUrl?: string; + maxGasFee: number; + maxGasFeeUSD?: number; + usdPayment?: number; + premiumPercentage: number; + validUntil?: number; +}; export type BiconomyTokenPaymasterRequest = { - feeQuote: PaymasterFeeQuote - spender: string - maxApproval?: boolean -} + feeQuote: PaymasterFeeQuote; + spender: string; + maxApproval?: boolean; +}; export type FeeQuotesOrDataResponse = { - feeQuotes?: PaymasterFeeQuote[] - tokenPaymasterAddress?: string // spender - paymasterAndData?: string - preVerificationGas?: BigNumberish - verificationGasLimit?: BigNumberish - callGasLimit?: BigNumberish -} + feeQuotes?: PaymasterFeeQuote[]; + tokenPaymasterAddress?: string; // spender + paymasterAndData?: string; + preVerificationGas?: BigNumberish; + verificationGasLimit?: BigNumberish; + callGasLimit?: BigNumberish; +}; export type PaymasterAndDataResponse = { - paymasterAndData: string - preVerificationGas?: BigNumberish - verificationGasLimit?: BigNumberish - callGasLimit?: BigNumberish -} + paymasterAndData: string; + preVerificationGas?: BigNumberish; + verificationGasLimit?: BigNumberish; + callGasLimit?: BigNumberish; +}; export enum PaymasterMode { - ERC20 = 'ERC20', - SPONSORED = 'SPONSORED' + ERC20 = "ERC20", + SPONSORED = "SPONSORED", } diff --git a/packages/paymaster/tests/paymaster.spec.ts b/packages/paymaster/tests/paymaster.spec.ts index e99000dfe..54e655580 100644 --- a/packages/paymaster/tests/paymaster.spec.ts +++ b/packages/paymaster/tests/paymaster.spec.ts @@ -1,6 +1,5 @@ -describe('Paymaster Tests', () => { - it('should have a basic test', () => { - expect(true).toBe(true); - }); +describe("Paymaster Tests", () => { + it("should have a basic test", () => { + expect(true).toBe(true); }); - \ No newline at end of file +}); diff --git a/packages/paymaster/tsconfig.json b/packages/paymaster/tsconfig.json index a31c33fe3..3dc5293ed 100644 --- a/packages/paymaster/tsconfig.json +++ b/packages/paymaster/tsconfig.json @@ -5,7 +5,7 @@ "outDir": "dist", "baseUrl": "src", "resolveJsonModule": true, - "esModuleInterop": true, + "esModuleInterop": true }, "include": ["src", "src/**/*.json"] } diff --git a/packages/transak/CHANGELOG.md b/packages/transak/CHANGELOG.md index 379471e96..b0a6115a9 100644 --- a/packages/transak/CHANGELOG.md +++ b/packages/transak/CHANGELOG.md @@ -7,22 +7,14 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline VERSION bump only - - ## 2.0.0 (2023-04-07) - ### Features -* transak wrapper module ([102e6eb](https://github.com/bcnmy/biconomy-client-sdk/commit/102e6eb5f179e4aff77d1e91973e0b32fa7b8f9a)) - - - - +- transak wrapper module ([102e6eb](https://github.com/bcnmy/biconomy-client-sdk/commit/102e6eb5f179e4aff77d1e91973e0b32fa7b8f9a)) ## 1.0.0 (2023-01-03) - ### Features -* transak wrapper module ([102e6eb](https://github.com/bcnmy/biconomy-client-sdk/commit/102e6eb5f179e4aff77d1e91973e0b32fa7b8f9a)) +- transak wrapper module ([102e6eb](https://github.com/bcnmy/biconomy-client-sdk/commit/102e6eb5f179e4aff77d1e91973e0b32fa7b8f9a)) diff --git a/packages/transak/README.md b/packages/transak/README.md index 91c317da3..ea5b73266 100644 --- a/packages/transak/README.md +++ b/packages/transak/README.md @@ -7,7 +7,7 @@ No need to create api key from transak dashboard. ```ts -import Transak from '@biconomy/transak'; -const transak = new Transak('STAGING'); +import Transak from "@biconomy/transak"; +const transak = new Transak("STAGING"); transak.init(); ``` diff --git a/packages/transak/src/index.ts b/packages/transak/src/index.ts index ca4d66d13..db7346e29 100644 --- a/packages/transak/src/index.ts +++ b/packages/transak/src/index.ts @@ -1,42 +1,43 @@ /* eslint-disable @typescript-eslint/ban-ts-comment */ // @ts-ignore -import transakSDK from '@transak/transak-sdk' -import { ITransakDto, environments } from 'interface' +import transakSDK from "@transak/transak-sdk"; +import { ITransakDto, environments } from "interface"; class TransakSDK { - apiKey: string + apiKey: string; + /* eslint-disable @typescript-eslint/no-explicit-any */ - transak: any + transak: any; constructor(environment: environments, transakData: ITransakDto = {}) { - if (environment === 'PRODUCTION') { - this.apiKey = 'f7d64c91-8f89-4018-9577-9098e42290af' + if (environment === "PRODUCTION") { + this.apiKey = "f7d64c91-8f89-4018-9577-9098e42290af"; } else { - this.apiKey = 'c71ecd4a-0819-46a7-8d63-c8b7148aaf63' + this.apiKey = "c71ecd4a-0819-46a7-8d63-c8b7148aaf63"; } const transak = new transakSDK({ apiKey: this.apiKey, - widgetHeight: '625px', - widgetWidth: '500px', + widgetHeight: "625px", + widgetWidth: "500px", environment: environment, - ...transakData - }) - this.transak = transak + ...transakData, + }); + this.transak = transak; } init() { try { - this.transak.init() + this.transak.init(); /* eslint-disable @typescript-eslint/no-explicit-any */ } catch (err: any) { - console.error(err) - throw new Error('Error while init transakSDK') + console.error(err); + throw new Error("Error while init transakSDK"); } } getTransak() { - return this.transak + return this.transak; } } -export default TransakSDK +export default TransakSDK; diff --git a/packages/transak/src/interface.ts b/packages/transak/src/interface.ts index fec86c053..fd1218340 100644 --- a/packages/transak/src/interface.ts +++ b/packages/transak/src/interface.ts @@ -1,64 +1,64 @@ -export type environments = 'PRODUCTION' | 'STAGING' +export type environments = "PRODUCTION" | "STAGING"; export interface IConfigBasic { // apiKey: string // environment: environments - redirectURL?: string - cryptoCurrencyCode?: string - fiatCurrencyCode?: string - themeColor?: string - defaultCryptoCurrency?: string - defaultFiatCurrency?: string - walletAddress?: string - fiatAmount?: number - defaultFiatAmount?: number - defaultCryptoAmount?: number - fiatCurrency?: string - countryCode?: string - paymentMethod?: string - defaultPaymentMethod?: string - isAutoFillUserData?: boolean - isFeeCalculationHidden?: boolean - email?: string - disablePaymentMethods?: string - partnerOrderId?: string - partnerCustomerId?: string - exchangeScreenTitle?: string - hideMenu?: boolean - accessToken?: string - hideExchangeScreen?: boolean - isDisableCrypto?: boolean - disableWalletAddressForm?: boolean - defaultNetwork?: string - network?: string - widgetWidth?: string | number - widgetHeight?: string | number + redirectURL?: string; + cryptoCurrencyCode?: string; + fiatCurrencyCode?: string; + themeColor?: string; + defaultCryptoCurrency?: string; + defaultFiatCurrency?: string; + walletAddress?: string; + fiatAmount?: number; + defaultFiatAmount?: number; + defaultCryptoAmount?: number; + fiatCurrency?: string; + countryCode?: string; + paymentMethod?: string; + defaultPaymentMethod?: string; + isAutoFillUserData?: boolean; + isFeeCalculationHidden?: boolean; + email?: string; + disablePaymentMethods?: string; + partnerOrderId?: string; + partnerCustomerId?: string; + exchangeScreenTitle?: string; + hideMenu?: boolean; + accessToken?: string; + hideExchangeScreen?: boolean; + isDisableCrypto?: boolean; + disableWalletAddressForm?: boolean; + defaultNetwork?: string; + network?: string; + widgetWidth?: string | number; + widgetHeight?: string | number; } export interface ITransakDto extends IConfigBasic { - networks?: string - cryptoCurrencyList?: string + networks?: string; + cryptoCurrencyList?: string; userData?: { - firstName: string - lastName: string - email: string - mobileNumber: string - dob: string + firstName: string; + lastName: string; + email: string; + mobileNumber: string; + dob: string; address: { - addressLine1: string - addressLine2: string - city: string - state: string - postCode: string - countryCode: string - } - } + addressLine1: string; + addressLine2: string; + city: string; + state: string; + postCode: string; + countryCode: string; + }; + }; walletAddressesData?: { networks?: { - [key: string]: { address: string; addressAdditionalData?: string } - } + [key: string]: { address: string; addressAdditionalData?: string }; + }; coins?: { - [key: string]: { address: string; addressAdditionalData?: string } - } - } + [key: string]: { address: string; addressAdditionalData?: string }; + }; + }; } diff --git a/packages/transak/tests/transak.spec.ts b/packages/transak/tests/transak.spec.ts index da26c9ca3..4c5cad00c 100644 --- a/packages/transak/tests/transak.spec.ts +++ b/packages/transak/tests/transak.spec.ts @@ -1,6 +1,5 @@ -describe('Transak Tests', () => { - it('should have a basic test', () => { - expect(true).toBe(true); - }); +describe("Transak Tests", () => { + it("should have a basic test", () => { + expect(true).toBe(true); }); - \ No newline at end of file +}); diff --git a/packages/transak/tsconfig.json b/packages/transak/tsconfig.json index 9e65871af..eb424084f 100644 --- a/packages/transak/tsconfig.json +++ b/packages/transak/tsconfig.json @@ -6,10 +6,7 @@ "outDir": "dist", "baseUrl": "src", "resolveJsonModule": true, - "esModuleInterop": true, + "esModuleInterop": true }, - "include": [ - "src", - "src/**/*.json" - ] -} \ No newline at end of file + "include": ["src", "src/**/*.json"] +} diff --git a/packages/web3-auth-native/.prettierrc.yaml b/packages/web3-auth-native/.prettierrc.yaml index 16ab1003d..ad7dfaff6 100644 --- a/packages/web3-auth-native/.prettierrc.yaml +++ b/packages/web3-auth-native/.prettierrc.yaml @@ -2,4 +2,4 @@ printWidth: 100 semi: false singleQuote: true -trailingComma: none \ No newline at end of file +trailingComma: none diff --git a/packages/web3-auth-native/CHANGELOG.md b/packages/web3-auth-native/CHANGELOG.md index 14b514d63..507e9447e 100644 --- a/packages/web3-auth-native/CHANGELOG.md +++ b/packages/web3-auth-native/CHANGELOG.md @@ -7,22 +7,15 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline VERSION bump only - - ## 3.0.0-alpha.0 (2023-07-12) - ### Bug Fixes -* clean web3-auth-native ([8cd1fab](https://github.com/bcnmy/biconomy-client-sdk/commit/8cd1fab6bc4864b87b0ef33ce505c2e4e28b63d4)) -* linting issue in social login ([334276b](https://github.com/bcnmy/biconomy-client-sdk/commit/334276b70e66bac576b83c1910a9890a8a451b42)) - - - +- clean web3-auth-native ([8cd1fab](https://github.com/bcnmy/biconomy-client-sdk/commit/8cd1fab6bc4864b87b0ef33ce505c2e4e28b63d4)) +- linting issue in social login ([334276b](https://github.com/bcnmy/biconomy-client-sdk/commit/334276b70e66bac576b83c1910a9890a8a451b42)) ## 2.0.0 (2023-04-07) - ### Features -* web3-auth-native ([111bf66](https://github.com/bcnmy/biconomy-client-sdk/commit/111bf66134b8519b934895fe51082d22c8805e65)) +- web3-auth-native ([111bf66](https://github.com/bcnmy/biconomy-client-sdk/commit/111bf66134b8519b934895fe51082d22c8805e65)) diff --git a/packages/web3-auth-native/README.md b/packages/web3-auth-native/README.md index 0bd345411..d559771d2 100644 --- a/packages/web3-auth-native/README.md +++ b/packages/web3-auth-native/README.md @@ -5,4 +5,5 @@ ## Usage ```ts + ``` diff --git a/packages/web3-auth-native/src/SocialLogin.ts b/packages/web3-auth-native/src/SocialLogin.ts index 8117ebdee..bd966926e 100644 --- a/packages/web3-auth-native/src/SocialLogin.ts +++ b/packages/web3-auth-native/src/SocialLogin.ts @@ -31,9 +31,8 @@ class SocialLogin { } async whitelistUrl(origin: string): Promise { - const whiteListUrlResponse: WhiteListSignatureResponse = await this.nodeClient.whitelistUrl( - origin - ) + const whiteListUrlResponse: WhiteListSignatureResponse = + await this.nodeClient.whitelistUrl(origin) return whiteListUrlResponse.data } diff --git a/packages/web3-auth-native/tests/web3-auth-native.spec.ts b/packages/web3-auth-native/tests/web3-auth-native.spec.ts index bab605baf..de58b27e6 100644 --- a/packages/web3-auth-native/tests/web3-auth-native.spec.ts +++ b/packages/web3-auth-native/tests/web3-auth-native.spec.ts @@ -1,6 +1,5 @@ describe('Web3 Auth Native Tests', () => { - it('should have a basic test', () => { - expect(true).toBe(true); - }); - }); - \ No newline at end of file + it('should have a basic test', () => { + expect(true).toBe(true) + }) +}) diff --git a/packages/web3-auth-native/tsconfig.json b/packages/web3-auth-native/tsconfig.json index 29b086a3b..86fa58e80 100644 --- a/packages/web3-auth-native/tsconfig.json +++ b/packages/web3-auth-native/tsconfig.json @@ -5,10 +5,7 @@ "strict": false, "module": "es6", "target": "es6", - "lib": [ - "ES2020", - "DOM" - ], + "lib": ["ES2020", "DOM"], "sourceMap": true, "esModuleInterop": true, "noImplicitThis": true, @@ -19,11 +16,6 @@ "skipLibCheck": true, "resolveJsonModule": true }, - "include": [ - "./src/**/*" - ], - "exclude": [ - "node_modules", - "dist" - ] -} \ No newline at end of file + "include": ["./src/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/packages/web3-auth/CHANGELOG.md b/packages/web3-auth/CHANGELOG.md index 5288626b7..ecaa97bc5 100644 --- a/packages/web3-auth/CHANGELOG.md +++ b/packages/web3-auth/CHANGELOG.md @@ -7,57 +7,41 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline VERSION bump only - - - - ## 3.0.0-alpha.0 (2023-07-12) - - - - ## 2.0.0 (2023-04-07) - ### Bug Fixes -* build ([6fb012a](https://github.com/bcnmy/biconomy-client-sdk/commit/6fb012a7d2004d5a5bad616a0ed025f1ee0a93b8)) -* css file not found ([d6cbd0b](https://github.com/bcnmy/biconomy-client-sdk/commit/d6cbd0bf88bc119c69778776df7c9bf6cd1efdb9)) -* error handling ([637bb67](https://github.com/bcnmy/biconomy-client-sdk/commit/637bb67b9390e39b4571374108bc70447a531963)) -* error handling ([7ebae72](https://github.com/bcnmy/biconomy-client-sdk/commit/7ebae72c5cfbe847bee8b2652cf88dd27a3934d9)) -* init param ([6bbccfb](https://github.com/bcnmy/biconomy-client-sdk/commit/6bbccfbff8834fa96160685f80bab7d64ec0f135)) -* ui bugs ([f7a4f47](https://github.com/bcnmy/biconomy-client-sdk/commit/f7a4f47c6076fd78515131ec59b128f312687a06)) - +- build ([6fb012a](https://github.com/bcnmy/biconomy-client-sdk/commit/6fb012a7d2004d5a5bad616a0ed025f1ee0a93b8)) +- css file not found ([d6cbd0b](https://github.com/bcnmy/biconomy-client-sdk/commit/d6cbd0bf88bc119c69778776df7c9bf6cd1efdb9)) +- error handling ([637bb67](https://github.com/bcnmy/biconomy-client-sdk/commit/637bb67b9390e39b4571374108bc70447a531963)) +- error handling ([7ebae72](https://github.com/bcnmy/biconomy-client-sdk/commit/7ebae72c5cfbe847bee8b2652cf88dd27a3934d9)) +- init param ([6bbccfb](https://github.com/bcnmy/biconomy-client-sdk/commit/6bbccfbff8834fa96160685f80bab7d64ec0f135)) +- ui bugs ([f7a4f47](https://github.com/bcnmy/biconomy-client-sdk/commit/f7a4f47c6076fd78515131ec59b128f312687a06)) ### Features -* added email input and light mode ([741301a](https://github.com/bcnmy/biconomy-client-sdk/commit/741301a526774ed45805e477fac461b1d6afd8ac)) -* increased bg opacity ([aabbb2f](https://github.com/bcnmy/biconomy-client-sdk/commit/aabbb2fc7bab637de7a6c29fead0636979e6f6d0)) -* social login ui added ([4772065](https://github.com/bcnmy/biconomy-client-sdk/commit/477206546e0518af5a1d835f7370d70d586420c0)) -* web3-auth-native ([111bf66](https://github.com/bcnmy/biconomy-client-sdk/commit/111bf66134b8519b934895fe51082d22c8805e65)) -* web3auth modal UI ([7b7e510](https://github.com/bcnmy/biconomy-client-sdk/commit/7b7e5104ad5b1828e083f70a185328b566e9d456)) -* whitelist logic added ([53c2140](https://github.com/bcnmy/biconomy-client-sdk/commit/53c2140ef9b9d79d9d9c0e0c2c80e82b1df7f8b9)) - - - - +- added email input and light mode ([741301a](https://github.com/bcnmy/biconomy-client-sdk/commit/741301a526774ed45805e477fac461b1d6afd8ac)) +- increased bg opacity ([aabbb2f](https://github.com/bcnmy/biconomy-client-sdk/commit/aabbb2fc7bab637de7a6c29fead0636979e6f6d0)) +- social login ui added ([4772065](https://github.com/bcnmy/biconomy-client-sdk/commit/477206546e0518af5a1d835f7370d70d586420c0)) +- web3-auth-native ([111bf66](https://github.com/bcnmy/biconomy-client-sdk/commit/111bf66134b8519b934895fe51082d22c8805e65)) +- web3auth modal UI ([7b7e510](https://github.com/bcnmy/biconomy-client-sdk/commit/7b7e5104ad5b1828e083f70a185328b566e9d456)) +- whitelist logic added ([53c2140](https://github.com/bcnmy/biconomy-client-sdk/commit/53c2140ef9b9d79d9d9c0e0c2c80e82b1df7f8b9)) ## 1.0.0 (2023-01-03) - ### Bug Fixes -* build ([6fb012a](https://github.com/bcnmy/biconomy-client-sdk/commit/6fb012a7d2004d5a5bad616a0ed025f1ee0a93b8)) -* css file not found ([d6cbd0b](https://github.com/bcnmy/biconomy-client-sdk/commit/d6cbd0bf88bc119c69778776df7c9bf6cd1efdb9)) -* init param ([6bbccfb](https://github.com/bcnmy/biconomy-client-sdk/commit/6bbccfbff8834fa96160685f80bab7d64ec0f135)) -* ui bugs ([f7a4f47](https://github.com/bcnmy/biconomy-client-sdk/commit/f7a4f47c6076fd78515131ec59b128f312687a06)) - +- build ([6fb012a](https://github.com/bcnmy/biconomy-client-sdk/commit/6fb012a7d2004d5a5bad616a0ed025f1ee0a93b8)) +- css file not found ([d6cbd0b](https://github.com/bcnmy/biconomy-client-sdk/commit/d6cbd0bf88bc119c69778776df7c9bf6cd1efdb9)) +- init param ([6bbccfb](https://github.com/bcnmy/biconomy-client-sdk/commit/6bbccfbff8834fa96160685f80bab7d64ec0f135)) +- ui bugs ([f7a4f47](https://github.com/bcnmy/biconomy-client-sdk/commit/f7a4f47c6076fd78515131ec59b128f312687a06)) ### Features -* added email input and light mode ([741301a](https://github.com/bcnmy/biconomy-client-sdk/commit/741301a526774ed45805e477fac461b1d6afd8ac)) -* increased bg opacity ([aabbb2f](https://github.com/bcnmy/biconomy-client-sdk/commit/aabbb2fc7bab637de7a6c29fead0636979e6f6d0)) -* social login ui added ([4772065](https://github.com/bcnmy/biconomy-client-sdk/commit/477206546e0518af5a1d835f7370d70d586420c0)) -* web3auth modal UI ([7b7e510](https://github.com/bcnmy/biconomy-client-sdk/commit/7b7e5104ad5b1828e083f70a185328b566e9d456)) -* whitelist logic added ([53c2140](https://github.com/bcnmy/biconomy-client-sdk/commit/53c2140ef9b9d79d9d9c0e0c2c80e82b1df7f8b9)) +- added email input and light mode ([741301a](https://github.com/bcnmy/biconomy-client-sdk/commit/741301a526774ed45805e477fac461b1d6afd8ac)) +- increased bg opacity ([aabbb2f](https://github.com/bcnmy/biconomy-client-sdk/commit/aabbb2fc7bab637de7a6c29fead0636979e6f6d0)) +- social login ui added ([4772065](https://github.com/bcnmy/biconomy-client-sdk/commit/477206546e0518af5a1d835f7370d70d586420c0)) +- web3auth modal UI ([7b7e510](https://github.com/bcnmy/biconomy-client-sdk/commit/7b7e5104ad5b1828e083f70a185328b566e9d456)) +- whitelist logic added ([53c2140](https://github.com/bcnmy/biconomy-client-sdk/commit/53c2140ef9b9d79d9d9c0e0c2c80e82b1df7f8b9)) diff --git a/packages/web3-auth/src/SocialLogin.tsx b/packages/web3-auth/src/SocialLogin.tsx index d72f1fc59..336c8a8fa 100644 --- a/packages/web3-auth/src/SocialLogin.tsx +++ b/packages/web3-auth/src/SocialLogin.tsx @@ -1,334 +1,334 @@ -import React from 'react' -import { createRoot } from 'react-dom/client' -import { ethers } from 'ethers' -import { Web3AuthCore } from '@web3auth/core' -import { - WALLET_ADAPTERS, - CHAIN_NAMESPACES, - SafeEventEmitterProvider, - UserInfo -} from '@web3auth/base' -import { OpenloginAdapter } from '@web3auth/openlogin-adapter' -import { MetamaskAdapter } from '@web3auth/metamask-adapter' -import { WalletConnectV1Adapter } from '@web3auth/wallet-connect-v1-adapter' -import QRCodeModal from '@walletconnect/qrcode-modal' -import NodeClient, { WhiteListSignatureResponse } from '@biconomy/node-client' - -import UI from './UI' -import { - DefaultSocialLoginConfig, - SocialLoginDTO, - WhiteLabelDataType -} from './types/Web3AuthConfig' +import React from "react"; +import { createRoot } from "react-dom/client"; +import { ethers } from "ethers"; +import { Web3AuthCore } from "@web3auth/core"; +import { WALLET_ADAPTERS, CHAIN_NAMESPACES, SafeEventEmitterProvider, UserInfo } from "@web3auth/base"; +import { OpenloginAdapter } from "@web3auth/openlogin-adapter"; +import { MetamaskAdapter } from "@web3auth/metamask-adapter"; +import { WalletConnectV1Adapter } from "@web3auth/wallet-connect-v1-adapter"; +import QRCodeModal from "@walletconnect/qrcode-modal"; +import NodeClient, { WhiteListSignatureResponse } from "@biconomy/node-client"; + +import UI from "./UI"; +import { DefaultSocialLoginConfig, SocialLoginDTO, WhiteLabelDataType } from "./types/Web3AuthConfig"; function createLoginModal(socialLogin: SocialLogin) { /* eslint-disable @typescript-eslint/no-explicit-any */ - const root = createRoot((document as any).getElementById('w3a-modal')) - root.render() + const root = createRoot((document as any).getElementById("w3a-modal")); + root.render(); } class SocialLogin { /* eslint-disable @typescript-eslint/no-explicit-any */ - walletDiv: any + walletDiv: any; + /* eslint-disable @typescript-eslint/no-explicit-any */ - walletIframe: any + walletIframe: any; + /* eslint-disable @typescript-eslint/no-explicit-any */ - iWin: any = false - iframeInitialized = false - isInit = false - clientId: string - whiteLabel: WhiteLabelDataType - userInfo: Partial | null = null - web3auth: Web3AuthCore | null = null - provider: SafeEventEmitterProvider | null = null - backendUrl!: string - nodeClient!: NodeClient + iWin: any = false; + + iframeInitialized = false; + + isInit = false; + + clientId: string; + + whiteLabel: WhiteLabelDataType; + + userInfo: Partial | null = null; + + web3auth: Web3AuthCore | null = null; + + provider: SafeEventEmitterProvider | null = null; + + backendUrl!: string; + + nodeClient!: NodeClient; constructor(backendUrl: string = defaultSocialLoginConfig.backendUrl) { - this.createWalletDiv() - this.isInit = false - this.web3auth = null - this.provider = null - this.clientId = - 'BDtxlmCXNAWQFGiiaiVY3Qb1aN-d7DQ82OhT6B-RBr5j_rGnrKAqbIkvLJlf-ofYlJRiNSHbnkeHlsh8j3ueuYY' - this.backendUrl = backendUrl - this.nodeClient = new NodeClient({ txServiceUrl: this.backendUrl }) + this.createWalletDiv(); + this.isInit = false; + this.web3auth = null; + this.provider = null; + this.clientId = "BDtxlmCXNAWQFGiiaiVY3Qb1aN-d7DQ82OhT6B-RBr5j_rGnrKAqbIkvLJlf-ofYlJRiNSHbnkeHlsh8j3ueuYY"; + this.backendUrl = backendUrl; + this.nodeClient = new NodeClient({ txServiceUrl: this.backendUrl }); this.whiteLabel = { - name: 'Biconomy SDK', - logo: 'https://s2.coinmarketcap.com/static/img/coins/64x64/9543.png' - } + name: "Biconomy SDK", + logo: "https://s2.coinmarketcap.com/static/img/coins/64x64/9543.png", + }; } async whitelistUrl(origin: string): Promise { - const whiteListUrlResponse: WhiteListSignatureResponse = await this.nodeClient.whitelistUrl( - origin - ) - console.log(whiteListUrlResponse.data) - return whiteListUrlResponse.data + const whiteListUrlResponse: WhiteListSignatureResponse = await this.nodeClient.whitelistUrl(origin); + console.log(whiteListUrlResponse.data); + return whiteListUrlResponse.data; } async init(socialLoginDTO?: Partial) { const finalDTO: SocialLoginDTO = { - chainId: '0x1', + chainId: "0x1", whitelistUrls: {}, - network: 'mainnet', - whteLableData: this.whiteLabel - } + network: "mainnet", + whteLableData: this.whiteLabel, + }; if (socialLoginDTO) { - if (socialLoginDTO.chainId) finalDTO.chainId = socialLoginDTO.chainId - if (socialLoginDTO.network) finalDTO.network = socialLoginDTO.network - if (socialLoginDTO.whitelistUrls) finalDTO.whitelistUrls = socialLoginDTO.whitelistUrls - if (socialLoginDTO.whteLableData) this.whiteLabel = socialLoginDTO.whteLableData + if (socialLoginDTO.chainId) finalDTO.chainId = socialLoginDTO.chainId; + if (socialLoginDTO.network) finalDTO.network = socialLoginDTO.network; + if (socialLoginDTO.whitelistUrls) finalDTO.whitelistUrls = socialLoginDTO.whitelistUrls; + if (socialLoginDTO.whteLableData) this.whiteLabel = socialLoginDTO.whteLableData; } try { - console.log('SocialLogin init') + console.log("SocialLogin init"); const web3AuthCore = new Web3AuthCore({ clientId: this.clientId, chainConfig: { chainNamespace: CHAIN_NAMESPACES.EIP155, - chainId: finalDTO.chainId - } - }) + chainId: finalDTO.chainId, + }, + }); const openloginAdapter = new OpenloginAdapter({ adapterSettings: { clientId: this.clientId, network: finalDTO.network, - uxMode: 'popup', + uxMode: "popup", whiteLabel: { name: this.whiteLabel.name, logoLight: this.whiteLabel.logo, logoDark: this.whiteLabel.logo, - defaultLanguage: 'en', - dark: true + defaultLanguage: "en", + dark: true, }, - originData: finalDTO.whitelistUrls - } - }) + originData: finalDTO.whitelistUrls, + }, + }); const metamaskAdapter = new MetamaskAdapter({ - clientId: this.clientId - }) + clientId: this.clientId, + }); const wcAdapter = new WalletConnectV1Adapter({ adapterSettings: { - qrcodeModal: QRCodeModal - } - }) - - web3AuthCore.configureAdapter(openloginAdapter) - web3AuthCore.configureAdapter(metamaskAdapter) - web3AuthCore.configureAdapter(wcAdapter) - await web3AuthCore.init() - this.web3auth = web3AuthCore + qrcodeModal: QRCodeModal, + }, + }); + + web3AuthCore.configureAdapter(openloginAdapter); + web3AuthCore.configureAdapter(metamaskAdapter); + web3AuthCore.configureAdapter(wcAdapter); + await web3AuthCore.init(); + this.web3auth = web3AuthCore; if (web3AuthCore && web3AuthCore.provider) { - this.provider = web3AuthCore.provider + this.provider = web3AuthCore.provider; } - createLoginModal(this) - this.isInit = true + createLoginModal(this); + this.isInit = true; } catch (error) { - console.error(error) + console.error(error); } } getProvider() { - return this.provider + return this.provider; } + /* eslint-disable @typescript-eslint/no-explicit-any */ private _createIframe(iframeContainerDiv: any) { - this.walletIframe = document.createElement('iframe') - this.walletIframe.style.display = 'none' - this.walletIframe.style.display = 'relative' + this.walletIframe = document.createElement("iframe"); + this.walletIframe.style.display = "none"; + this.walletIframe.style.display = "relative"; this.walletIframe.onload = () => { - this.iWin = this.walletIframe.contentWindow || this.walletIframe - this.iframeInitialized = true - } - iframeContainerDiv.appendChild(this.walletIframe) + this.iWin = this.walletIframe.contentWindow || this.walletIframe; + this.iframeInitialized = true; + }; + iframeContainerDiv.appendChild(this.walletIframe); } private createWalletDiv() { // create a fixed div into html but keep it hidden initially - const walletDiv = document.createElement('div') - walletDiv.id = 'w3a-modal' - walletDiv.className = 'w3a-modal w3a-modal--light' - walletDiv.style.display = 'none' - walletDiv.style.position = 'fixed' - walletDiv.style.top = '0' - walletDiv.style.right = '0' - walletDiv.style.height = '100%' - walletDiv.style.width = '100%' - walletDiv.style.background = 'rgba(33, 33, 33, 0.75)' - walletDiv.style.zIndex = '100' - this.walletDiv = walletDiv + const walletDiv = document.createElement("div"); + walletDiv.id = "w3a-modal"; + walletDiv.className = "w3a-modal w3a-modal--light"; + walletDiv.style.display = "none"; + walletDiv.style.position = "fixed"; + walletDiv.style.top = "0"; + walletDiv.style.right = "0"; + walletDiv.style.height = "100%"; + walletDiv.style.width = "100%"; + walletDiv.style.background = "rgba(33, 33, 33, 0.75)"; + walletDiv.style.zIndex = "100"; + this.walletDiv = walletDiv; // insert div into top of body. - document.body.insertBefore(walletDiv, document.body.firstChild) - this._createIframe(walletDiv) + document.body.insertBefore(walletDiv, document.body.firstChild); + this._createIframe(walletDiv); } showWallet() { - this.walletDiv.style.display = 'block' - this.walletIframe.style.display = 'block' + this.walletDiv.style.display = "block"; + this.walletIframe.style.display = "block"; // Set height and width of the iframe to 600x341 - this.walletIframe.style.height = '600px' - this.walletIframe.style.width = '341px' - this.walletIframe.style.border = '0px' - this.walletIframe.style.borderRadius = '3%' - const el = document.getElementById('w3a-modal') - el?.dispatchEvent(new Event('show-modal')) + this.walletIframe.style.height = "600px"; + this.walletIframe.style.width = "341px"; + this.walletIframe.style.border = "0px"; + this.walletIframe.style.borderRadius = "3%"; + const el = document.getElementById("w3a-modal"); + el?.dispatchEvent(new Event("show-modal")); } hideWallet() { - console.log('hide wallet') - this.walletDiv.style.display = 'none' - this.walletIframe.style.display = 'none' + console.log("hide wallet"); + this.walletDiv.style.display = "none"; + this.walletIframe.style.display = "none"; } async getUserInfo() { if (this.web3auth) { - const userInfo = await this.web3auth.getUserInfo() - this.userInfo = userInfo - return userInfo + const userInfo = await this.web3auth.getUserInfo(); + this.userInfo = userInfo; + return userInfo; } - return null + return null; } async getPrivateKey() { if (this.web3auth && this.web3auth.provider) { const privateKey = await this.web3auth.provider.request({ - method: 'eth_private_key' - }) - return privateKey + method: "eth_private_key", + }); + return privateKey; } - return null + return null; } async socialLogin(loginProvider: string) { if (!this.web3auth) { - console.info('web3auth not initialized yet') - return + console.info("web3auth not initialized yet"); + return; } try { const web3authProvider = await this.web3auth.connectTo(WALLET_ADAPTERS.OPENLOGIN, { - loginProvider: loginProvider - }) + loginProvider: loginProvider, + }); if (!web3authProvider) { - console.error('web3authProvider is null') - return null + console.error("web3authProvider is null"); + return null; } - const web3Provider = new ethers.providers.Web3Provider(web3authProvider) - const signer = web3Provider.getSigner() - const gotAccount = await signer.getAddress() - const network = await web3Provider.getNetwork() - console.info(`EOA Address ${gotAccount}\nNetwork: ${network}`) - this.provider = web3authProvider - return web3authProvider + const web3Provider = new ethers.providers.Web3Provider(web3authProvider); + const signer = web3Provider.getSigner(); + const gotAccount = await signer.getAddress(); + const network = await web3Provider.getNetwork(); + console.info(`EOA Address ${gotAccount}\nNetwork: ${network}`); + this.provider = web3authProvider; + return web3authProvider; } catch (error) { - console.error(error) - return error + console.error(error); + return error; } } async emailLogin(email: string) { if (!this.web3auth) { - console.info('web3auth not initialized yet') - return + console.info("web3auth not initialized yet"); + return; } try { const web3authProvider = await this.web3auth.connectTo(WALLET_ADAPTERS.OPENLOGIN, { - loginProvider: 'email_passwordless', - login_hint: email - }) + loginProvider: "email_passwordless", + login_hint: email, + }); if (!web3authProvider) { - console.error('web3authProvider is null') - return null + console.error("web3authProvider is null"); + return null; } - const web3Provider = new ethers.providers.Web3Provider(web3authProvider) - const signer = web3Provider.getSigner() - const gotAccount = await signer.getAddress() - const network = await web3Provider.getNetwork() - console.info(`EOA Address ${gotAccount}\nNetwork: ${network}`) - this.provider = web3authProvider - return web3authProvider + const web3Provider = new ethers.providers.Web3Provider(web3authProvider); + const signer = web3Provider.getSigner(); + const gotAccount = await signer.getAddress(); + const network = await web3Provider.getNetwork(); + console.info(`EOA Address ${gotAccount}\nNetwork: ${network}`); + this.provider = web3authProvider; + return web3authProvider; } catch (error) { - console.error(error) - return error + console.error(error); + return error; } } async metamaskLogin() { if (!this.web3auth) { - console.log('web3auth not initialized yet') - return + console.log("web3auth not initialized yet"); + return; } try { - const web3authProvider = await this.web3auth.connectTo(WALLET_ADAPTERS.METAMASK) + const web3authProvider = await this.web3auth.connectTo(WALLET_ADAPTERS.METAMASK); if (!web3authProvider) { - console.log('web3authProvider is null') - return null + console.log("web3authProvider is null"); + return null; } - const web3Provider = new ethers.providers.Web3Provider(web3authProvider) - const signer = web3Provider.getSigner() - const gotAccount = await signer.getAddress() - const network = await web3Provider.getNetwork() - console.info(`EOA Address ${gotAccount}\nNetwork: ${network}`) - this.provider = web3authProvider - return web3authProvider + const web3Provider = new ethers.providers.Web3Provider(web3authProvider); + const signer = web3Provider.getSigner(); + const gotAccount = await signer.getAddress(); + const network = await web3Provider.getNetwork(); + console.info(`EOA Address ${gotAccount}\nNetwork: ${network}`); + this.provider = web3authProvider; + return web3authProvider; } catch (error) { - console.error(error) - return error + console.error(error); + return error; } } async walletConnectLogin() { if (!this.web3auth) { - console.log('web3auth not initialized yet') - return + console.log("web3auth not initialized yet"); + return; } try { - const web3authProvider = await this.web3auth.connectTo(WALLET_ADAPTERS.WALLET_CONNECT_V1) + const web3authProvider = await this.web3auth.connectTo(WALLET_ADAPTERS.WALLET_CONNECT_V1); if (!web3authProvider) { - console.log('web3authProvider is null') - return null + console.log("web3authProvider is null"); + return null; } - const web3Provider = new ethers.providers.Web3Provider(web3authProvider) - const signer = web3Provider.getSigner() - const gotAccount = await signer.getAddress() - const network = await web3Provider.getNetwork() - console.info(`EOA Address ${gotAccount}\nNetwork: ${network}`) - this.provider = web3authProvider - return web3authProvider + const web3Provider = new ethers.providers.Web3Provider(web3authProvider); + const signer = web3Provider.getSigner(); + const gotAccount = await signer.getAddress(); + const network = await web3Provider.getNetwork(); + console.info(`EOA Address ${gotAccount}\nNetwork: ${network}`); + this.provider = web3authProvider; + return web3authProvider; } catch (error) { - console.error(error) - return error + console.error(error); + return error; } } async logout() { if (!this.web3auth) { - console.log('web3auth not initialized yet') - return + console.log("web3auth not initialized yet"); + return; } - await this.web3auth.logout() - this.web3auth.clearCache() - this.provider = null + await this.web3auth.logout(); + this.web3auth.clearCache(); + this.provider = null; } } const defaultSocialLoginConfig: DefaultSocialLoginConfig = { - backendUrl: 'https://sdk-backend.prod.biconomy.io/v1' -} + backendUrl: "https://sdk-backend.prod.biconomy.io/v1", +}; -export default SocialLogin +export default SocialLogin; -let initializedSocialLogin: SocialLogin | null = null +let initializedSocialLogin: SocialLogin | null = null; const getSocialLoginSDK = async (socialLoginDTO?: Partial) => { if (initializedSocialLogin) { - return initializedSocialLogin + return initializedSocialLogin; } - await socialLoginSDK.init(socialLoginDTO) - initializedSocialLogin = socialLoginSDK - return socialLoginSDK -} + await socialLoginSDK.init(socialLoginDTO); + initializedSocialLogin = socialLoginSDK; + return socialLoginSDK; +}; /* eslint-disable @typescript-eslint/no-explicit-any */ -const socialLoginSDK: SocialLogin = new SocialLogin() -;(window as any).socialLoginSDK = socialLoginSDK +const socialLoginSDK: SocialLogin = new SocialLogin(); +(window as any).socialLoginSDK = socialLoginSDK; -export { socialLoginSDK, getSocialLoginSDK } +export { socialLoginSDK, getSocialLoginSDK }; diff --git a/packages/web3-auth/src/UI.tsx b/packages/web3-auth/src/UI.tsx index cbf65486a..ee8c30df2 100644 --- a/packages/web3-auth/src/UI.tsx +++ b/packages/web3-auth/src/UI.tsx @@ -1,34 +1,34 @@ -import React, { useState } from 'react' -import SocialLogin from './SocialLogin' +import React, { useState } from "react"; +import SocialLogin from "./SocialLogin"; interface UIPorops { - socialLogin: SocialLogin + socialLogin: SocialLogin; } const container = { - position: 'fixed', - float: 'left', - left: '50%', - top: '50%', - width: 'min(90vw, 375px)', - transform: 'translate(-50%, -50%)', - transition: 'opacity 400ms ease-in', - border: '1px solid #181818', + position: "fixed", + float: "left", + left: "50%", + top: "50%", + width: "min(90vw, 375px)", + transform: "translate(-50%, -50%)", + transition: "opacity 400ms ease-in", + border: "1px solid #181818", borderRadius: 10, - background: 'black', - overflow: 'hidden' -} as React.CSSProperties + background: "black", + overflow: "hidden", +} as React.CSSProperties; const UI: React.FC = ({ socialLogin }) => { - const [email, setEmail] = useState('') + const [email, setEmail] = useState(""); function handleEmailSubmit(event: React.SyntheticEvent) { - event.preventDefault() - socialLogin.emailLogin(email) + event.preventDefault(); + socialLogin.emailLogin(email); } function handleEmailChange(event: React.FormEvent) { - setEmail(event.currentTarget.value) + setEmail(event.currentTarget.value); } return ( @@ -41,25 +41,10 @@ const UI: React.FC = ({ socialLogin }) => {

Select one of the following to continue

- @@ -69,31 +54,13 @@ const UI: React.FC = ({ socialLogin }) => {
CONTINUE WITH
  • -
  • -
@@ -101,14 +68,7 @@ const UI: React.FC = ({ socialLogin }) => {
EMAIL
- + @@ -117,18 +77,10 @@ const UI: React.FC = ({ socialLogin }) => {
EXTERNAL WALLET
- -
@@ -145,7 +97,7 @@ const UI: React.FC = ({ socialLogin }) => {
- ) -} + ); +}; -export default UI +export default UI; diff --git a/packages/web3-auth/src/index.ts b/packages/web3-auth/src/index.ts index fc68c3d4a..803fefd3a 100644 --- a/packages/web3-auth/src/index.ts +++ b/packages/web3-auth/src/index.ts @@ -1,4 +1,4 @@ -import SocialLogin, { socialLoginSDK, getSocialLoginSDK } from './SocialLogin' +import SocialLogin, { socialLoginSDK, getSocialLoginSDK } from "./SocialLogin"; -export default SocialLogin -export { socialLoginSDK, getSocialLoginSDK } +export default SocialLogin; +export { socialLoginSDK, getSocialLoginSDK }; diff --git a/packages/web3-auth/src/style.css b/packages/web3-auth/src/style.css index c65487baa..70264c5c1 100644 --- a/packages/web3-auth/src/style.css +++ b/packages/web3-auth/src/style.css @@ -1,52 +1,45 @@ /* devanagari */ @font-face { - font-family: 'Poppins'; + font-family: "Poppins"; font-style: normal; font-weight: 600; - src: url(https://fonts.gstatic.com/s/poppins/v15/pxiByp8kv8JHgFVrLEj6Z11lFd2JQEl8qw.woff2) - format('woff2'); - unicode-range: U+0900-097F, U+1CD0-1CF6, U+1CF8-1CF9, U+200C-200D, U+20A8, U+20B9, U+25CC, - U+A830-A839, U+A8E0-A8FB; + src: url(https://fonts.gstatic.com/s/poppins/v15/pxiByp8kv8JHgFVrLEj6Z11lFd2JQEl8qw.woff2) format("woff2"); + unicode-range: U+0900-097F, U+1CD0-1CF6, U+1CF8-1CF9, U+200C-200D, U+20A8, U+20B9, U+25CC, U+A830-A839, U+A8E0-A8FB; } /* latin-ext */ @font-face { - font-family: 'Poppins'; + font-family: "Poppins"; font-style: normal; font-weight: 600; - src: url(https://fonts.gstatic.com/s/poppins/v15/pxiByp8kv8JHgFVrLEj6Z1JlFd2JQEl8qw.woff2) - format('woff2'); - unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, - U+2C60-2C7F, U+A720-A7FF; + src: url(https://fonts.gstatic.com/s/poppins/v15/pxiByp8kv8JHgFVrLEj6Z1JlFd2JQEl8qw.woff2) format("woff2"); + unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; } /* latin */ @font-face { - font-family: 'Poppins'; + font-family: "Poppins"; font-style: normal; font-weight: 600; - src: url(https://fonts.gstatic.com/s/poppins/v15/pxiByp8kv8JHgFVrLEj6Z1xlFd2JQEk.woff2) - format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, - U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; + src: url(https://fonts.gstatic.com/s/poppins/v15/pxiByp8kv8JHgFVrLEj6Z1xlFd2JQEk.woff2) format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, + U+2215, U+FEFF, U+FFFD; } /* latin-ext */ @font-face { - font-family: 'DM Sans'; + font-family: "DM Sans"; font-style: normal; font-weight: 400; - src: url(https://fonts.gstatic.com/s/dmsans/v6/rP2Hp2ywxg089UriCZ2IHTWEBlwu8Q.woff2) - format('woff2'); - unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, - U+2C60-2C7F, U+A720-A7FF; + src: url(https://fonts.gstatic.com/s/dmsans/v6/rP2Hp2ywxg089UriCZ2IHTWEBlwu8Q.woff2) format("woff2"); + unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; } /* latin */ @font-face { - font-family: 'DM Sans'; + font-family: "DM Sans"; font-style: normal; font-weight: 400; - src: url(https://fonts.gstatic.com/s/dmsans/v6/rP2Hp2ywxg089UriCZOIHTWEBlw.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, - U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; + src: url(https://fonts.gstatic.com/s/dmsans/v6/rP2Hp2ywxg089UriCZOIHTWEBlw.woff2) format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, + U+2215, U+FEFF, U+FFFD; } /* Modal */ @@ -56,8 +49,8 @@ --text-color1: #d3d3d4; --text-color2: #ffffff; - --text-header: 'Poppins', Helvetica, sans-serif; - --text-body: 'DM Sans', Helvetica, sans-serif; + --text-header: "Poppins", Helvetica, sans-serif; + --text-body: "DM Sans", Helvetica, sans-serif; position: fixed; top: 0; @@ -210,7 +203,7 @@ #w3a-modal .w3a-spinner__mask, #w3a-modal .w3a-spinner__head { - content: ''; + content: ""; position: absolute; border-radius: 50%; } @@ -424,7 +417,9 @@ #w3a-modal .w3a-button__image { max-width: 100%; max-height: 100%; - transition: 0.3s cubic-bezier(0.25, 0.8, 0.5, 1), visibility 0s; + transition: + 0.3s cubic-bezier(0.25, 0.8, 0.5, 1), + visibility 0s; } #w3a-modal button.w3a-button.w3a-button--rotate .w3a-button__image { diff --git a/packages/web3-auth/src/types/Web3AuthConfig.ts b/packages/web3-auth/src/types/Web3AuthConfig.ts index 5d932ec45..8caee797c 100644 --- a/packages/web3-auth/src/types/Web3AuthConfig.ts +++ b/packages/web3-auth/src/types/Web3AuthConfig.ts @@ -1,15 +1,15 @@ export type DefaultSocialLoginConfig = { - backendUrl: string -} + backendUrl: string; +}; export type WhiteLabelDataType = { - name: string - logo: string -} + name: string; + logo: string; +}; export type SocialLoginDTO = { - chainId: string - whitelistUrls: { [P in string]: string } - network: 'mainnet' | 'testnet' - whteLableData: WhiteLabelDataType -} + chainId: string; + whitelistUrls: { [P in string]: string }; + network: "mainnet" | "testnet"; + whteLableData: WhiteLabelDataType; +}; diff --git a/packages/web3-auth/tests/web3-auth.spec.ts b/packages/web3-auth/tests/web3-auth.spec.ts index 22cb4d431..10bb465ec 100644 --- a/packages/web3-auth/tests/web3-auth.spec.ts +++ b/packages/web3-auth/tests/web3-auth.spec.ts @@ -1,6 +1,5 @@ -describe('Web3 Auth Tests', () => { - it('should have a basic test', () => { - expect(true).toBe(true); - }); +describe("Web3 Auth Tests", () => { + it("should have a basic test", () => { + expect(true).toBe(true); }); - \ No newline at end of file +}); diff --git a/packages/web3-auth/tsconfig.json b/packages/web3-auth/tsconfig.json index 9e65871af..eb424084f 100644 --- a/packages/web3-auth/tsconfig.json +++ b/packages/web3-auth/tsconfig.json @@ -6,10 +6,7 @@ "outDir": "dist", "baseUrl": "src", "resolveJsonModule": true, - "esModuleInterop": true, + "esModuleInterop": true }, - "include": [ - "src", - "src/**/*.json" - ] -} \ No newline at end of file + "include": ["src", "src/**/*.json"] +} diff --git a/tsconfig.settings.json b/tsconfig.settings.json index 86f910d6f..fbd122a5e 100644 --- a/tsconfig.settings.json +++ b/tsconfig.settings.json @@ -1,27 +1,27 @@ { "compilerOptions": { - "target": "ES2019", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ - "module": "CommonJS", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ - "allowJs": false, /* Allow javascript files to be compiled. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - "sourceMap": true, /* Generates corresponding '.map' file. */ - "strict": true, /* Enable all strict type-checking options. */ - "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ - "strictNullChecks": true, /* Enable strict null checks. */ - "strictFunctionTypes": true, /* Enable strict checking of function types. */ - "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ - "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ - "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ - "noUnusedParameters": true, /* Report errors on unused parameters. */ - "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - "skipLibCheck": true, /* Skip type checking of declaration files. */ - "forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */ + "target": "ES2019" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, + "module": "CommonJS" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, + "allowJs": false /* Allow javascript files to be compiled. */, + "declaration": true /* Generates corresponding '.d.ts' file. */, + "sourceMap": true /* Generates corresponding '.map' file. */, + "strict": true /* Enable all strict type-checking options. */, + "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, + "strictNullChecks": true /* Enable strict null checks. */, + "strictFunctionTypes": true /* Enable strict checking of function types. */, + "strictBindCallApply": true /* Enable strict 'bind', 'call', and 'apply' methods on functions. */, + "strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */, + "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */, + "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */, + "noUnusedParameters": true /* Report errors on unused parameters. */, + "noImplicitReturns": true /* Report error when not all code paths in function return a value. */, + "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */, + "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */, + "allowSyntheticDefaultImports": true /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */, + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, + "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */, + "skipLibCheck": true /* Skip type checking of declaration files. */, + "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, "resolveJsonModule": true } } From 3772ae26f09118cc1b1acb550f0df26075ba2bb8 Mon Sep 17 00:00:00 2001 From: aboudjem Date: Fri, 8 Sep 2023 18:09:27 +0700 Subject: [PATCH 9/9] =?UTF-8?q?=F0=9F=94=A7=20optimize=20config?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lerna.json | 2 +- package.json | 65 ++++++++++++++++++++++++++++++++------------------- tsconfig.json | 2 -- 3 files changed, 42 insertions(+), 27 deletions(-) diff --git a/lerna.json b/lerna.json index 519b24060..be069a470 100644 --- a/lerna.json +++ b/lerna.json @@ -7,5 +7,5 @@ "conventionalCommits": true } }, - "ignoreChanges": ["**/CHANGELOG.md", "**/node_modules/**", "**/package.json", "**/*.md", "**/perf/**"] + "ignoreChanges": ["**/CHANGELOG.md", "**/node_modules/**", "**/*.md", "**/perf/**"] } diff --git a/package.json b/package.json index 16cee71eb..e91f69d05 100644 --- a/package.json +++ b/package.json @@ -1,23 +1,43 @@ { "name": "biconomy-sdk", + "version": "1.0.0", + "description": "SDK for Biconomy integration with support for account abstraction, smart accounts, ERC-4337, ERC-6900, and cross-chain functionalities.", + "keywords": [ + "biconomy", + "sdk", + "blockchain", + "integration", + "account abstraction", + "smart accounts", + "erc-4337", + "erc-6900", + "crosschain", + "cross-chain", + "metatransactions" + ], + "license": "MIT", + "homepage": "https://biconomy.io/docs", + "bugs": { + "url": "https://github.com/bcnmy/biconomy-client-sdk/issues" + }, "repository": { "type": "git", "url": "https://github.com/bcnmy/biconomy-client-sdk" }, + "author": "Biconomy (https://biconomy.io)", "private": true, "scripts": { - "clean": "lerna clean", - "unbuild": "lerna run unbuild", - "build": "lerna run build --stream --npm-client=yarn", - "test": "npx jest --runInBand", - "test:coverage": "npx jest --coverage", - "test:ci": "FORCE_COLOR=1 lerna run test:ci --stream --npm-client=yarn", + "build": "lerna run build", + "clean": "lerna clean && lerna run unbuild", "format": "lerna run format --npm-client=yarn", - "prettier": "lerna run prettier --npm-client=npm", - "diff": "lerna diff", - "new-version": "lerna version patch --no-git-tag-version --no-push --conventional-commits --yes", + "prettier": "lerna run prettier --npm-client=yarn", "lint": "eslint -c .eslintrc.js 'packages/*/src/**/*.{ts,tsx}'", - "lint:fix": "eslint -c .eslintrc.js 'packages/*/src/**/*.{ts,tsx}' --fix" + "lint:fix": "eslint -c .eslintrc.js 'packages/*/src/**/*.{ts,tsx}' --fix", + "test": "yarn jest --runInBand", + "test:ci": "FORCE_COLOR=1 lerna run test:ci --stream --npm-client=yarn", + "test:coverage": "yarn jest --coverage", + "diff": "lerna diff", + "release": "lerna version patch --no-git-tag-version --no-push --conventional-commits --yes" }, "changelog": { "labels": { @@ -30,32 +50,29 @@ "packages/*" ] }, - "author": "Biconomy (https://biconomy.io)", + "dependencies": { + "node-gyp": "^9.4.0", + "typescript": "^5.2.2" + }, "devDependencies": { "@types/jest": "^29.5.4", - "@typescript-eslint/eslint-plugin": "^6.0.0", - "@typescript-eslint/parser": "^6.0.0", - "eslint": "^8.2.0", + "@typescript-eslint/eslint-plugin": "^6.6.0", + "@typescript-eslint/parser": "^6.6.0", + "eslint": "^8.48.0", "eslint-config-airbnb-base": "15.0.0", "eslint-config-airbnb-typescript": "17.1.0", "eslint-config-prettier": "^9.0.0", - "eslint-plugin-import": "^2.25.3", + "eslint-plugin-import": "^2.28.1", "eslint-plugin-prettier": "^5.0.0", "eslint-plugin-security": "^1.7.1", - "hardhat": "^2.9.9", + "hardhat": "^2.17.2", "jest": "^29.6.4", "lerna": "^7.2.0", "lerna-changelog": "^2.2.0", - "nx": "^15.8.3", + "nx": "^16.8.1", "prettier": "^3.0.3", - "rimraf": "^3.0.2", + "rimraf": "^5.0.1", "ts-jest": "^29.1.1", "ts-node": "^10.9.1" - }, - "dependencies": { - "chai": "^4.3.6", - "chai-as-promised": "^7.1.1", - "node-gyp": "^9.1.0", - "typescript": "^4.7.4" } } diff --git a/tsconfig.json b/tsconfig.json index 3f0596634..3ad9d22bd 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,8 +4,6 @@ "module": "commonjs", "declaration": true, "sourceMap": true, - "allowSyntheticDefaultImports": true, - "strictNullChecks": false, "strict": true, "esModuleInterop": true, "lib": ["es2020"],