From 46bfa32432696b2d0a1c7066f1beb14a0ba62b28 Mon Sep 17 00:00:00 2001 From: livingrockrises <90545960+livingrockrises@users.noreply.github.com> Date: Mon, 6 Nov 2023 18:33:04 +0530 Subject: [PATCH] rebase with development --- package.json | 4 +- packages/account/package.json | 1 + packages/account/src/BaseSmartAccount.ts | 62 +- packages/account/src/BiconomySmartAccount.ts | 89 +- .../account/src/BiconomySmartAccountV2.ts | 119 ++- packages/account/src/SmartAccount.ts | 43 +- packages/account/src/index.ts | 1 + packages/account/src/utils/Types.ts | 16 +- packages/account/src/utils/VoidSigner.ts | 57 ++ .../tests/SmartAccountV2.local.spec.ts | 33 +- packages/bundler/src/Bundler.ts | 138 ++- packages/bundler/src/interfaces/IBundler.ts | 14 +- packages/bundler/src/utils/Constants.ts | 143 ++- packages/bundler/src/utils/Types.ts | 38 +- packages/common/CHANGELOG.md | 2 +- packages/common/package.json | 1 + packages/common/src/Constants.ts | 5 + packages/common/src/httpRequests.ts | 1 + packages/core-types/CHANGELOG.md | 2 +- packages/core-types/src/ChainsTypes.ts | 33 +- .../modules/src/BatchedSessionRouterModule.ts | 9 +- .../modules/src/SessionKeyManagerModule.ts | 14 +- packages/modules/src/utils/Constants.ts | 4 +- packages/modules/src/utils/Types.ts | 8 + packages/node-client/CHANGELOG.md | 2 +- packages/node-client/README.md | 4 +- .../node-client/src/types/NodeClientTypes.ts | 2 +- packages/paymaster/src/BiconomyPaymaster.ts | 29 +- packages/paymaster/src/utils/Types.ts | 19 + packages/web3-auth-native/.gitignore | 584 ------------ packages/web3-auth-native/.prettierignore | 21 - packages/web3-auth-native/.prettierrc.yaml | 5 - packages/web3-auth-native/CHANGELOG.md | 33 - packages/web3-auth-native/README.md | 9 - packages/web3-auth-native/package.json | 71 -- packages/web3-auth-native/src/SocialLogin.ts | 101 -- packages/web3-auth-native/src/index.ts | 6 - .../web3-auth-native/src/types/IWebBrowser.ts | 310 ------- packages/web3-auth-native/src/types/State.ts | 10 - packages/web3-auth-native/src/types/sdk.ts | 90 -- .../tests/web3-auth-native.spec.ts | 5 - packages/web3-auth-native/torus.config.js | 3 - .../web3-auth-native/tsconfig.eslint.json | 3 - packages/web3-auth-native/tsconfig.json | 12 - packages/web3-auth/CHANGELOG.md | 90 -- packages/web3-auth/README.md | 14 - packages/web3-auth/package.json | 62 -- packages/web3-auth/src/SocialLogin.tsx | 332 ------- packages/web3-auth/src/UI.tsx | 103 --- packages/web3-auth/src/index.ts | 4 - packages/web3-auth/src/style.css | 871 ------------------ .../web3-auth/src/types/Web3AuthConfig.ts | 15 - packages/web3-auth/tests/web3-auth.spec.ts | 5 - packages/web3-auth/tsconfig.json | 12 - 54 files changed, 679 insertions(+), 2985 deletions(-) create mode 100644 packages/account/src/utils/VoidSigner.ts delete mode 100644 packages/web3-auth-native/.gitignore delete mode 100644 packages/web3-auth-native/.prettierignore delete mode 100644 packages/web3-auth-native/.prettierrc.yaml delete mode 100644 packages/web3-auth-native/CHANGELOG.md delete mode 100644 packages/web3-auth-native/README.md delete mode 100644 packages/web3-auth-native/package.json delete mode 100644 packages/web3-auth-native/src/SocialLogin.ts delete mode 100644 packages/web3-auth-native/src/index.ts delete mode 100644 packages/web3-auth-native/src/types/IWebBrowser.ts delete mode 100644 packages/web3-auth-native/src/types/State.ts delete mode 100644 packages/web3-auth-native/src/types/sdk.ts delete mode 100644 packages/web3-auth-native/tests/web3-auth-native.spec.ts delete mode 100644 packages/web3-auth-native/torus.config.js delete mode 100644 packages/web3-auth-native/tsconfig.eslint.json delete mode 100644 packages/web3-auth-native/tsconfig.json delete mode 100644 packages/web3-auth/CHANGELOG.md delete mode 100644 packages/web3-auth/README.md delete mode 100644 packages/web3-auth/package.json delete mode 100644 packages/web3-auth/src/SocialLogin.tsx delete mode 100644 packages/web3-auth/src/UI.tsx delete mode 100644 packages/web3-auth/src/index.ts delete mode 100644 packages/web3-auth/src/style.css delete mode 100644 packages/web3-auth/src/types/Web3AuthConfig.ts delete mode 100644 packages/web3-auth/tests/web3-auth.spec.ts delete mode 100644 packages/web3-auth/tsconfig.json diff --git a/package.json b/package.json index 34230c01b..35f668de6 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "test": "concurrently -k --success first 'yarn start:ganache' 'yarn test:run'", "start:ganache": "ganache -m 'direct buyer cliff train rice spirit census refuse glare expire innocent quote'", "test:ci": "FORCE_COLOR=1 lerna run test:ci --stream --npm-client=yarn", - "test:coverage": "yarn jest --coverage", + "test:coverage": "concurrently -k --success first 'yarn start:ganache' 'yarn jest --runInBand --coverage'", "diff": "lerna diff", "release": "lerna version patch --no-git-tag-version --no-push --conventional-commits --yes" }, @@ -56,6 +56,8 @@ "typescript": "^5.2.2" }, "devDependencies": { + "ganache": "^7.9.1", + "@types/debug": "^4.1.9", "@types/jest": "^29.5.4", "@typescript-eslint/eslint-plugin": "^6.7.0", "@typescript-eslint/parser": "^6.6.0", diff --git a/packages/account/package.json b/packages/account/package.json index 018d66a6d..7d89691ec 100644 --- a/packages/account/package.json +++ b/packages/account/package.json @@ -46,6 +46,7 @@ "@biconomy/modules": "^3.1.0", "@biconomy/node-client": "^3.1.0", "@biconomy/paymaster": "^3.1.0", + "@ethersproject/logger": "^5.7.0", "@ethersproject/providers": "^5.7.2", "ethers": "^5.7.0", "loglevel": "^1.8.1", diff --git a/packages/account/src/BaseSmartAccount.ts b/packages/account/src/BaseSmartAccount.ts index 7030daa1c..f0ef1146f 100644 --- a/packages/account/src/BaseSmartAccount.ts +++ b/packages/account/src/BaseSmartAccount.ts @@ -7,11 +7,13 @@ import { calcPreVerificationGas, DefaultGasLimits } from "./utils/Preverificaito import { NotPromise, packUserOp, Logger, RPC_PROVIDER_URLS } from "@biconomy/common"; import { IBundler, UserOpResponse } from "@biconomy/bundler"; import { IPaymaster, PaymasterAndDataResponse } from "@biconomy/paymaster"; +import { SendUserOpParams } from "@biconomy/modules"; +import { SponsorUserOperationDto, BiconomyPaymaster, PaymasterMode, IHybridPaymaster } from "@biconomy/paymaster"; import { BaseSmartAccountConfig, Overrides, TransactionDetailsForUserOp } from "./utils/Types"; import { GasOverheads } from "./utils/Preverificaiton"; import { EntryPoint, EntryPoint__factory } from "@account-abstraction/contracts"; import { DEFAULT_ENTRYPOINT_ADDRESS } from "./utils/Constants"; -import { LRUCache } from 'lru-cache' +import { LRUCache } from "lru-cache"; type UserOperationKey = keyof UserOperation; @@ -71,7 +73,7 @@ export abstract class BaseSmartAccount implements IBaseSmartAccount { validateUserOp(userOp: Partial, requiredFields: UserOperationKey[]): boolean { for (const field of requiredFields) { if (!userOp[field]) { - throw new Error(`${field} is missing`); + throw new Error(`${String(field)} is missing in the UserOp`); } } return true; @@ -181,7 +183,7 @@ export abstract class BaseSmartAccount implements IBaseSmartAccount { * @description This function call will take 'signedUserOp' as input and send it to the bundler * @returns */ - async sendSignedUserOp(userOp: UserOperation): Promise { + async sendSignedUserOp(userOp: UserOperation, params?: SendUserOpParams): Promise { const requiredFields: UserOperationKey[] = [ "sender", "nonce", @@ -199,16 +201,30 @@ export abstract class BaseSmartAccount implements IBaseSmartAccount { 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); + const bundlerResponse = await this.bundler.sendUserOp(userOp, params); return bundlerResponse; } 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()); - userOp.maxPriorityFeePerGas = - userOp.maxPriorityFeePerGas ?? feeData.maxPriorityFeePerGas ?? feeData.gasPrice ?? (await this.provider.getGasPrice()); + let feeData = null; + + if ( + userOp.maxFeePerGas === undefined || + userOp.maxFeePerGas === null || + userOp.maxPriorityFeePerGas === undefined || + userOp.maxPriorityFeePerGas === null + ) { + feeData = await this.provider.getFeeData(); + } + + if (userOp.maxFeePerGas === undefined || userOp.maxFeePerGas === null) { + userOp.maxFeePerGas = feeData?.maxFeePerGas ?? feeData?.gasPrice ?? (await this.provider.getGasPrice()); + } + + if (userOp.maxPriorityFeePerGas === undefined || userOp.maxPriorityFeePerGas === null) { + userOp.maxPriorityFeePerGas = feeData?.maxPriorityFeePerGas ?? feeData?.gasPrice ?? (await this.provider.getGasPrice()); + } if (userOp.initCode) userOp.verificationGasLimit = userOp.verificationGasLimit ?? (await this.getVerificationGasLimit(userOp.initCode)); userOp.callGasLimit = userOp.callGasLimit ?? @@ -221,16 +237,18 @@ export abstract class BaseSmartAccount implements IBaseSmartAccount { return userOp; } + // TODO // Should make this a Dto async estimateUserOpGas( userOp: Partial, overrides?: Overrides, skipBundlerGasEstimation?: boolean, + paymasterServiceData?: SponsorUserOperationDto, ): Promise> { const requiredFields: UserOperationKey[] = ["sender", "nonce", "initCode", "callData"]; this.validateUserOp(userOp, requiredFields); let finalUserOp = userOp; - const skipBundlerCall = skipBundlerGasEstimation ?? false; + const skipBundlerCall = skipBundlerGasEstimation ?? true; // Override gas values in userOp if provided in overrides params if (overrides) { userOp = { ...userOp, ...overrides }; @@ -238,12 +256,27 @@ export abstract class BaseSmartAccount implements IBaseSmartAccount { 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 no bundler url is provided run offchain logic to assign following values of UserOp - // maxFeePerGas, maxPriorityFeePerGas, verificationGasLimit, callGasLimit, preVerificationGas - finalUserOp = await this.calculateUserOpGasValues(userOp); + if (skipBundlerCall) { + if (this.paymaster && this.paymaster instanceof BiconomyPaymaster && paymasterServiceData?.mode === PaymasterMode.SPONSORED) { + if (!userOp.maxFeePerGas && !userOp.maxPriorityFeePerGas) { + throw new Error("maxFeePerGas and maxPriorityFeePerGas are required for skipBundlerCall mode"); + } + // Making call to paymaster to get gas estimations for userOp + const { callGasLimit, verificationGasLimit, preVerificationGas, paymasterAndData } = await ( + this.paymaster as IHybridPaymaster + ).getPaymasterAndData(userOp, paymasterServiceData); + finalUserOp.verificationGasLimit = verificationGasLimit ?? userOp.verificationGasLimit; + finalUserOp.callGasLimit = callGasLimit ?? userOp.callGasLimit; + finalUserOp.preVerificationGas = preVerificationGas ?? userOp.preVerificationGas; + finalUserOp.paymasterAndData = paymasterAndData ?? userOp.paymasterAndData; + } else { + Logger.warn("Skipped paymaster call. If you are using paymasterAndData, generate data externally"); + finalUserOp = await this.calculateUserOpGasValues(userOp); + finalUserOp.paymasterAndData = "0x"; + } } else { + if (!this.bundler) throw new Error("Bundler is not provided"); + // TODO: is this still needed to delete? delete userOp.maxFeePerGas; delete userOp.maxPriorityFeePerGas; // Making call to bundler to get gas estimations for userOp @@ -261,6 +294,7 @@ export abstract class BaseSmartAccount implements IBaseSmartAccount { finalUserOp.verificationGasLimit = verificationGasLimit ?? userOp.verificationGasLimit; finalUserOp.callGasLimit = callGasLimit ?? userOp.callGasLimit; finalUserOp.preVerificationGas = preVerificationGas ?? userOp.preVerificationGas; + finalUserOp.paymasterAndData = "0x"; } return finalUserOp; } diff --git a/packages/account/src/BiconomySmartAccount.ts b/packages/account/src/BiconomySmartAccount.ts index 2420f9017..40504b2b6 100644 --- a/packages/account/src/BiconomySmartAccount.ts +++ b/packages/account/src/BiconomySmartAccount.ts @@ -256,25 +256,59 @@ export class BiconomySmartAccount extends SmartAccount implements IBiconomySmart return "0x"; } - async buildUserOp(transactions: Transaction[], overrides?: Overrides, skipBundlerGasEstimation?: boolean): Promise> { + private async getNonce(): Promise { + let nonce = BigNumber.from(0); + try { + 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 + Logger.log("Error while getting nonce for the account. This is expected for undeployed accounts set nonce to 0"); + } + return nonce; + } + + private async getGasFeeValues( + overrides: Overrides | undefined, + skipBundlerGasEstimation: boolean | undefined, + ): Promise<{ maxFeePerGas?: BigNumberish | undefined; maxPriorityFeePerGas?: BigNumberish | undefined }> { + const gasFeeValues = { + maxFeePerGas: overrides?.maxFeePerGas, + maxPriorityFeePerGas: overrides?.maxPriorityFeePerGas, + }; + try { + if (this.bundler && !gasFeeValues.maxFeePerGas && !gasFeeValues.maxPriorityFeePerGas && (skipBundlerGasEstimation ?? true)) { + const gasFeeEstimation = await this.bundler.getGasFeeValues(); + gasFeeValues.maxFeePerGas = gasFeeEstimation.maxFeePerGas; + gasFeeValues.maxPriorityFeePerGas = gasFeeEstimation.maxPriorityFeePerGas; + } + return gasFeeValues; + } catch (error: any) { + Logger.error("Error while getting gasFeeValues from bundler. Provided bundler might not have getGasFeeValues endpoint", error); + return gasFeeValues; + } + } + + async buildUserOp( + transactions: Transaction[], + overrides?: Overrides, + skipBundlerGasEstimation?: boolean, + paymasterServiceData?: SponsorUserOperationDto, + ): Promise> { this.isInitialized(); 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 [nonce, gasFeeValues] = await Promise.all([this.getNonce(), this.getGasFeeValues(overrides, skipBundlerGasEstimation)]); + let callData = ""; if (transactions.length === 1) { callData = this.getExecuteCallData(to[0], value[0], data[0]); } else { callData = this.getExecuteBatchCallData(to, value, data); } - let nonce = BigNumber.from(0); - try { - 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; if (nonce.eq(0)) { @@ -286,16 +320,14 @@ export class BiconomySmartAccount extends SmartAccount implements IBiconomySmart nonce, initCode: !isDeployed ? this.initCode : "0x", callData: callData, + maxFeePerGas: gasFeeValues.maxFeePerGas || undefined, + maxPriorityFeePerGas: gasFeeValues.maxPriorityFeePerGas || undefined, + signature: this.getDummySignature(), }; - // for this Smart Account dummy ECDSA signature will be used to estimate gas - userOp.signature = this.getDummySignature(); - - 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) + // Note: Can change the default behaviour of calling estimations using bundler/local + userOp = await this.estimateUserOpGas(userOp, overrides, skipBundlerGasEstimation, paymasterServiceData); + Logger.log("UserOp after estimation ", userOp); return userOp; } @@ -394,36 +426,11 @@ export class BiconomySmartAccount extends SmartAccount implements IBiconomySmart newCallData = this.getExecuteBatchCallData(batchTo, batchValue, batchData); } - let finalUserOp: Partial = { + const finalUserOp: Partial = { ...userOp, 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; - - // Maybe send paymasterAndData since we know it's for Token paymaster - /*finalUserOp.paymasterAndData = - '0x00000f7365ca6c59a2c93719ad53d567ed49c14c000000000000000000000000000000000000000000000000000000000064e3d3890000000000000000000000000000000000000000000000000000000064e3cc81000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e583100000000000000000000000000000f7748595e46527413574a9327942e744e910000000000000000000000000000000000000000000000000000000063ac7f6c000000000000000000000000000000000000000000000000000000000010c8e07bf61410b71700f943499adfd23e50fb16040d587acb0a5e60ac8576cdbb4c8044f00579a1fc3f294e7dc4a5eb557a7193008343aa36225bddcfbd4fd15646031c'*/ - - // 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"))) { - return { - ...userOp, - callData: newCallData, - }; - } - 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"); - } return finalUserOp; } } catch (error) { diff --git a/packages/account/src/BiconomySmartAccountV2.ts b/packages/account/src/BiconomySmartAccountV2.ts index 0edc34842..72ce7723b 100644 --- a/packages/account/src/BiconomySmartAccountV2.ts +++ b/packages/account/src/BiconomySmartAccountV2.ts @@ -10,8 +10,15 @@ import { SmartAccount_v200__factory, SmartAccountFactory_v200__factory, } from "@biconomy/common"; -import { BiconomyTokenPaymasterRequest, BiconomySmartAccountV2Config, CounterFactualAddressParam, BuildUserOpOptions } from "./utils/Types"; -import { BaseValidationModule, ModuleInfo } from "@biconomy/modules"; +import { + BiconomyTokenPaymasterRequest, + BiconomySmartAccountV2Config, + CounterFactualAddressParam, + BuildUserOpOptions, + Overrides, + NonceOptions, +} from "./utils/Types"; +import { BaseValidationModule, ModuleInfo, SendUserOpParams } from "@biconomy/modules"; import { UserOperation, Transaction } from "@biconomy/core-types"; import NodeClient from "@biconomy/node-client"; import INodeClient from "@biconomy/node-client"; @@ -66,7 +73,6 @@ export class BiconomySmartAccountV2 extends BaseSmartAccount { public static async create(biconomySmartAccountConfig: BiconomySmartAccountV2Config): Promise { const instance = new BiconomySmartAccountV2(biconomySmartAccountConfig); - await instance.init(); instance.factoryAddress = biconomySmartAccountConfig.factoryAddress ?? DEFAULT_BICONOMY_FACTORY_ADDRESS; // This would be fetched from V2 const defaultFallbackHandlerAddress = @@ -93,6 +99,8 @@ export class BiconomySmartAccountV2 extends BaseSmartAccount { instance.nodeClient = new NodeClient({ txServiceUrl: nodeClientUrl ?? NODE_CLIENT_URL }); + await instance.init(); + return instance; } @@ -244,7 +252,7 @@ export class BiconomySmartAccountV2 extends BaseSmartAccount { return "0x"; } - async signUserOp(userOp: Partial, params?: ModuleInfo): Promise { + async signUserOp(userOp: Partial, params?: SendUserOpParams): Promise { this.isActiveValidationModuleDefined(); const requiredFields: UserOperationKey[] = [ "sender", @@ -300,32 +308,69 @@ export class BiconomySmartAccountV2 extends BaseSmartAccount { * @description This function call will take 'unsignedUserOp' as an input, sign it with the owner key, and send it to the bundler. * @returns Promise */ - async sendUserOp(userOp: Partial, params?: ModuleInfo): Promise { + async sendUserOp(userOp: Partial, params?: SendUserOpParams): Promise { Logger.log("userOp received in base account ", userOp); delete userOp.signature; const userOperation = await this.signUserOp(userOp, params); - const bundlerResponse = await this.sendSignedUserOp(userOperation); + const bundlerResponse = await this.sendSignedUserOp(userOperation, params); return bundlerResponse; } + private async getBuildUserOpNonce(nonceOptions: NonceOptions | undefined): Promise { + let nonce = BigNumber.from(0); + try { + if (nonceOptions?.nonceOverride) { + nonce = BigNumber.from(nonceOptions?.nonceOverride); + } else { + const _nonceSpace = nonceOptions?.nonceKey ?? 0; + nonce = await this.getNonce(_nonceSpace); + } + } catch (error) { + // Not throwing this error as nonce would be 0 if this.getNonce() throw exception, which is expected flow for undeployed account + Logger.log("Error while getting nonce for the account. This is expected for undeployed accounts set nonce to 0"); + } + return nonce; + } + + private async getGasFeeValues( + overrides: Overrides | undefined, + skipBundlerGasEstimation: boolean | undefined, + ): Promise<{ maxFeePerGas?: BigNumberish | undefined; maxPriorityFeePerGas?: BigNumberish | undefined }> { + const gasFeeValues = { + maxFeePerGas: overrides?.maxFeePerGas, + maxPriorityFeePerGas: overrides?.maxPriorityFeePerGas, + }; + try { + if (this.bundler && !gasFeeValues.maxFeePerGas && !gasFeeValues.maxPriorityFeePerGas && (skipBundlerGasEstimation ?? true)) { + const gasFeeEstimation = await this.bundler.getGasFeeValues(); + gasFeeValues.maxFeePerGas = gasFeeEstimation.maxFeePerGas; + gasFeeValues.maxPriorityFeePerGas = gasFeeEstimation.maxPriorityFeePerGas; + } + return gasFeeValues; + } catch (error: any) { + Logger.error("Error while getting gasFeeValues from bundler. Provided bundler might not have getGasFeeValues endpoint", error); + return gasFeeValues; + } + } + async buildUserOp(transactions: Transaction[], buildUseropDto?: BuildUserOpOptions): Promise> { 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")); - // Queue promises to fetch independent data. - const nonceFetchPromise = (async () => { - const _nonceSpace = buildUseropDto?.nonceOptions?.nonceKey ?? 0; - const nonce = await this.getNonce(_nonceSpace); - return nonce; - })(); const initCodeFetchPromise = this.getInitCode(); const dummySignatureFetchPromise = this.getDummySignature(buildUseropDto?.params); + const [nonceFromFetch, initCode, signature, finalGasFeeValue] = await Promise.all([ + this.getBuildUserOpNonce(buildUseropDto?.nonceOptions), + initCodeFetchPromise, + dummySignatureFetchPromise, + this.getGasFeeValues(buildUseropDto?.overrides, buildUseropDto?.skipBundlerGasEstimation), + ]); + if (transactions.length === 0) { throw new Error("Transactions array cannot be empty"); } - let callData = ""; if (transactions.length > 1 || buildUseropDto?.forceEncodeForBatch) { callData = await this.encodeExecuteBatch(to, value, data); @@ -334,34 +379,27 @@ export class BiconomySmartAccountV2 extends BaseSmartAccount { callData = await this.encodeExecute(to[0], value[0], data[0]); } - let nonce = BigNumber.from(0); - try { - if (buildUseropDto?.nonceOptions?.nonceOverride) { - nonce = BigNumber.from(buildUseropDto?.nonceOptions?.nonceOverride); - } else { - nonce = await nonceFetchPromise; - } - } catch (error) { - // Not throwing this error as nonce would be 0 if this.getNonce() throw exception, which is expected flow for undeployed account - } - let userOp: Partial = { sender: await this.getAccountAddress(), - nonce, - initCode: await initCodeFetchPromise, + nonce: nonceFromFetch, + initCode, callData: callData, + maxFeePerGas: finalGasFeeValue.maxFeePerGas || undefined, + maxPriorityFeePerGas: finalGasFeeValue.maxPriorityFeePerGas || undefined, }; // for this Smart Account current validation module dummy signature will be used to estimate gas - userOp.signature = await dummySignatureFetchPromise; + userOp.signature = signature; // Note: Can change the default behaviour of calling estimations using bundler/local - userOp = await this.estimateUserOpGas(userOp, buildUseropDto?.overrides, buildUseropDto?.skipBundlerGasEstimation); + userOp = await this.estimateUserOpGas( + userOp, + buildUseropDto?.overrides, + buildUseropDto?.skipBundlerGasEstimation, + buildUseropDto?.paymasterServiceData, + ); 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) - return userOp; } @@ -460,26 +498,11 @@ export class BiconomySmartAccountV2 extends BaseSmartAccount { newCallData = await this.encodeExecuteBatch(batchTo, batchValue, batchData); } - let finalUserOp: Partial = { + const finalUserOp: Partial = { ...userOp, callData: newCallData, }; - // Requesting to update gas limits again (especially callGasLimit needs to be re-calculated) - try { - finalUserOp = await this.estimateUserOpGas(finalUserOp); - const callGasLimit = ethers.BigNumber.from(finalUserOp.callGasLimit); - if (finalUserOp.callGasLimit && callGasLimit.lt(ethers.BigNumber.from("21000"))) { - return { - ...userOp, - callData: newCallData, - }; - } - 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"); - } return finalUserOp; } } catch (error) { @@ -490,7 +513,7 @@ export class BiconomySmartAccountV2 extends BaseSmartAccount { return userOp; } - async signUserOpHash(userOpHash: string, params?: ModuleInfo): Promise { + async signUserOpHash(userOpHash: string, params?: SendUserOpParams): Promise { this.isActiveValidationModuleDefined(); const moduleSig = await this.activeValidationModule.signUserOpHash(userOpHash, params); diff --git a/packages/account/src/SmartAccount.ts b/packages/account/src/SmartAccount.ts index fcc57a242..b23420398 100644 --- a/packages/account/src/SmartAccount.ts +++ b/packages/account/src/SmartAccount.ts @@ -10,7 +10,8 @@ import { IBundler, UserOpResponse } from "@biconomy/bundler"; import { IPaymaster, PaymasterAndDataResponse } from "@biconomy/paymaster"; import { Logger } from "@biconomy/common"; import { IEntryPoint } from "@account-abstraction/contracts"; -import { SmartAccountConfig, Overrides } from "./utils/Types"; +import { SponsorUserOperationDto, BiconomyPaymaster, IHybridPaymaster, PaymasterMode } from "@biconomy/paymaster"; +import { SmartAccountConfig, Overrides, SendUserOpDto } from "./utils/Types"; type UserOperationKey = keyof UserOperation; @@ -48,7 +49,7 @@ export abstract class SmartAccount implements ISmartAccount { private validateUserOp(userOp: Partial, requiredFields: UserOperationKey[]): boolean { for (const field of requiredFields) { if (!userOp[field]) { - throw new Error(`${field} is missing`); + throw new Error(`${String(field)} is missing in the UserOp`); } } return true; @@ -102,12 +103,13 @@ export abstract class SmartAccount implements ISmartAccount { userOp: Partial, overrides?: Overrides, skipBundlerGasEstimation?: boolean, + paymasterServiceData?: SponsorUserOperationDto, ): Promise> { const requiredFields: UserOperationKey[] = ["sender", "nonce", "initCode", "callData"]; this.validateUserOp(userOp, requiredFields); let finalUserOp = userOp; - const skipBundlerCall = skipBundlerGasEstimation ?? false; + const skipBundlerCall = skipBundlerGasEstimation ?? true; // Override gas values in userOp if provided in overrides params if (overrides) { userOp = { ...userOp, ...overrides }; @@ -115,17 +117,33 @@ export abstract class SmartAccount implements ISmartAccount { 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 no bundler url is provided run offchain logic to assign following values of UserOp - // maxFeePerGas, maxPriorityFeePerGas, verificationGasLimit, callGasLimit, preVerificationGas - finalUserOp = await this.calculateUserOpGasValues(userOp); + if (skipBundlerCall) { + if (this.paymaster && this.paymaster instanceof BiconomyPaymaster && paymasterServiceData?.mode === PaymasterMode.SPONSORED) { + if (!userOp.maxFeePerGas && !userOp.maxPriorityFeePerGas) { + throw new Error("maxFeePerGas and maxPriorityFeePerGas are required for skipBundlerCall mode"); + } + // Making call to paymaster to get gas estimations for userOp + const { callGasLimit, verificationGasLimit, preVerificationGas, paymasterAndData } = await ( + this.paymaster as IHybridPaymaster + ).getPaymasterAndData(userOp, paymasterServiceData); + finalUserOp.verificationGasLimit = verificationGasLimit ?? userOp.verificationGasLimit; + finalUserOp.callGasLimit = callGasLimit ?? userOp.callGasLimit; + finalUserOp.preVerificationGas = preVerificationGas ?? userOp.preVerificationGas; + finalUserOp.paymasterAndData = paymasterAndData ?? userOp.paymasterAndData; + } else { + Logger.warn("Skipped paymaster call. If you are using paymasterAndData, generate data externally"); + finalUserOp = await this.calculateUserOpGasValues(userOp); + finalUserOp.paymasterAndData = "0x"; + } } else { + if (!this.bundler) throw new Error("Bundler is not provided"); + // TODO: is this still needed to delete? 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 neither user sent gas fee nor the bundler, estimate gas from provider if (!userOp.maxFeePerGas && !userOp.maxPriorityFeePerGas && (!maxFeePerGas || !maxPriorityFeePerGas)) { const feeData = await this.provider.getFeeData(); finalUserOp.maxFeePerGas = feeData.maxFeePerGas ?? feeData.gasPrice ?? (await this.provider.getGasPrice()); @@ -137,6 +155,7 @@ export abstract class SmartAccount implements ISmartAccount { finalUserOp.verificationGasLimit = verificationGasLimit ?? userOp.verificationGasLimit; finalUserOp.callGasLimit = callGasLimit ?? userOp.callGasLimit; finalUserOp.preVerificationGas = preVerificationGas ?? userOp.preVerificationGas; + finalUserOp.paymasterAndData = "0x"; } return finalUserOp; } @@ -239,11 +258,11 @@ export abstract class SmartAccount implements ISmartAccount { * @description This function call will take 'unsignedUserOp' as an input, sign it with the owner key, and send it to the bundler. * @returns Promise */ - async sendUserOp(userOp: Partial): Promise { + async sendUserOp(userOp: Partial, params?: SendUserOpDto): Promise { Logger.log("userOp received in base account ", userOp); delete userOp.signature; const userOperation = await this.signUserOp(userOp); - const bundlerResponse = await this.sendSignedUserOp(userOperation); + const bundlerResponse = await this.sendSignedUserOp(userOperation, params); return bundlerResponse; } @@ -253,7 +272,7 @@ export abstract class SmartAccount implements ISmartAccount { * @description This function call will take 'signedUserOp' as input and send it to the bundler * @returns */ - async sendSignedUserOp(userOp: UserOperation): Promise { + async sendSignedUserOp(userOp: UserOperation, params?: SendUserOpDto): Promise { const requiredFields: UserOperationKey[] = [ "sender", "nonce", @@ -271,7 +290,7 @@ export abstract class SmartAccount implements ISmartAccount { 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); + const bundlerResponse = await this.bundler.sendUserOp(userOp, params); return bundlerResponse; } } diff --git a/packages/account/src/index.ts b/packages/account/src/index.ts index 784f36f10..d43249476 100644 --- a/packages/account/src/index.ts +++ b/packages/account/src/index.ts @@ -6,3 +6,4 @@ export * from "./SmartAccount"; export * from "./BiconomySmartAccount"; export * from "./utils/Constants"; export * from "./BiconomySmartAccountV2"; +export * from "./utils/VoidSigner"; diff --git a/packages/account/src/utils/Types.ts b/packages/account/src/utils/Types.ts index 5e4c578e7..250d69c47 100644 --- a/packages/account/src/utils/Types.ts +++ b/packages/account/src/utils/Types.ts @@ -2,7 +2,7 @@ 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 { IPaymaster, PaymasterFeeQuote, SponsorUserOperationDto } from "@biconomy/paymaster"; import { BaseValidationModule, ModuleInfo } from "@biconomy/modules"; import { Provider } from "@ethersproject/providers"; import { GasOverheads } from "./Preverificaiton"; @@ -80,6 +80,7 @@ export type BuildUserOpOptions = { params?: ModuleInfo; nonceOptions?: NonceOptions; forceEncodeForBatch?: boolean; + paymasterServiceData?: SponsorUserOperationDto; }; export type NonceOptions = { @@ -87,6 +88,19 @@ export type NonceOptions = { nonceOverride?: number; }; +// Used in AccountV1 +export type SendUserOpDto = { + signer?: Signer; + simulationType?: SimulationType; +}; + +// Generic options in AccountV2 +export type SendUserOpOptions = { + simulationType?: SimulationType; +}; + +export type SimulationType = "validation" | "validation_and_execution"; + export type Overrides = { callGasLimit?: BigNumberish; verificationGasLimit?: BigNumberish; diff --git a/packages/account/src/utils/VoidSigner.ts b/packages/account/src/utils/VoidSigner.ts new file mode 100644 index 000000000..d028c56ad --- /dev/null +++ b/packages/account/src/utils/VoidSigner.ts @@ -0,0 +1,57 @@ +import { Provider, TransactionRequest } from "@ethersproject/providers"; +import { BigNumberish, BytesLike, Bytes, Signer } from "ethers"; +import { LogLevel, Logger } from "@ethersproject/logger"; +const logger = new Logger("signer"); + +export interface TypedDataDomain { + name?: string; + version?: string; + chainId?: BigNumberish; + verifyingContract?: string; + salt?: BytesLike; +} + +export interface TypedDataField { + name: string; + type: string; +} + +export type Deferrable = { + [K in keyof T]: T[K] | Promise; +}; + +export class VoidSigner extends Signer { + readonly address: string; + + readonly provider?: Provider; + + constructor(_address: string, _provider?: Provider) { + super(); + this.address = _address; + this.provider = _provider; + } + + getAddress(): Promise { + return Promise.resolve(this.address); + } + + _fail(message: string, operation: string): Promise { + return Promise.resolve().then(() => { + logger.throwError(message, Logger.errors.UNSUPPORTED_OPERATION, { operation: operation }); + }); + } + + signMessage(message: Bytes | string): Promise { + logger._log(LogLevel.INFO, [message]); + return this._fail("VoidSigner cannot sign messages", "signMessage"); + } + + signTransaction(transaction: Deferrable): Promise { + logger._log(LogLevel.INFO, [transaction]); + return this._fail("VoidSigner cannot sign transactions", "signTransaction"); + } + + connect(provider: Provider): VoidSigner { + return new VoidSigner(this.address, provider); + } +} diff --git a/packages/account/tests/SmartAccountV2.local.spec.ts b/packages/account/tests/SmartAccountV2.local.spec.ts index 0ebc9da2a..cea9f406c 100644 --- a/packages/account/tests/SmartAccountV2.local.spec.ts +++ b/packages/account/tests/SmartAccountV2.local.spec.ts @@ -1,5 +1,5 @@ import { EntryPoint, EntryPoint__factory, UserOperationStruct, SimpleAccountFactory__factory } from "@account-abstraction/contracts"; -import { Wallet, ethers } from "ethers"; +import { VoidSigner, Wallet, ethers } from "ethers"; import { SampleRecipient, SampleRecipient__factory } from "@account-abstraction/utils/dist/src/types"; import { @@ -81,10 +81,6 @@ describe("BiconomySmartAccountV2 API Specs", () => { // console.log('account api provider ', accountAPI.provider) - accountAPI = await accountAPI.init(); - - console.log("Account address ", accountAPI.accountAddress); - const counterFactualAddress = await accountAPI.getAccountAddress(); console.log("Counterfactual address ", counterFactualAddress); @@ -144,7 +140,7 @@ describe("BiconomySmartAccountV2 API Specs", () => { // ((await expect(entryPoint.handleOps([signedUserOp], beneficiary))) as any).to.emit(recipient, "Sender"); expect(await provider.getCode(accountAddress).then((code) => code.length)).toBeGreaterThan(0); - }); + }, 10000); // on github runner it takes more time than 5000ms // TODO // possibly use local bundler API from image @@ -337,6 +333,31 @@ describe("BiconomySmartAccountV2 API Specs", () => { // ((await expect(entryPoint.handleOps([signedUserOp], beneficiary))) as any).to.emit(recipient, "Sender"); }, 10000); // on github runner it takes more time than 5000ms + it("Creates another replicated instance using void signer", async () => { + const newmodule = await ECDSAOwnershipValidationModule.create({ + signer: new VoidSigner(await owner.getAddress()), + moduleAddress: ecdsaModule.address, + }); + + const accountAPI2 = await BiconomySmartAccountV2.create({ + chainId: ChainId.GANACHE, + rpcUrl: "http://127.0.0.1:8545", + // paymaster: paymaster, + // bundler: bundler, + entryPointAddress: entryPoint.address, + factoryAddress: accountFactory.address, + implementationAddress: accountAPI.getImplementationAddress(), + defaultFallbackHandler: await accountFactory.minimalHandler(), + defaultValidationModule: newmodule, + activeValidationModule: newmodule, + }); + + const address = await accountAPI2.getAccountAddress(); + console.log("account address ", address); + + expect(address).toBe(accountAPI.accountAddress); + }, 10000); + // TODO // 1. sendSignedUserOp() // 2. sendUserOp() diff --git a/packages/bundler/src/Bundler.ts b/packages/bundler/src/Bundler.ts index 24399febf..43668d25e 100644 --- a/packages/bundler/src/Bundler.ts +++ b/packages/bundler/src/Bundler.ts @@ -1,7 +1,7 @@ import { IBundler } from "./interfaces/IBundler"; import { UserOperation, ChainId } from "@biconomy/core-types"; import { - GetUserOperationResponse, + GetUserOperationReceiptResponse, GetUserOpByHashResponse, Bundlerconfig, UserOpResponse, @@ -10,11 +10,21 @@ import { SendUserOpResponse, UserOpGasResponse, UserOpByHashResponse, + SendUserOpOptions, + GetGasFeeValuesResponse, + GasFeeValues, + UserOpStatus, + GetUserOperationStatusResponse, } 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 { + UserOpReceiptIntervals, + UserOpWaitForTxHashIntervals, + UserOpWaitForTxHashMaxDurationIntervals, + UserOpReceiptMaxDurationIntervals, +} from "./utils/Constants"; import { JsonRpcProvider } from "@ethersproject/providers"; /** @@ -24,13 +34,34 @@ import { JsonRpcProvider } from "@ethersproject/providers"; */ export class Bundler implements IBundler { // eslint-disable-next-line no-unused-vars - UserOpReceiptIntervals: { [key in ChainId]?: number }; + UserOpReceiptIntervals!: { [key in ChainId]?: number }; + + UserOpWaitForTxHashIntervals!: { [key in ChainId]?: number }; + + UserOpReceiptMaxDurationIntervals!: { [key in ChainId]?: number }; + + UserOpWaitForTxHashMaxDurationIntervals!: { [key in ChainId]?: number }; constructor(readonly bundlerConfig: Bundlerconfig) { this.UserOpReceiptIntervals = { ...UserOpReceiptIntervals, ...bundlerConfig.userOpReceiptIntervals, }; + + this.UserOpWaitForTxHashIntervals = { + ...UserOpWaitForTxHashIntervals, + ...bundlerConfig.userOpWaitForTxHashIntervals, + }; + + this.UserOpReceiptMaxDurationIntervals = { + ...UserOpReceiptMaxDurationIntervals, + ...bundlerConfig.userOpReceiptMaxDurationIntervals, + }; + + this.UserOpWaitForTxHashMaxDurationIntervals = { + ...UserOpWaitForTxHashMaxDurationIntervals, + ...bundlerConfig.userOpWaitForTxHashMaxDurationIntervals, + }; } private getBundlerUrl(): string { @@ -78,12 +109,15 @@ export class Bundler implements IBundler { * @description This function will send signed userOp to bundler to get mined on chain * @returns Promise */ - async sendUserOp(userOp: UserOperation): Promise { + async sendUserOp(userOp: UserOperation, simulationParam?: SendUserOpOptions): Promise { 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 simType = { + simulation_type: simulationParam?.simulationType || "validation", + }; + const params = [hexifiedUserOp, this.bundlerConfig.entryPointAddress, simType]; const bundlerUrl = this.getBundlerUrl(); const sendUserOperationResponse: SendUserOpResponse = await sendRequest({ url: bundlerUrl, @@ -99,7 +133,12 @@ export class Bundler implements IBundler { userOpHash: sendUserOperationResponse.result, wait: (confirmations?: number): Promise => { const provider = new JsonRpcProvider(RPC_PROVIDER_URLS[chainId]); + // Note: maxDuration can be defined per chainId + const maxDuration = this.UserOpReceiptMaxDurationIntervals[chainId] || 30000; // default 30 seconds + let totalDuration = 0; + return new Promise((resolve, reject) => { + const intervalValue = this.UserOpReceiptIntervals[chainId] || 5000; // default 5 seconds const intervalId = setInterval(async () => { try { const userOpResponse = await this.getUserOpReceipt(sendUserOperationResponse.result); @@ -119,7 +158,52 @@ export class Bundler implements IBundler { clearInterval(intervalId); reject(error); } - }, this.UserOpReceiptIntervals[chainId]); + + totalDuration += intervalValue; + if (totalDuration >= maxDuration) { + clearInterval(intervalId); + reject( + new Error( + `Exceeded maximum duration (${maxDuration / 1000} sec) waiting to get receipt for userOpHash ${ + sendUserOperationResponse.result + }. Try getting the receipt manually using eth_getUserOperationReceipt rpc method on bundler`, + ), + ); + } + }, intervalValue); + }); + }, + waitForTxHash: (): Promise => { + const maxDuration = this.UserOpWaitForTxHashMaxDurationIntervals[chainId] || 20000; // default 20 seconds + let totalDuration = 0; + + return new Promise((resolve, reject) => { + const intervalValue = this.UserOpWaitForTxHashIntervals[chainId] || 500; // default 0.5 seconds + const intervalId = setInterval(() => { + this.getUserOpStatus(sendUserOperationResponse.result) + .then((userOpStatus) => { + if (userOpStatus && userOpStatus.state && userOpStatus.transactionHash) { + clearInterval(intervalId); + resolve(userOpStatus); + } + }) + .catch((error) => { + clearInterval(intervalId); + reject(error); + }); + + totalDuration += intervalValue; + if (totalDuration >= maxDuration) { + clearInterval(intervalId); + reject( + new Error( + `Exceeded maximum duration (${maxDuration / 1000} sec) waiting to get receipt for userOpHash ${ + sendUserOperationResponse.result + }. Try getting the receipt manually using eth_getUserOperationReceipt rpc method on bundler`, + ), + ); + } + }, intervalValue); }); }, }; @@ -134,7 +218,7 @@ export class Bundler implements IBundler { */ async getUserOpReceipt(userOpHash: string): Promise { const bundlerUrl = this.getBundlerUrl(); - const response: GetUserOperationResponse = await sendRequest({ + const response: GetUserOperationReceiptResponse = await sendRequest({ url: bundlerUrl, method: HttpMethod.Post, body: { @@ -148,6 +232,28 @@ export class Bundler implements IBundler { return userOpReceipt; } + /** + * + * @param userOpHash + * @description This function will return userOpReceipt for a given userOpHash + * @returns Promise + */ + async getUserOpStatus(userOpHash: string): Promise { + const bundlerUrl = this.getBundlerUrl(); + const response: GetUserOperationStatusResponse = await sendRequest({ + url: bundlerUrl, + method: HttpMethod.Post, + body: { + method: "biconomy_getUserOperationStatus", + params: [userOpHash], + id: getTimestampInSeconds(), + jsonrpc: "2.0", + }, + }); + const userOpStatus: UserOpStatus = response.result; + return userOpStatus; + } + /** * * @param userOpHash @@ -170,4 +276,22 @@ export class Bundler implements IBundler { const userOpByHashResponse: UserOpByHashResponse = response.result; return userOpByHashResponse; } + + /** + * @description This function will return the gas fee values + */ + async getGasFeeValues(): Promise { + const bundlerUrl = this.getBundlerUrl(); + const response: GetGasFeeValuesResponse = await sendRequest({ + url: bundlerUrl, + method: HttpMethod.Post, + body: { + method: "biconomy_getGasFeeValues", + params: [], + id: getTimestampInSeconds(), + jsonrpc: "2.0", + }, + }); + return response.result; + } } diff --git a/packages/bundler/src/interfaces/IBundler.ts b/packages/bundler/src/interfaces/IBundler.ts index a64c1151d..bf98a39e5 100644 --- a/packages/bundler/src/interfaces/IBundler.ts +++ b/packages/bundler/src/interfaces/IBundler.ts @@ -1,9 +1,19 @@ -import { UserOpResponse, UserOpGasResponse, UserOpReceipt, UserOpByHashResponse } from "../utils/Types"; +import { + UserOpResponse, + UserOpGasResponse, + UserOpReceipt, + UserOpByHashResponse, + SendUserOpOptions, + GasFeeValues, + UserOpStatus, +} from "../utils/Types"; import { UserOperation } from "@biconomy/core-types"; export interface IBundler { estimateUserOpGas(_userOp: Partial): Promise; - sendUserOp(_userOp: UserOperation): Promise; + sendUserOp(_userOp: UserOperation, _simulationParam?: SendUserOpOptions): Promise; getUserOpReceipt(_userOpHash: string): Promise; getUserOpByHash(_userOpHash: string): Promise; + getGasFeeValues(): Promise; + getUserOpStatus(_userOpHash: string): Promise; } diff --git a/packages/bundler/src/utils/Constants.ts b/packages/bundler/src/utils/Constants.ts index 13f89d7b3..7892814a1 100644 --- a/packages/bundler/src/utils/Constants.ts +++ b/packages/bundler/src/utils/Constants.ts @@ -3,26 +3,125 @@ import { ChainId } from "@biconomy/core-types"; // eslint-disable-next-line no-unused-vars export const UserOpReceiptIntervals: { [key in ChainId]?: number } = { [ChainId.MAINNET]: 10000, - [ChainId.GOERLI]: 5000, - [ChainId.POLYGON_MUMBAI]: 5000, - [ChainId.POLYGON_MAINNET]: 5000, - [ChainId.BSC_TESTNET]: 5000, - [ChainId.BSC_MAINNET]: 5000, - [ChainId.POLYGON_ZKEVM_TESTNET]: 5000, - [ChainId.POLYGON_ZKEVM_MAINNET]: 5000, - [ChainId.ARBITRUM_GOERLI_TESTNET]: 5000, - [ChainId.ARBITRUM_ONE_MAINNET]: 5000, - [ChainId.ARBITRUM_NOVA_MAINNET]: 5000, - [ChainId.OPTIMISM_MAINNET]: 5000, - [ChainId.OPTIMISM_GOERLI_TESTNET]: 5000, - [ChainId.AVALANCHE_MAINNET]: 5000, - [ChainId.AVALANCHE_TESTNET]: 5000, - [ChainId.MOONBEAM_MAINNET]: 5000, - [ChainId.BASE_GOERLI_TESTNET]: 5000, - [ChainId.BASE_MAINNET]: 5000, - [ChainId.LINEA_TESTNET]: 5000, - [ChainId.MANTLE_MAINNET]: 5000, - [ChainId.MANTLE_TESTNET]: 5000, - [ChainId.OPBNB_MAINNET]: 5000, - [ChainId.OPBNB_TESTNET]: 5000, + [ChainId.GOERLI]: 2000, + [ChainId.POLYGON_MUMBAI]: 2000, + [ChainId.POLYGON_MAINNET]: 2000, + [ChainId.BSC_TESTNET]: 2000, + [ChainId.BSC_MAINNET]: 2000, + [ChainId.POLYGON_ZKEVM_TESTNET]: 2000, + [ChainId.POLYGON_ZKEVM_MAINNET]: 2000, + [ChainId.ARBITRUM_GOERLI_TESTNET]: 2000, + [ChainId.ARBITRUM_ONE_MAINNET]: 2000, + [ChainId.ARBITRUM_NOVA_MAINNET]: 2000, + [ChainId.OPTIMISM_MAINNET]: 2000, + [ChainId.OPTIMISM_GOERLI_TESTNET]: 2000, + [ChainId.AVALANCHE_MAINNET]: 2000, + [ChainId.AVALANCHE_TESTNET]: 2000, + [ChainId.MOONBEAM_MAINNET]: 2000, + [ChainId.BASE_GOERLI_TESTNET]: 2000, + [ChainId.BASE_MAINNET]: 2000, + [ChainId.LINEA_TESTNET]: 2000, + [ChainId.LINEA_MAINNET]: 2000, + [ChainId.MANTLE_MAINNET]: 2000, + [ChainId.MANTLE_TESTNET]: 2000, + [ChainId.OPBNB_MAINNET]: 2000, + [ChainId.OPBNB_TESTNET]: 2000, + [ChainId.ASTAR_MAINNET]: 2000, + [ChainId.ASTAR_TESTNET]: 2000, + [ChainId.CHILIZ_MAINNET]: 2000, + [ChainId.CHILIZ_TESTNET]: 2000, +}; + +// Note: Reduced by 1/10th.. can reduce more +export const UserOpWaitForTxHashIntervals: { [key in ChainId]?: number } = { + [ChainId.MAINNET]: 1000, + [ChainId.GOERLI]: 500, + [ChainId.POLYGON_MUMBAI]: 500, + [ChainId.POLYGON_MAINNET]: 500, + [ChainId.BSC_TESTNET]: 500, + [ChainId.BSC_MAINNET]: 500, + [ChainId.POLYGON_ZKEVM_TESTNET]: 500, + [ChainId.POLYGON_ZKEVM_MAINNET]: 500, + [ChainId.ARBITRUM_GOERLI_TESTNET]: 500, + [ChainId.ARBITRUM_ONE_MAINNET]: 500, + [ChainId.ARBITRUM_NOVA_MAINNET]: 500, + [ChainId.OPTIMISM_MAINNET]: 500, + [ChainId.OPTIMISM_GOERLI_TESTNET]: 500, + [ChainId.AVALANCHE_MAINNET]: 500, + [ChainId.AVALANCHE_TESTNET]: 500, + [ChainId.MOONBEAM_MAINNET]: 500, + [ChainId.BASE_GOERLI_TESTNET]: 500, + [ChainId.BASE_MAINNET]: 500, + [ChainId.LINEA_TESTNET]: 500, + [ChainId.LINEA_MAINNET]: 500, + [ChainId.MANTLE_MAINNET]: 500, + [ChainId.MANTLE_TESTNET]: 500, + [ChainId.OPBNB_MAINNET]: 500, + [ChainId.OPBNB_TESTNET]: 500, + [ChainId.ASTAR_MAINNET]: 500, + [ChainId.ASTAR_TESTNET]: 500, + [ChainId.CHILIZ_MAINNET]: 500, + [ChainId.CHILIZ_TESTNET]: 500, +}; + +export const UserOpReceiptMaxDurationIntervals: { [key in ChainId]?: number } = { + [ChainId.MAINNET]: 300000, + [ChainId.GOERLI]: 30000, + [ChainId.POLYGON_MUMBAI]: 30000, + [ChainId.POLYGON_MAINNET]: 30000, + [ChainId.BSC_TESTNET]: 30000, + [ChainId.BSC_MAINNET]: 30000, + [ChainId.POLYGON_ZKEVM_TESTNET]: 30000, + [ChainId.POLYGON_ZKEVM_MAINNET]: 30000, + [ChainId.ARBITRUM_GOERLI_TESTNET]: 30000, + [ChainId.ARBITRUM_ONE_MAINNET]: 30000, + [ChainId.ARBITRUM_NOVA_MAINNET]: 30000, + [ChainId.OPTIMISM_MAINNET]: 30000, + [ChainId.OPTIMISM_GOERLI_TESTNET]: 30000, + [ChainId.AVALANCHE_MAINNET]: 30000, + [ChainId.AVALANCHE_TESTNET]: 30000, + [ChainId.MOONBEAM_MAINNET]: 30000, + [ChainId.BASE_GOERLI_TESTNET]: 30000, + [ChainId.BASE_MAINNET]: 30000, + [ChainId.LINEA_TESTNET]: 30000, + [ChainId.LINEA_MAINNET]: 30000, + [ChainId.MANTLE_MAINNET]: 30000, + [ChainId.MANTLE_TESTNET]: 30000, + [ChainId.OPBNB_MAINNET]: 30000, + [ChainId.OPBNB_TESTNET]: 30000, + [ChainId.ASTAR_MAINNET]: 30000, + [ChainId.ASTAR_TESTNET]: 30000, + [ChainId.CHILIZ_MAINNET]: 30000, + [ChainId.CHILIZ_TESTNET]: 30000, +}; + +export const UserOpWaitForTxHashMaxDurationIntervals: { [key in ChainId]?: number } = { + [ChainId.MAINNET]: 20000, + [ChainId.GOERLI]: 20000, + [ChainId.POLYGON_MUMBAI]: 20000, + [ChainId.POLYGON_MAINNET]: 20000, + [ChainId.BSC_TESTNET]: 20000, + [ChainId.BSC_MAINNET]: 20000, + [ChainId.POLYGON_ZKEVM_TESTNET]: 20000, + [ChainId.POLYGON_ZKEVM_MAINNET]: 20000, + [ChainId.ARBITRUM_GOERLI_TESTNET]: 20000, + [ChainId.ARBITRUM_ONE_MAINNET]: 20000, + [ChainId.ARBITRUM_NOVA_MAINNET]: 20000, + [ChainId.OPTIMISM_MAINNET]: 20000, + [ChainId.OPTIMISM_GOERLI_TESTNET]: 20000, + [ChainId.AVALANCHE_MAINNET]: 20000, + [ChainId.AVALANCHE_TESTNET]: 20000, + [ChainId.MOONBEAM_MAINNET]: 20000, + [ChainId.BASE_GOERLI_TESTNET]: 20000, + [ChainId.BASE_MAINNET]: 20000, + [ChainId.LINEA_TESTNET]: 20000, + [ChainId.LINEA_MAINNET]: 20000, + [ChainId.MANTLE_MAINNET]: 20000, + [ChainId.MANTLE_TESTNET]: 20000, + [ChainId.OPBNB_MAINNET]: 20000, + [ChainId.OPBNB_TESTNET]: 20000, + [ChainId.ASTAR_MAINNET]: 20000, + [ChainId.ASTAR_TESTNET]: 20000, + [ChainId.CHILIZ_MAINNET]: 20000, + [ChainId.CHILIZ_TESTNET]: 20000, }; diff --git a/packages/bundler/src/utils/Types.ts b/packages/bundler/src/utils/Types.ts index 17e1e8def..c1af046ed 100644 --- a/packages/bundler/src/utils/Types.ts +++ b/packages/bundler/src/utils/Types.ts @@ -7,6 +7,9 @@ export type Bundlerconfig = { chainId: ChainId; // eslint-disable-next-line no-unused-vars userOpReceiptIntervals?: { [key in ChainId]?: number }; + userOpWaitForTxHashIntervals?: { [key in ChainId]?: number }; + userOpReceiptMaxDurationIntervals?: { [key in ChainId]?: number }; + userOpWaitForTxHashMaxDurationIntervals?: { [key in ChainId]?: number }; }; export type UserOpReceipt = { @@ -23,14 +26,34 @@ export type UserOpReceipt = { receipt: ethers.providers.TransactionReceipt; }; +// review +export type UserOpStatus = { + state: string; // for now // could be an enum + transactionHash?: string; + userOperationReceipt?: UserOpReceipt; +}; + +export type SendUserOpOptions = { + simulationType?: SimulationType; +}; + +export type SimulationType = "validation" | "validation_and_execution"; + // Converted to JsonRpcResponse with strict type -export type GetUserOperationResponse = { +export type GetUserOperationReceiptResponse = { jsonrpc: string; id: number; result: UserOpReceipt; error?: JsonRpcError; }; +export type GetUserOperationStatusResponse = { + jsonrpc: string; + id: number; + result: UserOpStatus; + error?: JsonRpcError; +}; + // Converted to JsonRpcResponse with strict type export type SendUserOpResponse = { jsonrpc: string; @@ -42,6 +65,8 @@ export type SendUserOpResponse = { export type UserOpResponse = { userOpHash: string; wait(_confirmations?: number): Promise; + // Review: waitForTxHash(): vs waitForTxHash?(): + waitForTxHash(): Promise; }; // Converted to JsonRpcResponse with strict type @@ -80,3 +105,14 @@ export type JsonRpcError = { message: string; data: any; }; + +export type GetGasFeeValuesResponse = { + jsonrpc: string; + id: number; + result: GasFeeValues; + error?: JsonRpcError; +}; +export type GasFeeValues = { + maxPriorityFeePerGas: string; + maxFeePerGas: string; +}; diff --git a/packages/common/CHANGELOG.md b/packages/common/CHANGELOG.md index 6b9a5ff10..704bd526f 100644 --- a/packages/common/CHANGELOG.md +++ b/packages/common/CHANGELOG.md @@ -82,7 +82,7 @@ VERSION bump only * 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)) +* skipBundlerGasEstimation 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)) diff --git a/packages/common/package.json b/packages/common/package.json index 1890c8719..5ce64628d 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -51,6 +51,7 @@ "concurrently": "^7.4.0", "debug": "^4.3.4", "ethers": "^5.7.0", + "node-fetch": "^2.7.0", "typechain": "^8.1.1" }, "devDependencies": { diff --git a/packages/common/src/Constants.ts b/packages/common/src/Constants.ts index 73c4a506b..4c291a810 100644 --- a/packages/common/src/Constants.ts +++ b/packages/common/src/Constants.ts @@ -23,8 +23,13 @@ export const RPC_PROVIDER_URLS: { [key in ChainId]?: string } = { [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.LINEA_MAINNET]: "https://rpc.linea.build", [ChainId.MANTLE_MAINNET]: "https://rpc.mantle.xyz", [ChainId.MANTLE_TESTNET]: "https://rpc.testnet.mantle.xyz", [ChainId.OPBNB_MAINNET]: "https://opbnb-mainnet-rpc.bnbchain.org", [ChainId.OPBNB_TESTNET]: "https://opbnb-testnet-rpc.bnbchain.org", + [ChainId.ASTAR_MAINNET]: "https://evm.astar.network", + [ChainId.ASTAR_TESTNET]: "https://evm.shibuya.astar.network", + [ChainId.CHILIZ_MAINNET]: "https://rpc.ankr.com/chiliz", + [ChainId.CHILIZ_TESTNET]: "https://spicy-rpc.chiliz.com", }; diff --git a/packages/common/src/httpRequests.ts b/packages/common/src/httpRequests.ts index 40f414ad7..d4923d2b6 100644 --- a/packages/common/src/httpRequests.ts +++ b/packages/common/src/httpRequests.ts @@ -1,3 +1,4 @@ +import fetch from "node-fetch"; import { Logger } from "./Logger"; export enum HttpMethod { diff --git a/packages/core-types/CHANGELOG.md b/packages/core-types/CHANGELOG.md index 59ab27456..3eca80798 100644 --- a/packages/core-types/CHANGELOG.md +++ b/packages/core-types/CHANGELOG.md @@ -67,7 +67,7 @@ VERSION bump only - 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)) +- skipBundlerGasEstimation 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) diff --git a/packages/core-types/src/ChainsTypes.ts b/packages/core-types/src/ChainsTypes.ts index b0491fcb8..6ab988d6f 100644 --- a/packages/core-types/src/ChainsTypes.ts +++ b/packages/core-types/src/ChainsTypes.ts @@ -1,31 +1,3 @@ -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", -} - -// NOTE: Update chainId for networks we're planning to support export enum ChainId { // Ethereum MAINNET = 1, @@ -47,9 +19,14 @@ export enum ChainId { BASE_GOERLI_TESTNET = 84531, BASE_MAINNET = 8453, LINEA_TESTNET = 59140, + LINEA_MAINNET = 59144, MANTLE_MAINNET = 5000, MANTLE_TESTNET = 5001, OPBNB_MAINNET = 204, OPBNB_TESTNET = 5611, + ASTAR_MAINNET = 592, + ASTAR_TESTNET = 81, + CHILIZ_MAINNET = 88888, + CHILIZ_TESTNET = 88882, GANACHE = 1337, //Temp } diff --git a/packages/modules/src/BatchedSessionRouterModule.ts b/packages/modules/src/BatchedSessionRouterModule.ts index a41a2a6a9..ffd273223 100644 --- a/packages/modules/src/BatchedSessionRouterModule.ts +++ b/packages/modules/src/BatchedSessionRouterModule.ts @@ -100,14 +100,7 @@ export class BatchedSessionRouterModule extends BaseValidationModule { // signer must be the same for all the sessions const sessionSigner = sessionParams[0].sessionSigner; - const userOpHashAndModuleAddress = ethers.utils.hexConcat([ - ethers.utils.hexZeroPad(userOpHash, 32), - ethers.utils.hexZeroPad(this.getSessionKeyManagerAddress(), 20), - ]); - - const resultingHash = ethers.utils.keccak256(userOpHashAndModuleAddress); - - const signature = await sessionSigner.signMessage(arrayify(resultingHash)); + const signature = await sessionSigner.signMessage(arrayify(userOpHash)); for (const sessionParam of sessionParams) { if (!sessionParam.sessionSigner) { diff --git a/packages/modules/src/SessionKeyManagerModule.ts b/packages/modules/src/SessionKeyManagerModule.ts index 92ff6c5b3..fcae0f383 100644 --- a/packages/modules/src/SessionKeyManagerModule.ts +++ b/packages/modules/src/SessionKeyManagerModule.ts @@ -7,9 +7,9 @@ import { SessionKeyManagerModuleConfig, ModuleVersion, CreateSessionDataParams, - StorageType, ModuleInfo, CreateSessionDataResponse, + StorageType, } from "./utils/Types"; import NodeClient from "@biconomy/node-client"; import INodeClient from "@biconomy/node-client"; @@ -67,10 +67,16 @@ export class SessionKeyManagerModule extends BaseValidationModule { txServiceUrl: moduleConfig.nodeClientUrl ?? NODE_CLIENT_URL, }); - if (!moduleConfig.storageType || moduleConfig.storageType === StorageType.LOCAL_STORAGE) { - instance.sessionStorageClient = new SessionLocalStorage(moduleConfig.smartAccountAddress); + if (moduleConfig.sessionStorageClient) { + instance.sessionStorageClient = moduleConfig.sessionStorageClient; } else { - throw new Error("Invalid storage type"); + switch (moduleConfig.storageType) { + case StorageType.LOCAL_STORAGE: + instance.sessionStorageClient = new SessionLocalStorage(moduleConfig.smartAccountAddress); + break; + default: + throw new Error("Invalid storage type"); + } } const existingSessionData = await instance.sessionStorageClient.getAllSessionData(); diff --git a/packages/modules/src/utils/Constants.ts b/packages/modules/src/utils/Constants.ts index 59b31e147..cab7efbef 100644 --- a/packages/modules/src/utils/Constants.ts +++ b/packages/modules/src/utils/Constants.ts @@ -27,10 +27,10 @@ export const SESSION_MANAGER_MODULE_ADDRESSES_BY_VERSION = { V1_0_1: "0x000002FbFfedd9B33F4E7156F2DE8D48945E7489", }; -export const DEFAULT_BATCHED_SESSION_ROUTER_MODULE = "0x000008dA71757C0E1D83CE56c823e25Aa49bC058"; +export const DEFAULT_BATCHED_SESSION_ROUTER_MODULE = "0x00000D09967410f8C76752A104c9848b57ebba55"; export const BATCHED_SESSION_ROUTER_MODULE_ADDRESSES_BY_VERSION = { - V1_0_0: "0x000008dA71757C0E1D83CE56c823e25Aa49bC058", + V1_0_0: "0x00000D09967410f8C76752A104c9848b57ebba55", }; export const DEFAULT_MULTICHAIN_MODULE = "0x000000824dc138db84FD9109fc154bdad332Aa8E"; diff --git a/packages/modules/src/utils/Types.ts b/packages/modules/src/utils/Types.ts index 1c4e65b01..34c7e8f04 100644 --- a/packages/modules/src/utils/Types.ts +++ b/packages/modules/src/utils/Types.ts @@ -1,6 +1,7 @@ import { ChainId, UserOperation } from "@biconomy/core-types"; import { Signer } from "ethers"; import { SessionKeyManagerModule } from "../SessionKeyManagerModule"; +import { ISessionStorage } from "interfaces/ISessionStorage"; export type ModuleVersion = "V1_0_0"; // | 'V1_0_1' @@ -20,6 +21,7 @@ export interface SessionKeyManagerModuleConfig extends BaseValidationModuleConfi nodeClientUrl?: string; smartAccountAddress: string; storageType?: StorageType; + sessionStorageClient?: ISessionStorage; } export interface BatchedSessionRouterModuleConfig extends BaseValidationModuleConfig { @@ -59,6 +61,12 @@ export type ModuleInfo = { batchSessionParams?: SessionParams[]; }; +export interface SendUserOpParams extends ModuleInfo { + simulationType?: SimulationType; +} + +export type SimulationType = "validation" | "validation_and_execution"; + export type CreateSessionDataResponse = { data: string; sessionIDInfo: Array; diff --git a/packages/node-client/CHANGELOG.md b/packages/node-client/CHANGELOG.md index 479c1cffd..b2f9ab90e 100644 --- a/packages/node-client/CHANGELOG.md +++ b/packages/node-client/CHANGELOG.md @@ -37,7 +37,7 @@ Version Bump Only. ### Features -* skipEstimation flag for gas ([487f3ae](https://github.com/bcnmy/biconomy-client-sdk/commit/487f3aefe21b2dd4fd46e18bef7168eae3c1ecc1)) +* skipBundlerGasEstimation flag for gas ([487f3ae](https://github.com/bcnmy/biconomy-client-sdk/commit/487f3aefe21b2dd4fd46e18bef7168eae3c1ecc1)) diff --git a/packages/node-client/README.md b/packages/node-client/README.md index f77c33226..b14934051 100644 --- a/packages/node-client/README.md +++ b/packages/node-client/README.md @@ -62,14 +62,14 @@ const balanceParams: BalancesDto = // is being supplied for initialization chainId: ChainId.MAINNET, // chainId of your choice - eoaAddress: address, + address: address, // 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: [], }; -const balFromSdk = await nodeClient.getAlltokenBalances(balanceParams); +const balFromSdk = await nodeClient.getAllTokenBalances(balanceParams); console.info("balFromSdk ", balFromSdk); const usdBalFromSdk = await nodeClient.getTotalBalanceInUsd(balanceParams); diff --git a/packages/node-client/src/types/NodeClientTypes.ts b/packages/node-client/src/types/NodeClientTypes.ts index 2f74b240c..c94937936 100644 --- a/packages/node-client/src/types/NodeClientTypes.ts +++ b/packages/node-client/src/types/NodeClientTypes.ts @@ -39,7 +39,7 @@ export type SCWTransactionResponse = { export type BalancesDto = { chainId: number; - eoaAddress: string; + address: string; tokenAddresses: string[]; }; diff --git a/packages/paymaster/src/BiconomyPaymaster.ts b/packages/paymaster/src/BiconomyPaymaster.ts index 405a0e50b..1734e23e6 100644 --- a/packages/paymaster/src/BiconomyPaymaster.ts +++ b/packages/paymaster/src/BiconomyPaymaster.ts @@ -19,7 +19,7 @@ import { IHybridPaymaster } from "./interfaces/IHybridPaymaster"; const defaultPaymasterConfig: PaymasterConfig = { paymasterUrl: "", - strictMode: true, // Set your desired default value for strictMode here + strictMode: false, // Set your desired default value for strictMode here }; /** * @dev Hybrid - Generic Gas Abstraction paymaster @@ -42,20 +42,24 @@ export class BiconomyPaymaster implements IHybridPaymaster): Promise> { userOp = await resolveProperties(userOp); - if (userOp.nonce !== null || userOp.nonce !== undefined) { + if (userOp.nonce !== null && userOp.nonce !== undefined) { userOp.nonce = BigNumber.from(userOp.nonce).toHexString(); } - if (userOp.callGasLimit !== null || userOp.callGasLimit !== undefined) { + if (userOp.callGasLimit !== null && userOp.callGasLimit !== undefined) { userOp.callGasLimit = BigNumber.from(userOp.callGasLimit).toString(); } - if (userOp.verificationGasLimit !== null || userOp.verificationGasLimit !== undefined) { + if (userOp.verificationGasLimit !== null && userOp.verificationGasLimit !== undefined) { userOp.verificationGasLimit = BigNumber.from(userOp.verificationGasLimit).toString(); } - if (userOp.preVerificationGas !== null || userOp.preVerificationGas !== undefined) { + if (userOp.preVerificationGas !== null && userOp.preVerificationGas !== undefined) { userOp.preVerificationGas = BigNumber.from(userOp.preVerificationGas).toString(); } - userOp.maxFeePerGas = BigNumber.from(userOp.maxFeePerGas).toHexString(); - userOp.maxPriorityFeePerGas = BigNumber.from(userOp.maxPriorityFeePerGas).toHexString(); + if (userOp.maxFeePerGas !== null && userOp.maxFeePerGas !== undefined) { + userOp.maxFeePerGas = BigNumber.from(userOp.maxFeePerGas).toString(); + } + if (userOp.maxPriorityFeePerGas !== null && userOp.maxPriorityFeePerGas !== undefined) { + userOp.maxPriorityFeePerGas = BigNumber.from(userOp.maxPriorityFeePerGas).toString(); + } userOp.signature = userOp.signature || "0x"; userOp.paymasterAndData = userOp.paymasterAndData || "0x"; return userOp; @@ -136,14 +140,14 @@ export class BiconomyPaymaster implements IHybridPaymaster A library to import the web3 social auth directly from Biconomy Sdk. - -## Usage - -```ts - -``` diff --git a/packages/web3-auth-native/package.json b/packages/web3-auth-native/package.json deleted file mode 100644 index 5fc0def8d..000000000 --- a/packages/web3-auth-native/package.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "name": "@biconomy/web3-auth-native", - "version": "3.1.0", - "description": "web3-auth expo react-native for biconomy sdk.", - "main": "dist/web3AuthNative.cjs.js", - "module": "dist/web3AuthNative.esm.js", - "source": "src/index.ts", - "types": "dist/types/index.d.ts", - "keywords": [ - "legos", - "batching", - "one-click", - "cross-chain", - "web3auth", - "react-native" - ], - "author": "livingrockrises ", - "homepage": "https://github.com/bcnmy/biconomy-client-sdk#readme", - "license": "MIT", - "files": [ - "dist", - "src", - "README.md" - ], - "scripts": { - "start": "torus-scripts start", - "build": "torus-scripts build", - "lint:ts": "eslint --fix 'src/**/*.ts'", - "prepack": "npm run build" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/bcnmy/biconomy-client-sdk.git" - }, - "dependencies": { - "@biconomy/node-client": "^3.1.0", - "@toruslabs/openlogin": "^2.8.0", - "@toruslabs/openlogin-jrpc": "^2.9.0", - "@toruslabs/openlogin-utils": "^2.1.0", - "base64url": "^3.0.1", - "buffer": "^6.0.3", - "loglevel": "^1.8.1", - "react-native-url-polyfill": "^2.0.0" - }, - "peerDependencies": { - "@babel/runtime": "^7.x", - "react-native": "~0.68.2" - }, - "devDependencies": { - "@babel/runtime": "^7.20.1", - "@toruslabs/eslint-config-typescript": "1.2.0", - "@toruslabs/torus-scripts": "^1.3.0", - "@types/node": "^16", - "@types/react-native": "^0.69.3", - "@typescript-eslint/eslint-plugin": "^5.44.0", - "@typescript-eslint/parser": "^5.44.0", - "eslint": "^8.28.0", - "eslint-plugin-import": "^2.26.0", - "eslint-plugin-n": "^15.5.1", - "eslint-plugin-prettier": "^4.2.1", - "eslint-plugin-promise": "^6.1.1", - "eslint-plugin-simple-import-sort": "^10.0.0", - "eslint-plugin-tsdoc": "^0.2.17", - "husky": "^8.0.3", - "lint-staged": "^14.0.1", - "prettier": "^3.0.3", - "react-native": "~0.72.4", - "rimraf": "^5.0.1", - "typescript": "^5.2.2" - } -} diff --git a/packages/web3-auth-native/src/SocialLogin.ts b/packages/web3-auth-native/src/SocialLogin.ts deleted file mode 100644 index a85530f1e..000000000 --- a/packages/web3-auth-native/src/SocialLogin.ts +++ /dev/null @@ -1,101 +0,0 @@ -import NodeClient, { WhiteListSignatureResponse } from '@biconomy/node-client' -import base64url from 'base64url' -import log from 'loglevel' -import { URL } from 'react-native-url-polyfill' - -import { IWebBrowser, WebBrowserAuthSessionResult } from './types/IWebBrowser' -import { SdkInitParams, SdkLoginParams, SdkLogoutParams, SocialLoginDto } from './types/sdk' -import { State } from './types/State' - -class SocialLogin { - initParams: SdkInitParams - - webBrowser: IWebBrowser - - nodeClient!: NodeClient - - private backendUrl: string - - private clientId: string - - constructor(socialLoginDto: SocialLoginDto) { - this.initParams = socialLoginDto.initParams - if (!this.initParams.sdkUrl) { - this.initParams.sdkUrl = 'https://sdk.openlogin.com' - } - this.webBrowser = socialLoginDto.webBrowser - this.clientId = - 'BDtxlmCXNAWQFGiiaiVY3Qb1aN-d7DQ82OhT6B-RBr5j_rGnrKAqbIkvLJlf-ofYlJRiNSHbnkeHlsh8j3ueuYY' - this.backendUrl = 'https://sdk-backend.prod.biconomy.io/v1' - this.nodeClient = new NodeClient({ txServiceUrl: this.backendUrl }) - } - - async whitelistUrl(origin: string): Promise { - const whiteListUrlResponse: WhiteListSignatureResponse = - await this.nodeClient.whitelistUrl(origin) - return whiteListUrlResponse.data - } - - async login(options: SdkLoginParams): Promise { - const result = await this.request('login', options.redirectUrl, options) - if (result.type !== 'success' || !result.url) { - log.error(`[Web3Auth] login flow failed with error type ${result.type}`) - throw new Error(`login flow failed with error type ${result.type}`) - } - - const fragment = new URL(result.url).hash - const decodedPayload = base64url.decode(fragment) - const state = JSON.parse(decodedPayload) - return state - } - - async logout(options: SdkLogoutParams): Promise { - const redirectUrl = options.redirectUrl || '/' - const result = await this.request('logout', redirectUrl, options) - - if (result.type !== 'success' || !result.url) { - log.error(`[Web3Auth] logout flow failed with error type ${result.type}`) - throw new Error(`logout flow failed with error type ${result.type}`) - } - } - - private async request( - path: string, - redirectUrl: string, - params: Record = {} - ): Promise { - const initParams = { - ...this.initParams, - clientId: this.clientId, - originData: params.originData, - network: this.initParams.network || 'mainnet', - ...(!!this.initParams.redirectUrl && { - redirectUrl: this.initParams.redirectUrl - }) - } - - const mergedParams = { - init: initParams, - params: { - ...params, - ...(!params.redirectUrl && { redirectUrl }) - } - } - - log.debug(`[Web3Auth] params passed to Web3Auth: ${mergedParams}`) - - const hash = base64url.encode(JSON.stringify(mergedParams)) - - const url = new URL(this.initParams.sdkUrl || '') - url.pathname = `${url.pathname}${path}` - url.hash = hash - - log.info( - `[Web3Auth] opening login screen in browser at ${url.href}, will redirect to ${redirectUrl}` - ) - - return this.webBrowser.openAuthSessionAsync(url.href, redirectUrl) - } -} - -export default SocialLogin diff --git a/packages/web3-auth-native/src/index.ts b/packages/web3-auth-native/src/index.ts deleted file mode 100644 index baf5608e1..000000000 --- a/packages/web3-auth-native/src/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -import SocialLogin from './SocialLogin' - -export default SocialLogin -export * from './types/IWebBrowser' -export * from './types/sdk' -export * from './types/State' diff --git a/packages/web3-auth-native/src/types/IWebBrowser.ts b/packages/web3-auth-native/src/types/IWebBrowser.ts deleted file mode 100644 index fcc51728c..000000000 --- a/packages/web3-auth-native/src/types/IWebBrowser.ts +++ /dev/null @@ -1,310 +0,0 @@ -export declare type RedirectEvent = { - url: string -} -export declare type WebBrowserWindowFeatures = Record -export declare type WebBrowserOpenOptions = { - /** - * Color of the toolbar in either `#AARRGGBB` or `#RRGGBB` format. - */ - toolbarColor?: string - /** - * Package name of a browser to be used to handle Custom Tabs. List of - * available packages is to be queried by [`getCustomTabsSupportingBrowsers`](#webbrowsergetcustomtabssupportingbrowsersasync) method. - * @platform android - */ - browserPackage?: string - /** - * A boolean determining whether the toolbar should be hiding when a user scrolls the website. - */ - enableBarCollapsing?: boolean - /** - * Color of the secondary toolbar in either `#AARRGGBB` or `#RRGGBB` format. - * @platform android - */ - secondaryToolbarColor?: string - /** - * A boolean determining whether the browser should show the title of website on the toolbar. - * @platform android - */ - showTitle?: boolean - /** - * A boolean determining whether a default share item should be added to the menu. - * @platform android - */ - enableDefaultShareMenuItem?: boolean - /** - * A boolean determining whether browsed website should be shown as separate - * entry in Android recents/multitasking view. Requires `createTask` to be `true` (default). - * @default false - * @platform android - */ - showInRecents?: boolean - /** - * A boolean determining whether the browser should open in a new task or in - * the same task as your app. - * @default true - * @platform android - */ - createTask?: boolean - /** - * Tint color for controls in SKSafariViewController in `#AARRGGBB` or `#RRGGBB` format. - * @platform ios - */ - controlsColor?: string - /** - * The style of the dismiss button. Should be one of: `done`, `close`, or `cancel`. - * @platform ios - */ - dismissButtonStyle?: 'done' | 'close' | 'cancel' - /** - * A boolean determining whether Safari should enter Reader mode, if it is available. - * @platform ios - */ - readerMode?: boolean - /** - * Name to assign to the popup window. - * @platform web - */ - windowName?: string - /** - * Features to use with `window.open()`. - * @platform web - */ - windowFeatures?: string | WebBrowserWindowFeatures -} -export declare type WebBrowserAuthSessionResult = WebBrowserRedirectResult | WebBrowserResult -export declare type WebBrowserCustomTabsResults = { - /** - * Default package chosen by user, `null` if there is no such packages. Also `null` usually means, - * that user will be prompted to choose from available packages. - */ - defaultBrowserPackage?: string - /** - * Package preferred by `CustomTabsClient` to be used to handle Custom Tabs. It favors browser - * chosen by user as default, as long as it is present on both `browserPackages` and - * `servicePackages` lists. Only such browsers are considered as fully supporting Custom Tabs. - * It might be `null` when there is no such browser installed or when default browser is not in - * `servicePackages` list. - */ - preferredBrowserPackage?: string - /** - * All packages recognized by `PackageManager` as capable of handling Custom Tabs. Empty array - * means there is no supporting browsers on device. - */ - browserPackages: string[] - /** - * All packages recognized by `PackageManager` as capable of handling Custom Tabs Service. - * This service is used by [`warmUpAsync`](#webbrowserwarmupasyncbrowserpackage), [`mayInitWithUrlAsync`](#webbrowsermayinitwithurlasyncurl-browserpackage) - * and [`coolDownAsync`](#webbrowsercooldownasyncbrowserpackage). - */ - servicePackages: string[] -} -export declare enum WebBrowserResultType { - /** - * @platform ios - */ - CANCEL = 'cancel', - /** - * @platform ios - */ - DISMISS = 'dismiss', - /** - * @platform android - */ - OPENED = 'opened', - LOCKED = 'locked' -} -export declare type WebBrowserResult = { - /** - * Type of the result. - */ - type: WebBrowserResultType -} -export declare type WebBrowserRedirectResult = { - /** - * Type of the result. - */ - type: 'success' - url: string -} -export declare type ServiceActionResult = { - servicePackage?: string -} -export declare type WebBrowserMayInitWithUrlResult = ServiceActionResult -export declare type WebBrowserWarmUpResult = ServiceActionResult -export declare type WebBrowserCoolDownResult = ServiceActionResult -export declare type WebBrowserCompleteAuthSessionOptions = { - /** - * Attempt to close the window without checking to see if the auth redirect matches the cached redirect URL. - */ - skipRedirectCheck?: boolean -} -export declare type WebBrowserCompleteAuthSessionResult = { - /** - * Type of the result. - */ - type: 'success' | 'failed' - /** - * Additional description or reasoning of the result. - */ - message: string -} - -export interface IWebBrowser { - /** - * Returns a list of applications package names supporting Custom Tabs, Custom Tabs - * service, user chosen and preferred one. This may not be fully reliable, since it uses - * `PackageManager.getResolvingActivities` under the hood. (For example, some browsers might not be - * present in browserPackages list once another browser is set to default.) - * - * @return The promise which fulfils with [`WebBrowserCustomTabsResults`](#webbrowsercustomtabsresults) object. - * @platform android - */ - // getCustomTabsSupportingBrowsersAsync(): Promise; - /** - * This method calls `warmUp` method on [CustomTabsClient](https://developer.android.com/reference/android/support/customtabs/CustomTabsClient.html#warmup(long)) - * for specified package. - * - * @param browserPackage Package of browser to be warmed up. If not set, preferred browser will be warmed. - * - * @return A promise which fulfils with `WebBrowserWarmUpResult` object. - * @platform android - */ - // warmUpAsync(browserPackage?: string): Promise; - /** - * This method initiates (if needed) [CustomTabsSession](https://developer.android.com/reference/android/support/customtabs/CustomTabsSession.html#maylaunchurl) - * and calls its `mayLaunchUrl` method for browser specified by the package. - * - * @param url The url of page that is likely to be loaded first when opening browser. - * @param browserPackage Package of browser to be informed. If not set, preferred - * browser will be used. - * - * @return A promise which fulfils with `WebBrowserMayInitWithUrlResult` object. - * @platform android - */ - // mayInitWithUrlAsync( - // url: string, - // browserPackage?: string - // ): Promise; - /** - * This methods removes all bindings to services created by [`warmUpAsync`](#webbrowserwarmupasyncbrowserpackage) - * or [`mayInitWithUrlAsync`](#webbrowsermayinitwithurlasyncurl-browserpackage). You should call - * this method once you don't need them to avoid potential memory leaks. However, those binding - * would be cleared once your application is destroyed, which might be sufficient in most cases. - * - * @param browserPackage Package of browser to be cooled. If not set, preferred browser will be used. - * - * @return The promise which fulfils with ` WebBrowserCoolDownResult` when cooling is performed, or - * an empty object when there was no connection to be dismissed. - * @platform android - */ - // coolDownAsync(browserPackage?: string): Promise; - /** - * Opens the url with Safari in a modal on iOS using [`SFSafariViewController`](https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller), - * and Chrome in a new [custom tab](https://developer.chrome.com/multidevice/android/customtabs) - * on Android. On iOS, the modal Safari will not share cookies with the system Safari. If you need - * this, use [`openAuthSessionAsync`](#webbrowseropenauthsessionasyncurl-redirecturl-browserparams). - * - * @param url The url to open in the web browser. - * @param browserParams A dictionary of key-value pairs. - * - * @return The promise behaves differently based on the platform. - * On Android promise resolves with `{type: 'opened'}` if we were able to open browser. - * On iOS: - * - If the user closed the web browser, the Promise resolves with `{ type: 'cancel' }`. - * - If the browser is closed using [`dismissBrowser`](#webbrowserdismissbrowser), the Promise resolves with `{ type: 'dismiss' }`. - */ - // openBrowserAsync( - // url: string, - // browserParams?: WebBrowserOpenOptions - // ): Promise; - /** - * Dismisses the presented web browser. - * - * @return The `void` on successful attempt, or throws error, if dismiss functionality is not avaiable. - * @platform ios - */ - // dismissBrowser(): void; - /** - * # On iOS: - * Opens the url with Safari in a modal using `SFAuthenticationSession` on iOS 11 and greater, - * and falling back on a `SFSafariViewController`. The user will be asked whether to allow the app - * to authenticate using the given url. - * - * # On Android: - * This will be done using a "custom Chrome tabs" browser, [AppState](../react-native/appstate/), - * and [Linking](./linking/) APIs. - * - * # On web: - * > This API can only be used in a secure environment (`https`). You can use expo `start:web --https` - * to test this. Otherwise, an error with code [`ERR_WEB_BROWSER_CRYPTO`](#errwebbrowsercrypto) will be thrown. - * This will use the browser's [`window.open()`](https://developer.mozilla.org/en-US/docs/Web/API/Window/open) API. - * - _Desktop_: This will create a new web popup window in the browser that can be closed later using `WebBrowser.maybeCompleteAuthSession()`. - * - _Mobile_: This will open a new tab in the browser which can be closed using `WebBrowser.maybeCompleteAuthSession()`. - * - * How this works on web: - * - A crypto state will be created for verifying the redirect. - * - This means you need to run with `expo start:web --https` - * - The state will be added to the window's `localstorage`. This ensures that auth cannot complete - * unless it's done from a page running with the same origin as it was started. - * Ex: if `openAuthSessionAsync` is invoked on `https://localhost:19006`, then `maybeCompleteAuthSession` - * must be invoked on a page hosted from the origin `https://localhost:19006`. Using a different - * website, or even a different host like `https://128.0.0.*:19006` for example will not work. - * - A timer will be started to check for every 1000 milliseconds (1 second) to detect if the window - * has been closed by the user. If this happens then a promise will resolve with `{ type: 'dismiss' }`. - * - * > On mobile web, Chrome and Safari will block any call to [`window.open()`](https://developer.mozilla.org/en-US/docs/Web/API/Window/open) - * which takes too long to fire after a user interaction. This method must be invoked immediately - * after a user interaction. If the event is blocked, an error with code [`ERR_WEB_BROWSER_BLOCKED`](#errwebbrowserblocked) will be thrown. - * - * @param url The url to open in the web browser. This should be a login page. - * @param redirectUrl _Optional_ - The url to deep link back into your app. By default, this will be [`Constants.linkingUrl`](./constants/#expoconstantslinkinguri). - * @param browserParams _Optional_ - An object with the same keys as [`WebBrowserOpenOptions`](#webbrowseropenoptions). - * If there is no native AuthSession implementation available (which is the case on Android) - * these params will be used in the browser polyfill. If there is a native AuthSession implementation, - * these params will be ignored. - * - * @return - * - If the user does not permit the application to authenticate with the given url, the Promise fulfills with `{ type: 'cancel' }` object. - * - If the user closed the web browser, the Promise fulfills with `{ type: 'cancel' }` object. - * - If the browser is closed using [`dismissBrowser`](#webbrowserdismissbrowser), - * the Promise fulfills with `{ type: 'dismiss' }` object. - */ - openAuthSessionAsync( - _url: string, - _redirectUrl: string, - _browserParams?: WebBrowserOpenOptions - ): Promise - // dismissAuthSession(): void; - /** - * Possibly completes an authentication session on web in a window popup. The method - * should be invoked on the page that the window redirects to. - * - * @param options - * - * @return Returns an object with message about why the redirect failed or succeeded: - * - * If `type` is set to `failed`, the reason depends on the message: - * - `Not supported on this platform`: If the platform doesn't support this method (iOS, Android). - * - `Cannot use expo-web-browser in a non-browser environment`: If the code was executed in an SSR - * or node environment. - * - `No auth session is currently in progress`: (the cached state wasn't found in local storage). - * This can happen if the window redirects to an origin (website) that is different to the initial - * website origin. If this happens in development, it may be because the auth started on localhost - * and finished on your computer port (Ex: `128.0.0.*`). This is controlled by the `redirectUrl` - * and `returnUrl`. - * - `Current URL "" and original redirect URL "" do not match`: This can occur when the - * redirect URL doesn't match what was initial defined as the `returnUrl`. You can skip this test - * in development by passing `{ skipRedirectCheck: true }` to the function. - * - * If `type` is set to `success`, the parent window will attempt to close the child window immediately. - * - * If the error `ERR_WEB_BROWSER_REDIRECT` was thrown, it may mean that the parent window was - * reloaded before the auth was completed. In this case you'll need to close the child window manually. - * - * @platform web - */ - // maybeCompleteAuthSession( - // options?: WebBrowserCompleteAuthSessionOptions - // ): WebBrowserCompleteAuthSessionResult; -} diff --git a/packages/web3-auth-native/src/types/State.ts b/packages/web3-auth-native/src/types/State.ts deleted file mode 100644 index 403e0eda6..000000000 --- a/packages/web3-auth-native/src/types/State.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { OpenloginUserInfo } from '@toruslabs/openlogin' - -interface State { - privKey?: string - ed25519PrivKey?: string - userInfo?: OpenloginUserInfo - sessionId?: string -} - -export type { State } diff --git a/packages/web3-auth-native/src/types/sdk.ts b/packages/web3-auth-native/src/types/sdk.ts deleted file mode 100644 index 4f6bc16cb..000000000 --- a/packages/web3-auth-native/src/types/sdk.ts +++ /dev/null @@ -1,90 +0,0 @@ -import type { - BaseLogoutParams, - BaseRedirectParams, - LoginParams, - OpenLoginOptions -} from '@toruslabs/openlogin' -import { IWebBrowser } from './IWebBrowser' - -type SdkSpecificInitParams = { - sdkUrl?: string -} - -export type SocialLoginDto = { - initParams: SdkInitParams - webBrowser: IWebBrowser -} - -export type IOriginData = { - [P: string]: string -} - -export type SdkInitParams = Omit< - OpenLoginOptions & SdkSpecificInitParams, - | 'no3PC' - | 'uxMode' - | 'replaceUrlOnRedirect' - | 'originData' - | '_iframeUrl' - | '_startUrl' - | '_popupUrl' - | '_storageServerUrl' - | 'clientId' -> - -export type SdkLoginParams = Omit< - LoginParams & IOriginData, - 'fastLogin' | 'skipTKey' | 'getWalletKey' -> - -export type SdkLogoutParams = Partial & Partial - -export const OPENLOGIN_NETWORK = { - MAINNET: 'mainnet', - TESTNET: 'testnet', - CYAN: 'cyan', - AQUA: 'aqua', - CELESTE: 'celeste' -} as const - -export const SUPPORTED_KEY_CURVES = { - SECP256K1: 'secp256k1', - ED25519: 'ed25519' -} - -export const LOGIN_PROVIDER = { - GOOGLE: 'google', - FACEBOOK: 'facebook', - REDDIT: 'reddit', - DISCORD: 'discord', - TWITCH: 'twitch', - APPLE: 'apple', - LINE: 'line', - GITHUB: 'github', - KAKAO: 'kakao', - LINKEDIN: 'linkedin', - TWITTER: 'twitter', - WEIBO: 'weibo', - WECHAT: 'wechat', - EMAIL_PASSWORDLESS: 'email_passwordless', - JWT: 'jwt' -} as const - -export const MFA_LEVELS = { - DEFAULT: 'default', - OPTIONAL: 'optional', - MANDATORY: 'mandatory', - NONE: 'none' -} - -export type { - ALLOWED_INTERACTIONS_TYPE, - LOGIN_PROVIDER_TYPE, - LoginParams, - MfaLevelType, - OPENLOGIN_NETWORK_TYPE, - OpenloginUserInfo, - SUPPORTED_KEY_CURVES_TYPE -} from '@toruslabs/openlogin' -export type { TypeOfLogin, WhiteLabelData } from '@toruslabs/openlogin-jrpc' -export type { ExtraLoginOptions } from '@toruslabs/openlogin-utils' diff --git a/packages/web3-auth-native/tests/web3-auth-native.spec.ts b/packages/web3-auth-native/tests/web3-auth-native.spec.ts deleted file mode 100644 index de58b27e6..000000000 --- a/packages/web3-auth-native/tests/web3-auth-native.spec.ts +++ /dev/null @@ -1,5 +0,0 @@ -describe('Web3 Auth Native Tests', () => { - it('should have a basic test', () => { - expect(true).toBe(true) - }) -}) diff --git a/packages/web3-auth-native/torus.config.js b/packages/web3-auth-native/torus.config.js deleted file mode 100644 index e41d0b5b8..000000000 --- a/packages/web3-auth-native/torus.config.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - umd: false -} diff --git a/packages/web3-auth-native/tsconfig.eslint.json b/packages/web3-auth-native/tsconfig.eslint.json deleted file mode 100644 index eced3c6c6..000000000 --- a/packages/web3-auth-native/tsconfig.eslint.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": ["../../tsconfig.eslint.json"] -} diff --git a/packages/web3-auth-native/tsconfig.json b/packages/web3-auth-native/tsconfig.json deleted file mode 100644 index eb424084f..000000000 --- a/packages/web3-auth-native/tsconfig.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../../tsconfig.settings.json", - "compilerOptions": { - "jsx": "react", - "composite": true, - "outDir": "dist", - "baseUrl": "src", - "resolveJsonModule": true, - "esModuleInterop": true - }, - "include": ["src", "src/**/*.json"] -} diff --git a/packages/web3-auth/CHANGELOG.md b/packages/web3-auth/CHANGELOG.md deleted file mode 100644 index 074458c88..000000000 --- a/packages/web3-auth/CHANGELOG.md +++ /dev/null @@ -1,90 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## 3.1.0 (2023-09-20) - - -### 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)) -* more lint issues ([10df908](https://github.com/bcnmy/biconomy-client-sdk/commit/10df90821b473fd668907cf3e447dfe3825317fc)) -* 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)) - - - - - -# 3.0.0 (2023-08-28) - -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)) - - -### 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)) - - - - - -## 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)) - - -### 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)) diff --git a/packages/web3-auth/README.md b/packages/web3-auth/README.md deleted file mode 100644 index 1ed6c771a..000000000 --- a/packages/web3-auth/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# `@biconomy/web3-auth` - -> A library to import the torus web3 social auth directly from [Biconomy SDK](https://github.com/bcnmy/biconomy-client-sdk) - -## Usage - -```ts -import SocialLogin from "@biconomy/web3-auth"; -// init wallet -const socialLoginSDK = new SocialLogin(); -await socialLoginSDK.init(); -// show connect modal -socialLoginSDK.showWallet(); -``` diff --git a/packages/web3-auth/package.json b/packages/web3-auth/package.json deleted file mode 100644 index cbbd149be..000000000 --- a/packages/web3-auth/package.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "name": "@biconomy/web3-auth", - "version": "3.1.0", - "description": "web3-auth for biconomy sdk", - "main": "./dist/src/index.js", - "typings": "./dist/src/index.d.ts", - "keywords": [ - "legos", - "batching", - "one-click", - "cross-chain", - "web3auth" - ], - "author": "livingrockrises ", - "homepage": "https://github.com/bcnmy/biconomy-client-sdk#readme", - "license": "MIT", - "files": [ - "dist/*", - "README.md" - ], - "repository": { - "type": "git", - "url": "git+https://github.com/bcnmy/biconomy-client-sdk.git" - }, - "scripts": { - "unbuild": "rimraf dist *.tsbuildinfo", - "copy-files": "npx copyfiles -u 1 src/**/*.css dist/src", - "build": "rimraf dist && tsc && yarn copy-files", - "format": "prettier --write \"{src,tests}/**/*.ts\"", - "lint": "tslint -p tsconfig.json" - }, - "bugs": { - "url": "https://github.com/bcnmy/biconomy-client-sdk/issues" - }, - "publishConfig": { - "access": "public" - }, - "dependencies": { - "@biconomy/node-client": "^3.1.0", - "@walletconnect/qrcode-modal": "^1.8.0", - "@web3auth/base": "^3.0.0", - "@web3auth/core": "^3.0.0", - "@web3auth/metamask-adapter": "^3.0.0", - "@web3auth/openlogin-adapter": "^3.0.3", - "@web3auth/wallet-connect-v1-adapter": "^3.0.3", - "ethers": "^5.7.0", - "process": "^0.11.10", - "react": "^18.2.0", - "react-dom": "^18.2.0" - }, - "devDependencies": { - "@biconomy/node-client": "^3.1.0", - "@types/react": "^18.0.15", - "@types/react-dom": "^18.0.6", - "path": "^0.12.7", - "tslint": "^6.1.3", - "tslint-config-prettier": "^1.18.0", - "typescript": "^4.7.4", - "webpack": "^5.74.0", - "webpack-cli": "^4.10.0" - } -} diff --git a/packages/web3-auth/src/SocialLogin.tsx b/packages/web3-auth/src/SocialLogin.tsx deleted file mode 100644 index 306bdc95c..000000000 --- a/packages/web3-auth/src/SocialLogin.tsx +++ /dev/null @@ -1,332 +0,0 @@ -/* eslint-disable no-console */ -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): void { - /* eslint-disable @typescript-eslint/no-explicit-any */ - const root = createRoot((document as any).getElementById("w3a-modal")); - root.render(); -} - -const defaultSocialLoginConfig: DefaultSocialLoginConfig = { - backendUrl: "https://sdk-backend.prod.biconomy.io/v1", -}; - -class SocialLogin { - /* eslint-disable @typescript-eslint/no-explicit-any */ - walletDiv: any; - - /* eslint-disable @typescript-eslint/no-explicit-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; - - 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.whiteLabel = { - 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); - return whiteListUrlResponse.data; - } - - async init(socialLoginDTO?: Partial): Promise { - const finalDTO: SocialLoginDTO = { - chainId: "0x1", - whitelistUrls: {}, - 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; - } - try { - const web3AuthCore = new Web3AuthCore({ - clientId: this.clientId, - chainConfig: { - chainNamespace: CHAIN_NAMESPACES.EIP155, - chainId: finalDTO.chainId, - }, - }); - - const openloginAdapter = new OpenloginAdapter({ - adapterSettings: { - clientId: this.clientId, - network: finalDTO.network, - uxMode: "popup", - whiteLabel: { - name: this.whiteLabel.name, - logoLight: this.whiteLabel.logo, - logoDark: this.whiteLabel.logo, - defaultLanguage: "en", - dark: true, - }, - originData: finalDTO.whitelistUrls, - }, - }); - const metamaskAdapter = new MetamaskAdapter({ - 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; - if (web3AuthCore && web3AuthCore.provider) { - this.provider = web3AuthCore.provider; - } - createLoginModal(this); - this.isInit = true; - } catch (error) { - console.error(error); - } - } - - getProvider(): SafeEventEmitterProvider | null { - return this.provider; - } - - /* eslint-disable @typescript-eslint/no-explicit-any */ - private _createIframe(iframeContainerDiv: any): void { - 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); - } - - private createWalletDiv(): void { - // 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; - // insert div into top of body. - document.body.insertBefore(walletDiv, document.body.firstChild); - this._createIframe(walletDiv); - } - - showWallet(): void { - 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")); - } - - hideWallet(): void { - this.walletDiv.style.display = "none"; - this.walletIframe.style.display = "none"; - } - - async getUserInfo(): Promise | null> { - if (this.web3auth) { - const userInfo = await this.web3auth.getUserInfo(); - this.userInfo = userInfo; - return userInfo; - } - return null; - } - - async getPrivateKey(): Promise { - if (this.web3auth && this.web3auth.provider) { - const privateKey = await this.web3auth.provider.request({ - method: "eth_private_key", - }); - return privateKey as string; - } - return null; - } - - async socialLogin(loginProvider: string): Promise { - if (!this.web3auth) { - console.info("web3auth not initialized yet"); - return null; - } - try { - const web3authProvider = await this.web3auth.connectTo(WALLET_ADAPTERS.OPENLOGIN, { - loginProvider: loginProvider, - }); - if (!web3authProvider) { - 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; - } catch (error) { - console.error(error); - return null; - } - } - - async emailLogin(email: string): Promise { - if (!this.web3auth) { - console.info("web3auth not initialized yet"); - return null; - } - try { - const web3authProvider = await this.web3auth.connectTo(WALLET_ADAPTERS.OPENLOGIN, { - loginProvider: "email_passwordless", - login_hint: email, - }); - if (!web3authProvider) { - 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; - } catch (error) { - console.error(error); - return null; - } - } - - async metamaskLogin(): Promise { - if (!this.web3auth) { - console.log("web3auth not initialized yet"); - return null; - } - try { - const web3authProvider = await this.web3auth.connectTo(WALLET_ADAPTERS.METAMASK); - if (!web3authProvider) { - 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; - } catch (error) { - console.error(error); - return null; - } - } - - async walletConnectLogin(): Promise { - if (!this.web3auth) { - console.log("web3auth not initialized yet"); - return null; - } - try { - const web3authProvider = await this.web3auth.connectTo(WALLET_ADAPTERS.WALLET_CONNECT_V1); - if (!web3authProvider) { - 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; - } catch (error) { - console.error(error); - return null; - } - } - - async logout(): Promise { - if (!this.web3auth) { - console.log("web3auth not initialized yet"); - return; - } - await this.web3auth.logout(); - this.web3auth.clearCache(); - this.provider = null; - } -} - -const socialLoginSDK: SocialLogin = new SocialLogin(); -(window as any).socialLoginSDK = socialLoginSDK; - -export default SocialLogin; - -let initializedSocialLogin: SocialLogin | null = null; -const getSocialLoginSDK = async (socialLoginDTO?: Partial): Promise => { - if (initializedSocialLogin) { - return initializedSocialLogin; - } - await socialLoginSDK.init(socialLoginDTO); - initializedSocialLogin = socialLoginSDK; - return socialLoginSDK; -}; - -export { socialLoginSDK, getSocialLoginSDK }; diff --git a/packages/web3-auth/src/UI.tsx b/packages/web3-auth/src/UI.tsx deleted file mode 100644 index 2fd8e5187..000000000 --- a/packages/web3-auth/src/UI.tsx +++ /dev/null @@ -1,103 +0,0 @@ -import React, { useState } from "react"; -import SocialLogin from "./SocialLogin"; - -interface UIPorops { - 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", - borderRadius: 10, - background: "black", - overflow: "hidden", -} as React.CSSProperties; - -const UI: React.FC = ({ socialLogin }) => { - const [email, setEmail] = useState(""); - - function handleEmailSubmit(event: React.SyntheticEvent): void { - event.preventDefault(); - socialLogin.emailLogin(email); - } - - function handleEmailChange(event: React.FormEvent): void { - setEmail(event.currentTarget.value); - } - - return ( -
-
-
- logo -
-
Sign in
-

