Skip to content

Commit

Permalink
Merge pull request #194 from jayden-sudo/develop
Browse files Browse the repository at this point in the history
SoulWallet instances add parameter `_config` that can skip on-chain d…
  • Loading branch information
jayden-sudo authored Oct 18, 2024
2 parents aad3e5b + a3ae446 commit 61910bc
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 22 deletions.
5 changes: 5 additions & 0 deletions .changeset/itchy-files-whisper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@soulwallet/sdk": patch
---

SoulWallet instances add parameter `_config` that can skip on-chain detection
54 changes: 32 additions & 22 deletions packages/soulwallet-sdk/src/soulWallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { TypedDataDomain, TypedDataField, ethers } from "ethers";
import { GuardHookInputData, ISoulWallet, InitialKey, SignkeyType, Transaction } from "./interface/ISoulWallet.js";
import { UserOperation } from "./interface/UserOperation.js";
import { TypeGuard } from "./tools/typeGuard.js";
import { StorageCache } from "./tools/storageCache.js";
import { MemCache } from "./tools/memCache.js";
import { ABI_SoulWalletFactory, ABI_SoulWallet, ABI_EntryPoint } from "@soulwallet/abi";
import { HookInputData, Signature } from "./tools/signature.js";
// import { Hex } from "./tools/hex.js";
Expand All @@ -16,14 +16,14 @@ import { SocialRecovery } from "./socialRecovery.js";
import { ECCPoint, RSAPublicKey } from "./tools/webauthn.js";
import { WalletFactory } from "./tools/walletFactory.js";
import { StateOverride, UserOpGas } from "./interface/IBundler.js";
import { Address } from "./interface/types.js";

export class onChainConfig {
chainId: number = 0;
entryPoint: string = "";
soulWalletLogic: string = "";
export interface onChainConfig {
chainId: number;
entryPoint: Address;
soulWalletLogic: Address;
}


/**
* main class of the SDK.
*
Expand All @@ -37,20 +37,27 @@ export class SoulWallet implements ISoulWallet {
readonly soulWalletFactoryAddress: string;
readonly defalutCallbackHandlerAddress?: string;
readonly socialRecoveryModuleAddress?: string;

readonly preVerificationGasDeploy: number = 10000000;

readonly Bundler: Bundler;

private _onChainConfig: onChainConfig | undefined = undefined;


/**
* Creates an instance of SoulWallet.
* @param {(string | ethers.JsonRpcProvider)} _provider ethreum client rpc url
* @param {(string | ethers.JsonRpcProvider)} _bundler eip-4337 bundler rpc url
* @param {Address} _soulWalletFactoryAddress soulWalletFactory contract address
* @param {Address} [_defalutCallbackHandlerAddress] default callback handler contract address
* @param {Address} [_socialRecoveryModuleAddress] social recovery module contract address
* @param {onChainConfig} [_config] if provided, skip onchain config check
* @memberof SoulWallet
*/
constructor(
_provider: string | ethers.JsonRpcProvider,
_bundler: string | ethers.JsonRpcProvider,
_soulWalletFactoryAddress: string,
_defalutCallbackHandlerAddress?: string,
_socialRecoveryModuleAddress?: string
_soulWalletFactoryAddress: Address,
_defalutCallbackHandlerAddress?: Address,
_socialRecoveryModuleAddress?: Address,
_config?: onChainConfig
) {
if (typeof _provider === 'string') {
if (TypeGuard.httpOrHttps(_provider).isErr() === true) throw new Error("invalid provider");
Expand All @@ -77,6 +84,9 @@ export class SoulWallet implements ISoulWallet {
this.socialRecoveryModuleAddress = _socialRecoveryModuleAddress;
// this.defaultValidator = _defaultValidator;
this.Bundler = new Bundler(this.bundler);
if (_config !== undefined) {
this._onChainConfig = _config;
}
}


Expand All @@ -103,15 +113,13 @@ export class SoulWallet implements ISoulWallet {

const key = `onChainConfig_${this.soulWalletFactoryAddress}_${_chainId}`;
// read from cache
let _onChainConfig = StorageCache.getInstance().get<onChainConfig | undefined>(key, undefined);
let _onChainConfig = MemCache.getInstance().get<onChainConfig | undefined>(key, undefined);
if (!_onChainConfig) {
const _soulWalletFactory = new ethers.Contract(this.soulWalletFactoryAddress, ABI_SoulWalletFactory, this.provider);
const soulWalletLogic: string = await _soulWalletFactory.getFunction("_WALLETIMPL").staticCall();
const _soulWallet = new ethers.Contract(soulWalletLogic, ABI_SoulWallet, this.provider);
const entryPoint: string = await _soulWallet.getFunction("entryPoint").staticCall();

_onChainConfig = new onChainConfig();

const _bundlerChainIdBigint = (await this.bundler.getNetwork()).chainId;
const _bundlerChainId: number = Number(_bundlerChainIdBigint);
if (Number.isSafeInteger(_bundlerChainId)) {
Expand All @@ -132,12 +140,14 @@ export class SoulWallet implements ISoulWallet {
);
}

_onChainConfig.chainId = _chainId;
_onChainConfig.entryPoint = entryPoint;
_onChainConfig.soulWalletLogic = soulWalletLogic;
_onChainConfig = {
chainId: _chainId,
entryPoint: entryPoint,
soulWalletLogic: soulWalletLogic
} as onChainConfig;

// save to cache
StorageCache.getInstance().set(key, _onChainConfig);
MemCache.getInstance().set(key, _onChainConfig);

// check bundler RPC
const ret = await this.Bundler.eth_supportedEntryPoints();
Expand Down Expand Up @@ -724,14 +734,14 @@ export class SoulWallet implements ISoulWallet {
}
const key = `${walletAddress}-${_onChainConfig.OK.chainId}`;

if (StorageCache.getInstance().get<boolean>(key, false)) {
if (MemCache.getInstance().get<boolean>(key, false)) {
return new Ok(true);
}
try {
const code = await this.provider.getCode(walletAddress);
const deployed = code !== "0x";
if (deployed) {
StorageCache.getInstance().set(key, true);
MemCache.getInstance().set(key, true);
}
return new Ok(deployed);
} catch (error: unknown) {
Expand Down
45 changes: 45 additions & 0 deletions packages/soulwallet-sdk/src/tools/memCache.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
export class MemCache {
private static instance?: MemCache = undefined;

public static getInstance(): MemCache {
if (!MemCache.instance)
MemCache.instance = new MemCache();
return MemCache.instance!;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
private storage: Record<string, any> = {};

private constructor() { }

/**
*
*
* @template T
* @param {string} key
* @param {T} value
*/
public set<T>(key: string, value: T) {
if (value === undefined) {
throw new Error("value is undefined");
}
this.storage[key] = value;
}

/**
*
*
* @template T
* @param {string} key
* @param {T} defaultValue
* @return {*} {T}
*/
public get<T>(key: string, defaultValue: T): T {
if (key in this.storage) {
const v = this.storage[key] as T;
if (v !== undefined) {
return v;
}
}
return defaultValue;
}
}

0 comments on commit 61910bc

Please sign in to comment.