From b7c796f9d6a01b4674263815d5048aae30d6c95c Mon Sep 17 00:00:00 2001 From: Szabolcs Szentes Date: Thu, 4 Apr 2024 22:37:38 +0200 Subject: [PATCH] PublicOrWallet client abstraction on sdk calls --- src/index.ts | 11 +++++------ src/lib/erc2771/callWithSyncFeeERC2771/index.ts | 5 ++--- src/lib/erc2771/getDataToSignERC2771/index.ts | 12 +++++------- src/lib/erc2771/getSignatureDataERC2771/index.ts | 12 +++++------- src/lib/erc2771/sponsoredCallERC2771/index.ts | 7 +++---- src/lib/erc2771/utils/populatePayloadToSign.ts | 16 +++++++--------- src/lib/types/index.ts | 4 +++- src/utils/getPublicClient.ts | 15 +++++++++++++++ src/utils/getUserNonce.ts | 9 +++++---- src/utils/isSigner.ts | 6 +++--- src/utils/populateOptionalUserParameters.ts | 10 ++++------ src/utils/signTypedDataV4.ts | 11 ++++++----- 12 files changed, 63 insertions(+), 55 deletions(-) create mode 100644 src/utils/getPublicClient.ts diff --git a/src/index.ts b/src/index.ts index f815a04..b3b8f85 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,3 @@ -import { WalletClient } from "viem"; - import * as library from "./lib"; import { CallWithSyncFeeRequest } from "./lib/callWithSyncFee/types"; import { SponsoredCallRequest } from "./lib/sponsoredCall/types"; @@ -18,6 +16,7 @@ import { Config, RelayRequestOptions, RelayResponse, + PublicOrWalletClient, } from "./lib/types"; import { GELATO_RELAY_1BALANCE_ERC2771_ADDRESS, @@ -135,7 +134,7 @@ export class GelatoRelay { request: | CallWithSyncFeeERC2771Request | CallWithSyncFeeConcurrentERC2771Request, - client: WalletClient, + client: PublicOrWalletClient, options?: RelayRequestOptions, sponsorApiKey?: string ): Promise => { @@ -190,7 +189,7 @@ export class GelatoRelay { */ sponsoredCallERC2771 = async ( request: CallWithERC2771Request | CallWithConcurrentERC2771Request, - client: WalletClient, + client: PublicOrWalletClient, sponsorApiKey: string, options?: RelayRequestOptions ): Promise => { @@ -220,7 +219,7 @@ export class GelatoRelay { */ getSignatureDataERC2771 = ( request: CallWithERC2771Request | CallWithConcurrentERC2771Request, - client: WalletClient, + client: PublicOrWalletClient, type: ERC2771Type ): Promise => library.getSignatureDataERC2771({ request, client, type }, this.#config); @@ -235,7 +234,7 @@ export class GelatoRelay { getDataToSignERC2771 = ( request: CallWithERC2771Request | CallWithConcurrentERC2771Request, type: ERC2771Type, - client?: WalletClient + client?: PublicOrWalletClient ): Promise => library.getDataToSignERC2771({ request, client, type }, this.#config); diff --git a/src/lib/erc2771/callWithSyncFeeERC2771/index.ts b/src/lib/erc2771/callWithSyncFeeERC2771/index.ts index 0f7a382..027d821 100644 --- a/src/lib/erc2771/callWithSyncFeeERC2771/index.ts +++ b/src/lib/erc2771/callWithSyncFeeERC2771/index.ts @@ -1,5 +1,3 @@ -import { WalletClient } from "viem"; - import { post } from "../../../utils"; import { ApiKey, @@ -10,6 +8,7 @@ import { RelayCall, RelayRequestOptions, RelayResponse, + PublicOrWalletClient, } from "../../types"; import { CallWithConcurrentERC2771Struct, @@ -27,7 +26,7 @@ export const relayWithCallWithSyncFeeERC2771 = async ( request: | CallWithSyncFeeERC2771Request | CallWithSyncFeeConcurrentERC2771Request; - client: WalletClient; + client: PublicOrWalletClient; sponsorApiKey?: string; options?: RelayRequestOptions; }, diff --git a/src/lib/erc2771/getDataToSignERC2771/index.ts b/src/lib/erc2771/getDataToSignERC2771/index.ts index 2e6a148..468a3a5 100644 --- a/src/lib/erc2771/getDataToSignERC2771/index.ts +++ b/src/lib/erc2771/getDataToSignERC2771/index.ts @@ -1,8 +1,6 @@ -import { WalletClient } from "viem"; - import { isConcurrentRequest } from "../../../utils"; import { isNetworkSupported } from "../../network"; -import { Config } from "../../types"; +import { Config, PublicOrWalletClient } from "../../types"; import { CallWithERC2771Request, ERC2771Type, @@ -17,7 +15,7 @@ export async function getDataToSignERC2771( payload: { request: CallWithERC2771Request; type: ERC2771Type.CallWithSyncFee | ERC2771Type.SponsoredCall; - client?: WalletClient; + client?: PublicOrWalletClient; }, config: Config ): Promise; @@ -28,7 +26,7 @@ export async function getDataToSignERC2771( type: | ERC2771Type.ConcurrentCallWithSyncFee | ERC2771Type.ConcurrentSponsoredCall; - client?: WalletClient; + client?: PublicOrWalletClient; }, config: Config ): Promise; @@ -37,7 +35,7 @@ export async function getDataToSignERC2771( payload: { request: CallWithERC2771Request | CallWithConcurrentERC2771Request; type: ERC2771Type; - client?: WalletClient; + client?: PublicOrWalletClient; }, config: Config ): Promise; @@ -46,7 +44,7 @@ export async function getDataToSignERC2771( payload: { request: CallWithERC2771Request | CallWithConcurrentERC2771Request; type: ERC2771Type; - client?: WalletClient; + client?: PublicOrWalletClient; }, config: Config ): Promise { diff --git a/src/lib/erc2771/getSignatureDataERC2771/index.ts b/src/lib/erc2771/getSignatureDataERC2771/index.ts index dbc3b40..7af961c 100644 --- a/src/lib/erc2771/getSignatureDataERC2771/index.ts +++ b/src/lib/erc2771/getSignatureDataERC2771/index.ts @@ -1,7 +1,5 @@ -import { WalletClient } from "viem"; - import { isConcurrentRequest, signTypedDataV4 } from "../../../utils"; -import { Config } from "../../types"; +import { Config, PublicOrWalletClient } from "../../types"; import { SignatureData, CallWithERC2771Request, @@ -15,7 +13,7 @@ import { getDataToSignERC2771 } from "../getDataToSignERC2771/index.js"; export async function getSignatureDataERC2771( payload: { request: CallWithERC2771Request; - client: WalletClient; + client: PublicOrWalletClient; type: ERC2771Type.CallWithSyncFee | ERC2771Type.SponsoredCall; }, config: Config @@ -24,7 +22,7 @@ export async function getSignatureDataERC2771( export async function getSignatureDataERC2771( payload: { request: CallWithConcurrentERC2771Request; - client: WalletClient; + client: PublicOrWalletClient; type: | ERC2771Type.ConcurrentCallWithSyncFee | ERC2771Type.ConcurrentSponsoredCall; @@ -35,7 +33,7 @@ export async function getSignatureDataERC2771( export async function getSignatureDataERC2771( payload: { request: CallWithERC2771Request | CallWithConcurrentERC2771Request; - client: WalletClient; + client: PublicOrWalletClient; type: ERC2771Type; }, config: Config @@ -44,7 +42,7 @@ export async function getSignatureDataERC2771( export async function getSignatureDataERC2771( payload: { request: CallWithERC2771Request | CallWithConcurrentERC2771Request; - client: WalletClient; + client: PublicOrWalletClient; type: ERC2771Type; }, config: Config diff --git a/src/lib/erc2771/sponsoredCallERC2771/index.ts b/src/lib/erc2771/sponsoredCallERC2771/index.ts index eed3daa..2f5ec29 100644 --- a/src/lib/erc2771/sponsoredCallERC2771/index.ts +++ b/src/lib/erc2771/sponsoredCallERC2771/index.ts @@ -1,5 +1,3 @@ -import { WalletClient } from "viem"; - import { isConcurrentRequest, post } from "../../../utils"; import { ApiKey, @@ -8,6 +6,7 @@ import { RelayCall, RelayRequestOptions, RelayResponse, + PublicOrWalletClient, } from "../../types"; import { CallWithConcurrentERC2771Request, @@ -23,7 +22,7 @@ import { safeTransformStruct } from "../utils/safeTransformStruct.js"; export const relayWithSponsoredCallERC2771 = async ( payload: { request: CallWithERC2771Request | CallWithConcurrentERC2771Request; - client: WalletClient; + client: PublicOrWalletClient; sponsorApiKey: string; options?: RelayRequestOptions; }, @@ -35,7 +34,7 @@ export const relayWithSponsoredCallERC2771 = async ( const sponsoredCallERC2771 = async ( payload: { request: CallWithERC2771Request | CallWithConcurrentERC2771Request; - client: WalletClient; + client: PublicOrWalletClient; sponsorApiKey: string; options?: RelayRequestOptions; }, diff --git a/src/lib/erc2771/utils/populatePayloadToSign.ts b/src/lib/erc2771/utils/populatePayloadToSign.ts index e3324da..f3aaa40 100644 --- a/src/lib/erc2771/utils/populatePayloadToSign.ts +++ b/src/lib/erc2771/utils/populatePayloadToSign.ts @@ -1,5 +1,3 @@ -import { WalletClient } from "viem"; - import { CallWithConcurrentERC2771Request, CallWithERC2771Request, @@ -8,10 +6,10 @@ import { PayloadToSign, SequentialPayloadToSign, } from "../types"; -import { Config } from "../../types"; +import { Config, PublicOrWalletClient } from "../../types"; import { isConcurrentRequest, - isLocalSigner, + isWalletClient, populateOptionalUserParameters, } from "../../../utils"; @@ -25,7 +23,7 @@ export async function populatePayloadToSign( type: | ERC2771Type.ConcurrentCallWithSyncFee | ERC2771Type.ConcurrentSponsoredCall; - client?: WalletClient; + client?: PublicOrWalletClient; }, config: Config ): Promise; @@ -34,7 +32,7 @@ export async function populatePayloadToSign( payload: { request: CallWithERC2771Request; type: ERC2771Type.CallWithSyncFee | ERC2771Type.SponsoredCall; - client?: WalletClient; + client?: PublicOrWalletClient; }, config: Config ): Promise; @@ -43,7 +41,7 @@ export async function populatePayloadToSign( payload: { request: CallWithConcurrentERC2771Request | CallWithERC2771Request; type: ERC2771Type; - client?: WalletClient; + client?: PublicOrWalletClient; }, config: Config ): Promise { @@ -69,7 +67,7 @@ export async function populatePayloadToSign( { struct: safeStruct, type, - isSigner: client ? isLocalSigner(client) : undefined, + isSigner: client ? isWalletClient(client) : undefined, }, config ); @@ -99,7 +97,7 @@ export async function populatePayloadToSign( { struct: safeStruct, type, - isSigner: client ? isLocalSigner(client) : undefined, + isSigner: client ? isWalletClient(client) : undefined, }, config ); diff --git a/src/lib/types/index.ts b/src/lib/types/index.ts index a25a343..6f95e49 100644 --- a/src/lib/types/index.ts +++ b/src/lib/types/index.ts @@ -1,4 +1,4 @@ -import { Hex, ByteArray } from "viem"; +import { Hex, ByteArray, WalletClient, PublicClient } from "viem"; export enum RelayCall { CallWithSyncFee, @@ -77,3 +77,5 @@ export type SafeRequestPayload = { ? SafeRequestPayload : T[K]; }; + +export type PublicOrWalletClient = PublicClient | WalletClient; diff --git a/src/utils/getPublicClient.ts b/src/utils/getPublicClient.ts new file mode 100644 index 0000000..b0768ef --- /dev/null +++ b/src/utils/getPublicClient.ts @@ -0,0 +1,15 @@ +import { PublicClient, publicActions } from "viem"; + +import { PublicOrWalletClient } from "../lib/types"; + +export const getPublicClient = (client: PublicOrWalletClient): PublicClient => { + let publicClient: PublicClient; + if (client.type === "walletClient") { + publicClient = client.extend(publicActions) as PublicClient; + } else { + // publicClient + publicClient = client as PublicClient; + } + + return publicClient; +}; diff --git a/src/utils/getUserNonce.ts b/src/utils/getUserNonce.ts index f688f50..6d9c34a 100644 --- a/src/utils/getUserNonce.ts +++ b/src/utils/getUserNonce.ts @@ -1,16 +1,17 @@ -import { WalletClient, publicActions, parseAbi } from "viem"; +import { parseAbi } from "viem"; import { USER_NONCE_ABI } from "../constants"; -import { Config } from "../lib/types"; +import { Config, PublicOrWalletClient } from "../lib/types"; import { ERC2771Type } from "../lib/erc2771/types"; import { getGelatoRelayERC2771Address } from "./relayAddress"; +import { getPublicClient } from "./getPublicClient"; export const getUserNonce = async ( payload: { account: string; type: ERC2771Type; - client: WalletClient; + client: PublicOrWalletClient; }, config: Config ): Promise => { @@ -18,7 +19,7 @@ export const getUserNonce = async ( const chainId = BigInt(await client.getChainId()); - const publicClient = client.extend(publicActions); + const publicClient = getPublicClient(client); const nonce = await publicClient.readContract({ abi: parseAbi(USER_NONCE_ABI), diff --git a/src/utils/isSigner.ts b/src/utils/isSigner.ts index e93fd1b..30e3aa6 100644 --- a/src/utils/isSigner.ts +++ b/src/utils/isSigner.ts @@ -1,5 +1,5 @@ -import { WalletClient } from "viem"; +import { PublicOrWalletClient } from "../lib/types"; -export const isLocalSigner = (client: WalletClient): boolean => { - return client?.account?.type === "local"; +export const isWalletClient = (client: PublicOrWalletClient): boolean => { + return client.type === "walletClient"; }; diff --git a/src/utils/populateOptionalUserParameters.ts b/src/utils/populateOptionalUserParameters.ts index d64fa4f..7ed7b65 100644 --- a/src/utils/populateOptionalUserParameters.ts +++ b/src/utils/populateOptionalUserParameters.ts @@ -1,5 +1,3 @@ -import { WalletClient } from "viem"; - import { DEFAULT_DEADLINE_GAP } from "../constants"; import { CallWithConcurrentERC2771Request, @@ -8,7 +6,7 @@ import { CallWithERC2771RequestOptionalParameters, ERC2771Type, } from "../lib/erc2771/types"; -import { Config } from "../lib/types"; +import { Config, PublicOrWalletClient } from "../lib/types"; import { calculateDeadline } from "./calculateDeadline"; import { getUserNonce } from "./getUserNonce"; @@ -21,7 +19,7 @@ export async function populateOptionalUserParameters( type: | ERC2771Type.ConcurrentCallWithSyncFee | ERC2771Type.ConcurrentSponsoredCall; - client?: WalletClient; + client?: PublicOrWalletClient; }, config: Config @@ -31,7 +29,7 @@ export async function populateOptionalUserParameters( payload: { request: CallWithERC2771Request; type: ERC2771Type.CallWithSyncFee | ERC2771Type.SponsoredCall; - client?: WalletClient; + client?: PublicOrWalletClient; }, config: Config @@ -41,7 +39,7 @@ export async function populateOptionalUserParameters( payload: { request: CallWithConcurrentERC2771Request | CallWithERC2771Request; type: ERC2771Type; - client?: WalletClient; + client?: PublicOrWalletClient; }, config: Config diff --git a/src/utils/signTypedDataV4.ts b/src/utils/signTypedDataV4.ts index b84923a..55d23d8 100644 --- a/src/utils/signTypedDataV4.ts +++ b/src/utils/signTypedDataV4.ts @@ -1,5 +1,4 @@ -import { WalletClient } from "viem"; - +import { PublicOrWalletClient } from "../lib/types"; import { CallWithSyncFeeERC2771PayloadToSign, SponsoredCallERC2771PayloadToSign, @@ -7,17 +6,19 @@ import { CallWithSyncFeeConcurrentERC2771PayloadToSign, } from "../lib/erc2771/types"; +import { isWalletClient } from "./isSigner"; + export const signTypedDataV4 = async ( - client: WalletClient, + client: PublicOrWalletClient, payload: | SponsoredCallERC2771PayloadToSign | CallWithSyncFeeERC2771PayloadToSign | SponsoredCallConcurrentERC2771PayloadToSign | CallWithSyncFeeConcurrentERC2771PayloadToSign ): Promise => { - if (!client.account) { + if (!isWalletClient(client) || !client.account) { throw new Error( - "Account not found on client. Please, provide an account during the client creation." + "The provided client is not a wallet client, or account not found on the client. Please, provide an account during the client creation." ); }