Select one of the following to continue

-
-
- -
- -
-
-
CONTINUE WITH
-
    -
  • - -
  • -
  • - -
  • -
-
-
-
EMAIL
-
- - -
-
-
-
-
EXTERNAL WALLET
- - -
-
-
- -
-
-
-
- Powered by Biconomy -
-
-
-
-
- ); -}; - -export default UI; diff --git a/packages/web3-auth/src/index.ts b/packages/web3-auth/src/index.ts deleted file mode 100644 index 803fefd3a..000000000 --- a/packages/web3-auth/src/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -import SocialLogin, { socialLoginSDK, getSocialLoginSDK } from "./SocialLogin"; - -export default SocialLogin; -export { socialLoginSDK, getSocialLoginSDK }; diff --git a/packages/web3-auth/src/style.css b/packages/web3-auth/src/style.css deleted file mode 100644 index 70264c5c1..000000000 --- a/packages/web3-auth/src/style.css +++ /dev/null @@ -1,871 +0,0 @@ -/* devanagari */ -@font-face { - 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; -} -/* latin-ext */ -@font-face { - 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; -} -/* latin */ -@font-face { - 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; -} - -/* latin-ext */ -@font-face { - 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; -} -/* latin */ -@font-face { - 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; -} - -/* Modal */ -#w3a-modal { - --bg1: #0f1222; - --bg2: #24262e; - --text-color1: #d3d3d4; - --text-color2: #ffffff; - - --text-header: "Poppins", Helvetica, sans-serif; - --text-body: "DM Sans", Helvetica, sans-serif; - - position: fixed; - top: 0; - left: 0; - width: 100vw; - height: 100vh; - display: flex; - align-items: center; - justify-content: center; - box-sizing: border-box; - padding: 15px; - background: rgba(33, 33, 33, 0.46); - color: var(--text-color1); - font-family: var(--text-body); -} - -#w3a-modal.w3a-modal--hidden { - display: none; -} - -#w3a-modal p, -#w3a-modal form, -#w3a-modal button { - margin: 0; - padding: 0; -} - -#w3a-modal .w3a-modal__inner { - width: 100%; - max-width: 375px; - overflow: hidden; - border-radius: 6px; - position: relative; - max-height: 95%; - overflow-y: auto; - opacity: 0; - transition: 200ms cubic-bezier(0.25, 0.8, 0.25, 1); - transform-origin: center center; - min-height: 350px; -} - -#w3a-modal .w3a-modal__inner.w3a-modal__inner--active { - opacity: 1; - transition: 200ms cubic-bezier(0.25, 0.8, 0.25, 1); - transform-origin: center center; -} - -#w3a-modal .w3a-modal__header { - padding: 25px 34px; - background: var(--bg1); - box-shadow: 0px 4px 28px rgba(3, 100, 255, 0.05); - position: relative; -} -#w3a-modal .w3a-modal__content { - padding: 30px 34px; - background: var(--bg2); -} -#w3a-modal .w3a-modal__footer { - padding: 16px 34px; - background: var(--bg1); -} - -/* SPINNER */ -/* Loader */ -#w3a-modal .w3a-modal__loader { - background: var(--bg2); - position: absolute; - display: flex; - justify-content: center; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 10; -} - -#w3a-modal .w3a-modal__loader.w3a-modal__loader--hidden { - display: none; -} - -#w3a-modal .w3a-modal__loader-content { - text-align: center; - margin-bottom: 80px; - position: relative; - display: flex; - flex-direction: column; -} - -#w3a-modal .w3a-modal__loader-info { - flex-grow: 1; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - padding: 0 30px; -} - -#w3a-modal .w3a-spinner-label { - margin-top: 10px; - font-size: 16px; - font-weight: 500; - color: #0364ff; -} - -#w3a-modal .w3a-spinner-message { - margin-top: 10px; - font-size: 16px; -} -#w3a-modal .w3a-spinner-message:first-letter { - text-transform: capitalize; -} -#w3a-modal .w3a-spinner-message.w3a-spinner-message--error { - color: #fb4a61; -} - -#w3a-modal button.w3a-logout { - background: none; - border: 0; - padding: 0; - display: inline-flex; - align-items: center; - margin-bottom: 30px; - cursor: pointer; - margin-top: 20px; - color: #0364ff; -} - -#w3a-modal .w3a-spinner-power { - margin-top: auto; - font-size: 12px; - line-height: 1.2em; - color: #b7b8bd; -} -#w3a-modal .w3a-spinner-power > img { - height: 32px; - width: auto; - display: inline; -} - -#w3a-modal .w3a-spinner { - display: inline-block; - position: relative; - background-color: #0364ff; - height: 60px; - width: 60px; - border-radius: 50%; - background: conic-gradient(transparent, #0364ff); - animation: rotate 1s linear infinite; -} - -#w3a-modal .w3a-spinner__mask, -#w3a-modal .w3a-spinner__head { - content: ""; - position: absolute; - border-radius: 50%; -} - -#w3a-modal .w3a-spinner__mask { - width: 50px; - height: 50px; - top: 5px; - left: 5px; - background-color: var(--bg2); -} - -#w3a-modal .w3a-spinner__head { - height: 5px; - width: 5px; - background-color: #0364ff; - top: 0; - left: 26px; -} - -@keyframes rotate { - from { - transform: rotateZ(0); - } - to { - transform: rotateZ(360deg); - } -} - -/* Header */ -#w3a-modal .w3a-header { - display: flex; - color: var(--text-color2); - align-items: center; -} -#w3a-modal .w3a-header__logo { - height: auto; - width: 40px; - margin-right: 16px; -} -#w3a-modal .w3a-header__title { - font-family: var(--text-header); - font-weight: 600; - font-size: 20px; - line-height: 1.5em; -} -#w3a-modal p.w3a-header__subtitle { - font-size: 14px; - line-height: 1.5em; - font-weight: 400; -} -#w3a-modal button.w3a-header__button { - cursor: pointer; - position: absolute; - background: none; - padding: 0; - border: 0; - top: 20px; - right: 26px; -} - -/* BODY */ -#w3a-modal .w3a-group { - margin-bottom: 24px; -} -#w3a-modal .w3a-group:last-child { - margin-bottom: 0; -} - -#w3a-modal .w3a-group.w3a-group--hidden, -#w3a-modal .w3a-group.w3a-group--social-hidden, -#w3a-modal .w3a-group.w3a-group--email-hidden, -#w3a-modal .w3a-group.w3a-group--ext-wallet-hidden { - display: none; -} - -#w3a-modal .w3a-group:not(.w3a-group--hidden):not(:last-child), -#w3a-modal .w3a-group:not(.w3a-group--social-hidden):not(:last-child), -#w3a-modal .w3a-group:not(.w3a-group--email-hidden):not(:last-child), -#w3a-modal .w3a-group:not(.w3a-group--ext-wallet-hidden):not(:last-child) { - border-bottom: 0.5px solid #5c6c7f; - padding-bottom: 24px; -} - -#w3a-modal div.w3a-group__title { - font-family: var(--text-header); - font-weight: 400; - font-size: 14px; - line-height: 1.5em; - margin-bottom: 8px; - text-transform: uppercase; -} - -/* Adapter List */ -#w3a-modal ul.w3a-adapter-list { - display: flex; - align-items: center; - padding: 0; - margin: 0; - gap: 16px; - overflow-y: hidden; - flex-wrap: wrap; - max-height: 500px; - transition: max-height 0.4s ease-in; -} - -#w3a-modal ul.w3a-adapter-list.w3a-adapter-list--shrink { - max-height: 48px; - transition: max-height 0.4s ease-out; -} - -#w3a-modal ul.w3a-adapter-list.w3a-adapter-list--hidden { - display: none; -} - -#w3a-modal li.w3a-adapter-item { - list-style: none; - margin-bottom: 0; -} - -#w3a-modal .w3a-adapter-item--hide { - display: none; -} - -#w3a-modal .w3a-adapter-item__label { - font-size: 12px; - color: #5c6c7f; - text-align: center; - margin: 8px 0 0 !important; - text-transform: capitalize; - position: absolute; - transform: translate(-6px); - width: 60px; -} - -/* Buttons */ -#w3a-modal button.w3a-button { - background-color: #2f3136; - border: 1px solid #404145; - box-sizing: border-box; - box-shadow: 2px 2px 12px rgba(3, 100, 255, 0.05); - border-radius: 24px; - height: 48px; - width: 100%; - padding: 8px; - display: flex; - align-items: center; - justify-content: center; - font-family: var(--text-body); - font-style: normal; - font-weight: 400; - font-size: 16px; - color: var(--text-color2); - cursor: pointer; -} - -#w3a-modal button.w3a-button:hover { - background: #595857; -} - -#w3a-modal button.w3a-button:active { - background: #6f717a; -} - -#w3a-modal button.w3a-button:disabled { - background: #27282d; - color: #6f717a; -} - -#w3a-modal button.w3a-button:focus-visible { - outline: 1px solid #daf0ff; - outline-offset: -1px; -} - -#w3a-modal button.w3a-button.w3ajs-external-toggle__button { - margin-bottom: 12px; -} - -#w3a-modal button.w3a-button.w3ajs-external-toggle__button:last-child { - margin-bottom: 0; -} - -#w3a-modal button.w3a-button--icon { - width: 48px; -} - -#w3a-modal button.w3a-button--left { - justify-content: start; - padding: 8px 16px; -} - -#w3a-modal button.w3a-button--left > img { - height: 30px; - width: auto; -} - -#w3a-modal button.w3a-button--left > div.w3a-button__name { - max-width: 180px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - text-transform: capitalize; -} - -#w3a-modal button.w3a-button--left > div.w3a-button__note { - margin-left: 8px; - color: #b7b8bd; - margin-left: auto; -} - -#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; -} - -#w3a-modal button.w3a-button.w3a-button--rotate .w3a-button__image { - transform: rotate(180deg); -} - -#w3a-modal .w3a-button--left .w3a-button__image { - margin-right: 12px; -} - -#w3a-modal button.w3a-button-expand { - height: unset; - width: auto; - margin-left: auto; - font-size: 12px; - margin-top: 16px; - display: flex; - border: 8px; - color: var(--text-color2); - align-items: center; - cursor: pointer; - border-radius: 12px; - cursor: pointer; - padding: 0 10px 0 8px; - background: transparent; -} - -#w3a-modal button.w3a-button-expand svg { - width: 12px; - height: auto; - margin-right: 4px; -} - -#w3a-modal .w3a-external-toggle { - display: block; -} - -#w3a-modal .w3a-external-toggle.w3a-external-toggle--hidden { - display: none; -} - -#w3a-modal .w3a-external-container { - display: block; - margin-bottom: 34px; -} - -#w3a-modal .w3a-external-container.w3a-external-container--hidden { - display: none; -} - -#w3a-modal .w3a-external-group { - display: flex; - flex-wrap: wrap; - gap: 12px; - margin-bottom: 16px; -} - -#w3a-modal .w3a-external-group__left { - flex-grow: 1; -} - -#w3a-modal button.w3a-external-back { - background: none; - border: 0; - padding: 0; - display: inline-flex; - align-items: center; - margin-bottom: 30px; - cursor: pointer; - color: var(--text-color1); -} - -#w3a-modal .w3a-external-back:focus-visible { - outline: 1px solid #daf0ff; -} - -#w3a-modal .w3a-external-back .w3a-group__title { - margin-bottom: 0; - margin-left: 5px; -} - -#w3a-modal .w3a-external-loader { - display: flex; - justify-content: center; -} - -#w3a-modal .w3a-wallet-connect { - display: block; - text-align: center; - margin-bottom: 16px; -} - -#w3a-modal .w3a-wallet-connect.w3a-wallet-connect--hidden { - display: none; -} - -#w3a-modal .w3a-wallet-connect__container { - background: #ffffff; - border-radius: 10px; - color: var(--text-color1); - font-size: 10px; - width: fit-content; - margin: auto; - min-width: 250px; - padding: 16px 12px; -} - -#w3a-modal .w3a-wallet-connect__container-desktop, -#w3a-modal .w3a-wallet-connect__container-android { - margin: auto; -} - -#w3a-modal .w3a-wallet-connect__container-btn-group { - display: flex; - gap: 18px; -} - -#w3a-modal .w3a-wallet-connect__container-ios { - display: flex; - grid-gap: 30px 20px; - padding: 0 0 28px; - box-sizing: border-box; - flex-wrap: wrap; -} - -#w3a-modal .w3a-wallet-connect-qr { - margin: 16px 16px; - padding: inherit; -} - -#w3a-modal .w3a-wallet-connect__container-android a { - text-decoration: none; -} - -#w3a-modal .w3a-wallet-connect__container-android .w3a-button { - background-color: rgb(64, 153, 255) !important; - color: #ffffff !important; - height: auto; - font-size: 14px; - padding: 8px 16px; - width: auto; - margin: auto; -} - -#w3a-modal .w3a-wallet-connect__logo > img { - text-align: center; - width: 115px; - margin-bottom: 16px; -} - -/* Text Field */ -#w3a-modal .w3a-text-field { - background: #393938; - border: 1px solid #27282d; - box-sizing: border-box; - box-shadow: inset 2px 2px 10px rgba(0, 0, 0, 0.4); - border-radius: 24px; - padding: 0 28px; - height: 48px; - width: 100%; - font-family: var(--text-body); - font-size: 16px; - color: var(--text-color2); - margin-bottom: 16px; -} - -#w3a-modal .w3a-text-field:active { - background: #0f1222; -} - -#w3a-modal .w3a-text-field:focus-visible { - outline: 1px solid #daf0ff; - outline-offset: -1px; -} - -/* Footer Components */ -#w3a-modal .w3a-footer { - display: flex; - justify-content: space-between; - align-items: center; - font-size: 10px; - line-height: 150%; - color: var(--text-color2); -} - -#w3a-modal .w3a-footer__links { - padding: 0; - margin: 0; -} - -#w3a-modal .w3a-footer__links a { - color: var(--text-color1); - text-decoration: none; -} - -#w3a-modal .w3a-footer__links a:focus-visible { - outline: 1px solid #daf0ff; -} - -#w3a-modal .w3a-footer__links span { - margin: 0 2px; -} - -#w3a-modal .w3a-footer__secured { - text-align: right; - color: #b7b8bd; -} -#w3a-modal .w3a-footer__secured > img { - height: 14px; - width: auto; -} - -/* Loader Bridge */ -#w3a-modal .w3a-modal__loader-bridge { - display: flex; - margin-bottom: 14px; -} - -#w3a-modal .w3a-modal__loader-bridge-message span { - text-transform: capitalize; -} - -#w3a-modal .w3a-modal__loader-app-logo { - display: flex; - padding: 8px; -} - -#w3a-modal .w3a-modal__loader-app-logo img { - width: 64px; - height: auto; -} - -#w3a-modal .w3a-modal__loader-adapter img { - width: 84px; - height: auto; -} - -#w3a-modal .w3a-modal__connector { - display: flex; - align-items: center; -} - -.w3a-modal__connector-beat { - display: inline-block; - position: relative; - width: 80px; - height: 80px; -} - -.w3a-modal__connector-beat div { - position: absolute; - top: 33px; - width: 13px; - height: 13px; - border-radius: 50%; - background: #808080; - animation-timing-function: cubic-bezier(0, 1, 1, 0); -} - -.w3a-modal__connector-beat div:nth-child(1) { - left: 8px; - animation: beat1 2.4s infinite; -} - -.w3a-modal__connector-beat div:nth-child(2) { - left: 8px; - animation: beat2 2.4s infinite; -} - -.w3a-modal__connector-beat div:nth-child(3) { - left: 8px; - animation: beat3 2.4s infinite; -} - -.w3a-modal__connector-beat div:nth-child(4) { - left: 32px; - animation: beat4 2.4s infinite; -} - -.w3a-modal__connector-beat div:nth-child(5) { - left: 56px; - animation: beat5 2.4s infinite; -} - -@keyframes beat1 { - 0% { - transform: scale(0); - } - - 25% { - transform: scale(0); - } - - 50% { - transform: scale(1); - } - - 75% { - transform: scale(0); - } - - 100% { - transform: scale(0); - } -} - -@keyframes beat2 { - 0% { - transform: scale(0); - } - - 25% { - transform: scale(1); - } - - 50% { - transform: translate(24px, 0); - } - - 75% { - transform: translate(0, 0); - } - - 100% { - transform: translate(0, 0) scale(0); - } -} - -@keyframes beat3 { - 0% { - transform: translate(0, 0); - } - - 25% { - transform: translate(24px, 0); - } - - 50% { - transform: translate(48px, 0); - } - - 75% { - transform: translate(24px, 0); - } - - 100% { - transform: translate(0, 0); - } -} - -@keyframes beat4 { - 0% { - transform: translate(0, 0); - } - - 25% { - transform: translate(24px, 0); - } - - 50% { - transform: translate(24px, 0) scale(0); - } - - 75% { - transform: translate(24px, 0) scale(1); - } - - 100% { - transform: translate(0, 0); - } -} - -@keyframes beat5 { - 0% { - transform: scale(1); - } - - 25% { - transform: scale(0); - } - - 50% { - transform: scale(0); - } - - 75% { - transform: scale(0); - } - - 100% { - transform: scale(1); - } -} - -/* LIGHT MODE */ -#w3a-modal.w3a-modal--light { - --bg1: #ffffff; - --bg2: #f9f9fb; - --text-color1: #a2a5b5; - --text-color2: #5c6c7f; -} - -#w3a-modal .w3a-group:not(.w3a-group--hidden):not(:last-child), -#w3a-modal .w3a-group:not(.w3a-group--social-hidden):not(:last-child), -#w3a-modal .w3a-group:not(.w3a-group--email-hidden):not(:last-child), -#w3a-modal .w3a-group:not(.w3a-group--ext-wallet-hidden):not(:last-child) { - border-bottom: 0.5px solid #b7b8bd; - padding-bottom: 24px; -} - -#w3a-modal.w3a-modal--light button.w3a-button { - background-color: #ffffff; - border: 1px solid #f3f3f4; - box-shadow: none; - color: #595857; -} - -#w3a-modal.w3a-modal--light button.w3a-button:disabled { - color: #b7b8bd; -} - -#w3a-modal.w3a-modal--light button.w3a-button:focus-visible { - outline: 1px solid #0f1222; -} - -#w3a-modal.w3a-modal--light .w3a-text-field { - background: #ffffff; - border: 1px solid #ffffff; - box-shadow: inset 2px 2px 10px rgba(0, 0, 0, 0.1); - color: #b7b8bd; -} - -#w3a-modal.w3a-modal--light .w3a-text-field:active { - color: #0f1222; - outline: 1px solid #0f1222; -} - -#w3a-modal.w3a-modal--light .w3a-text-field:focus-visible { - color: #0f1222; - outline: 1px solid #0f1222; -} - -#w3a-modal.w3a-modal--light .w3a-footer__links a:focus-visible { - outline: 1px solid #0f1222; -} - -#w3a-modal.w3a-modal--light .w3a-external-back:focus-visible { - outline: 1px solid #0f1222; -} diff --git a/packages/web3-auth/src/types/Web3AuthConfig.ts b/packages/web3-auth/src/types/Web3AuthConfig.ts deleted file mode 100644 index 404c7ef6e..000000000 --- a/packages/web3-auth/src/types/Web3AuthConfig.ts +++ /dev/null @@ -1,15 +0,0 @@ -export type DefaultSocialLoginConfig = { - backendUrl: string; -}; - -export type WhiteLabelDataType = { - name: string; - logo: string; -}; - -export type SocialLoginDTO = { - chainId: string; - whitelistUrls: { [P: 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 deleted file mode 100644 index 10bb465ec..000000000 --- a/packages/web3-auth/tests/web3-auth.spec.ts +++ /dev/null @@ -1,5 +0,0 @@ -describe("Web3 Auth Tests", () => { - it("should have a basic test", () => { - expect(true).toBe(true); - }); -}); diff --git a/packages/web3-auth/tsconfig.json b/packages/web3-auth/tsconfig.json deleted file mode 100644 index eb424084f..000000000 --- a/packages/web3-auth/tsconfig.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../../tsconfig.settings.json", - "compilerOptions": { - "jsx": "react", - "composite": true, - "outDir": "dist", - "baseUrl": "src", - "resolveJsonModule": true, - "esModuleInterop": true - }, - "include": ["src", "src/**/*.json"] -}