@zerodev/sdk 4.0.31 → 4.0.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/kernel-zerodev/abis/KernelAccountAbi.d.ts +42 -4
- package/dist/cjs/kernel-zerodev/abis/KernelAccountAbi.js +53 -4
- package/dist/cjs/kernel-zerodev/abis/KernelAccountAbi.js.map +1 -1
- package/dist/cjs/kernel-zerodev/account.d.ts +3 -0
- package/dist/cjs/kernel-zerodev/account.js +47 -6
- package/dist/cjs/kernel-zerodev/account.js.map +1 -1
- package/dist/cjs/kernel-zerodev/client/create-client.js.map +1 -1
- package/dist/cjs/kernel-zerodev/constants.d.ts +2 -2
- package/dist/cjs/kernel-zerodev/constants.js +2 -2
- package/dist/cjs/kernel-zerodev/constants.js.map +1 -1
- package/dist/cjs/kernel-zerodev/ethers-provider/account-signer.d.ts +1 -1
- package/dist/cjs/kernel-zerodev/ethers-provider/account-signer.js.map +1 -1
- package/dist/cjs/kernel-zerodev/middleware/paymaster.js +19 -6
- package/dist/cjs/kernel-zerodev/middleware/paymaster.js.map +1 -1
- package/dist/cjs/kernel-zerodev/owner/getCustodialOwner.d.ts +7 -3
- package/dist/cjs/kernel-zerodev/owner/getCustodialOwner.js +45 -18
- package/dist/cjs/kernel-zerodev/owner/getCustodialOwner.js.map +1 -1
- package/dist/cjs/kernel-zerodev/owner/passkey/createPasskeyOwner.js.map +1 -1
- package/dist/cjs/kernel-zerodev/owner/passkey/getAutocompletePasskeyOwner.js.map +1 -1
- package/dist/cjs/kernel-zerodev/owner/passkey/getPasskeyOwner.js.map +1 -1
- package/dist/cjs/kernel-zerodev/owner/passkey/utils.d.ts +0 -1
- package/dist/cjs/kernel-zerodev/owner/passkey/utils.js.map +1 -1
- package/dist/cjs/kernel-zerodev/paymaster/base.js +36 -33
- package/dist/cjs/kernel-zerodev/paymaster/base.js.map +1 -1
- package/dist/cjs/kernel-zerodev/paymaster/token-paymaster.d.ts +4 -3
- package/dist/cjs/kernel-zerodev/paymaster/token-paymaster.js +48 -39
- package/dist/cjs/kernel-zerodev/paymaster/token-paymaster.js.map +1 -1
- package/dist/cjs/kernel-zerodev/paymaster/verifying-paymaster.js +7 -15
- package/dist/cjs/kernel-zerodev/paymaster/verifying-paymaster.js.map +1 -1
- package/dist/cjs/kernel-zerodev/provider.js +1 -2
- package/dist/cjs/kernel-zerodev/provider.js.map +1 -1
- package/dist/esm/kernel-zerodev/abis/KernelAccountAbi.d.ts +42 -4
- package/dist/esm/kernel-zerodev/abis/KernelAccountAbi.js +53 -4
- package/dist/esm/kernel-zerodev/abis/KernelAccountAbi.js.map +1 -1
- package/dist/esm/kernel-zerodev/account.d.ts +3 -0
- package/dist/esm/kernel-zerodev/account.js +47 -6
- package/dist/esm/kernel-zerodev/account.js.map +1 -1
- package/dist/esm/kernel-zerodev/client/create-client.js.map +1 -1
- package/dist/esm/kernel-zerodev/constants.d.ts +2 -2
- package/dist/esm/kernel-zerodev/constants.js +2 -2
- package/dist/esm/kernel-zerodev/constants.js.map +1 -1
- package/dist/esm/kernel-zerodev/ethers-provider/account-signer.d.ts +1 -1
- package/dist/esm/kernel-zerodev/ethers-provider/account-signer.js.map +1 -1
- package/dist/esm/kernel-zerodev/middleware/paymaster.js +19 -6
- package/dist/esm/kernel-zerodev/middleware/paymaster.js.map +1 -1
- package/dist/esm/kernel-zerodev/owner/getCustodialOwner.d.ts +7 -3
- package/dist/esm/kernel-zerodev/owner/getCustodialOwner.js +46 -18
- package/dist/esm/kernel-zerodev/owner/getCustodialOwner.js.map +1 -1
- package/dist/esm/kernel-zerodev/owner/passkey/createPasskeyOwner.js.map +1 -1
- package/dist/esm/kernel-zerodev/owner/passkey/getAutocompletePasskeyOwner.js.map +1 -1
- package/dist/esm/kernel-zerodev/owner/passkey/getPasskeyOwner.js.map +1 -1
- package/dist/esm/kernel-zerodev/owner/passkey/utils.d.ts +0 -1
- package/dist/esm/kernel-zerodev/owner/passkey/utils.js.map +1 -1
- package/dist/esm/kernel-zerodev/paymaster/base.js +36 -33
- package/dist/esm/kernel-zerodev/paymaster/base.js.map +1 -1
- package/dist/esm/kernel-zerodev/paymaster/token-paymaster.d.ts +4 -3
- package/dist/esm/kernel-zerodev/paymaster/token-paymaster.js +47 -39
- package/dist/esm/kernel-zerodev/paymaster/token-paymaster.js.map +1 -1
- package/dist/esm/kernel-zerodev/paymaster/verifying-paymaster.js +7 -15
- package/dist/esm/kernel-zerodev/paymaster/verifying-paymaster.js.map +1 -1
- package/dist/esm/kernel-zerodev/provider.js +1 -2
- package/dist/esm/kernel-zerodev/provider.js.map +1 -1
- package/dist/types/kernel-zerodev/abis/KernelAccountAbi.d.ts +42 -4
- package/dist/types/kernel-zerodev/abis/KernelAccountAbi.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/account.d.ts +3 -0
- package/dist/types/kernel-zerodev/account.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/client/create-client.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/constants.d.ts +2 -2
- package/dist/types/kernel-zerodev/constants.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/ethers-provider/account-signer.d.ts +1 -1
- package/dist/types/kernel-zerodev/ethers-provider/account-signer.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/middleware/paymaster.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/owner/getCustodialOwner.d.ts +7 -3
- package/dist/types/kernel-zerodev/owner/getCustodialOwner.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/owner/passkey/createPasskeyOwner.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/owner/passkey/getAutocompletePasskeyOwner.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/owner/passkey/getPasskeyOwner.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/owner/passkey/utils.d.ts +0 -1
- package/dist/types/kernel-zerodev/owner/passkey/utils.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/paymaster/base.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/paymaster/token-paymaster.d.ts +4 -3
- package/dist/types/kernel-zerodev/paymaster/token-paymaster.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/paymaster/verifying-paymaster.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/provider.d.ts.map +1 -1
- package/package.json +4 -2
- package/src/kernel-zerodev/abis/KernelAccountAbi.ts +53 -4
- package/src/kernel-zerodev/account.ts +57 -10
- package/src/kernel-zerodev/client/create-client.ts +1 -0
- package/src/kernel-zerodev/constants.ts +3 -2
- package/src/kernel-zerodev/ethers-provider/account-signer.ts +1 -1
- package/src/kernel-zerodev/middleware/paymaster.ts +20 -9
- package/src/kernel-zerodev/owner/getCustodialOwner.ts +94 -36
- package/src/kernel-zerodev/owner/passkey/createPasskeyOwner.ts +0 -4
- package/src/kernel-zerodev/owner/passkey/getAutocompletePasskeyOwner.ts +0 -2
- package/src/kernel-zerodev/owner/passkey/getPasskeyOwner.ts +0 -2
- package/src/kernel-zerodev/owner/passkey/utils.ts +0 -1
- package/src/kernel-zerodev/paymaster/base.ts +44 -38
- package/src/kernel-zerodev/paymaster/token-paymaster.ts +74 -53
- package/src/kernel-zerodev/paymaster/verifying-paymaster.ts +7 -14
- package/src/kernel-zerodev/provider.ts +1 -2
|
@@ -1,9 +1,30 @@
|
|
|
1
|
-
import type { SmartAccountSigner } from "@alchemy/aa-core";
|
|
1
|
+
import type { SignTypedDataParams, SmartAccountSigner } from "@alchemy/aa-core";
|
|
2
2
|
import { API_URL } from "../constants.js";
|
|
3
3
|
import axios from "axios";
|
|
4
|
-
import
|
|
5
|
-
import type { SignTypedDataParams } from "@alchemy/aa-core";
|
|
4
|
+
import { TurnkeyClient } from "@turnkey/http";
|
|
6
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Params to get a custodial owner
|
|
8
|
+
* Priv / pub key combo or custodial file path should be in different types
|
|
9
|
+
*/
|
|
10
|
+
type GetCustodialOwnerParams = {
|
|
11
|
+
// ZeroDev api url
|
|
12
|
+
apiUrl?: string;
|
|
13
|
+
// Turnkey client (if the client want to reuse it
|
|
14
|
+
turnKeyClient?: TurnkeyClient;
|
|
15
|
+
|
|
16
|
+
// Direct access to priv / pub key
|
|
17
|
+
privateKey?: string;
|
|
18
|
+
publicKey?: string;
|
|
19
|
+
keyId?: string;
|
|
20
|
+
|
|
21
|
+
// Or read them from the custodial file path
|
|
22
|
+
custodialFilePath?: string;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Returns a signer for a custodial wallet via TurnKey
|
|
27
|
+
*/
|
|
7
28
|
export async function getCustodialOwner(
|
|
8
29
|
identifier: string,
|
|
9
30
|
{
|
|
@@ -12,14 +33,10 @@ export async function getCustodialOwner(
|
|
|
12
33
|
publicKey,
|
|
13
34
|
keyId,
|
|
14
35
|
apiUrl = API_URL,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
publicKey?: string;
|
|
18
|
-
keyId?: string;
|
|
19
|
-
custodialFilePath?: string;
|
|
20
|
-
apiUrl?: string;
|
|
21
|
-
}
|
|
36
|
+
turnKeyClient,
|
|
37
|
+
}: GetCustodialOwnerParams
|
|
22
38
|
): Promise<SmartAccountSigner | undefined> {
|
|
39
|
+
// Extract data from the custodial file path if provided
|
|
23
40
|
if (custodialFilePath) {
|
|
24
41
|
let fsModule;
|
|
25
42
|
try {
|
|
@@ -30,45 +47,86 @@ export async function getCustodialOwner(
|
|
|
30
47
|
}
|
|
31
48
|
const data = fsModule.readFileSync(custodialFilePath, "utf8");
|
|
32
49
|
const values = data.split("\n");
|
|
50
|
+
// Override the values, if they are provided, to the one from the custodial file
|
|
33
51
|
[privateKey, publicKey, keyId] = values;
|
|
34
52
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
TurnkeySigner =
|
|
38
|
-
require.resolve("@turnkey/ethers") &&
|
|
39
|
-
require("@turnkey/ethers").TurnkeySigner;
|
|
40
|
-
} catch (error) {
|
|
41
|
-
console.log(
|
|
42
|
-
"@turnkey/ethers module not available. Skipping FS operation..."
|
|
43
|
-
);
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
53
|
+
|
|
54
|
+
// Ensure we have the required values
|
|
46
55
|
if (!privateKey || !publicKey || !keyId) {
|
|
47
56
|
throw new Error(
|
|
48
57
|
"Must provide custodialFilePath or privateKey, publicKey, and keyId."
|
|
49
58
|
);
|
|
50
59
|
}
|
|
51
60
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
61
|
+
// Get our turnkey client (build it if needed)
|
|
62
|
+
if (!turnKeyClient) {
|
|
63
|
+
// Try to fetch turnkey client & api key stamper
|
|
64
|
+
let TurnkeyClient;
|
|
65
|
+
let ApiKeyStamper;
|
|
66
|
+
// TODO: Would be cleaner with something like radash and a tryit function?
|
|
67
|
+
try {
|
|
68
|
+
TurnkeyClient =
|
|
69
|
+
require.resolve("@turnkey/http") &&
|
|
70
|
+
require("@turnkey/http").TurnkeyClient;
|
|
71
|
+
ApiKeyStamper =
|
|
72
|
+
require.resolve("@turnkey/api-key-stamper") &&
|
|
73
|
+
require("@turnkey/api-key-stamper").ApiKeyStamper;
|
|
74
|
+
} catch (error) {
|
|
75
|
+
console.log(
|
|
76
|
+
"@turnkey/http or @turnkey/api-key-stamper module not available. Skipping FS operation..."
|
|
77
|
+
);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
55
80
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
81
|
+
// Build the turnkey client
|
|
82
|
+
turnKeyClient = new TurnkeyClient(
|
|
83
|
+
{
|
|
84
|
+
baseUrl: "https://api.turnkey.com",
|
|
85
|
+
},
|
|
86
|
+
new ApiKeyStamper({
|
|
87
|
+
apiPublicKey: publicKey,
|
|
88
|
+
apiPrivateKey: privateKey,
|
|
89
|
+
})
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Get the wallet identifier from the API
|
|
94
|
+
const response = await axios.post<any, { data: { walletId: string } }>(
|
|
95
|
+
`${apiUrl}/wallets/${identifier}`,
|
|
96
|
+
{
|
|
97
|
+
keyId,
|
|
98
|
+
}
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
// Build the turnkey viem account
|
|
102
|
+
let createAccount;
|
|
103
|
+
try {
|
|
104
|
+
createAccount =
|
|
105
|
+
require.resolve("@turnkey/viem") &&
|
|
106
|
+
require("@turnkey/viem").createAccount;
|
|
107
|
+
} catch (error) {
|
|
108
|
+
console.log("@turnkey/viem module not available. Skipping FS operation...");
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const turnkeySigner = await createAccount({
|
|
112
|
+
client: turnKeyClient,
|
|
60
113
|
organizationId: keyId,
|
|
61
114
|
privateKeyId: response.data.walletId,
|
|
62
115
|
});
|
|
116
|
+
|
|
117
|
+
// Return an alchemy AA signer from the turnkey signer
|
|
63
118
|
return {
|
|
64
|
-
getAddress: async () =>
|
|
65
|
-
signMessage: async (msg: Uint8Array | string) =>
|
|
66
|
-
(
|
|
119
|
+
getAddress: async () => turnkeySigner.address,
|
|
120
|
+
signMessage: async (msg: Uint8Array | string) => {
|
|
121
|
+
if (typeof msg === "string") {
|
|
122
|
+
// If the msg is a string, sign it directly
|
|
123
|
+
return turnkeySigner.signMessage({ message: msg });
|
|
124
|
+
} else {
|
|
125
|
+
// Otherwise, sign the raw data
|
|
126
|
+
return turnkeySigner.signMessage({ message: { raw: msg } });
|
|
127
|
+
}
|
|
128
|
+
},
|
|
67
129
|
signTypedData: async (params: SignTypedDataParams) =>
|
|
68
|
-
|
|
69
|
-
params.domain,
|
|
70
|
-
params.types,
|
|
71
|
-
params.message
|
|
72
|
-
)) as Hex,
|
|
130
|
+
turnkeySigner.signTypedData(params),
|
|
73
131
|
};
|
|
74
132
|
}
|
|
@@ -27,7 +27,6 @@ export async function createPasskeyOwner({
|
|
|
27
27
|
fallback?: () => Promise<SmartAccountSigner | undefined>;
|
|
28
28
|
apiUrl?: string;
|
|
29
29
|
}): Promise<SmartAccountSigner | undefined> {
|
|
30
|
-
//@ts-expect-error
|
|
31
30
|
if (typeof window !== "undefined") {
|
|
32
31
|
const challenge = generateRandomBuffer();
|
|
33
32
|
let credentials = undefined;
|
|
@@ -43,9 +42,7 @@ export async function createPasskeyOwner({
|
|
|
43
42
|
const attestation = await getWebAuthnAttestation({
|
|
44
43
|
publicKey: {
|
|
45
44
|
rp: {
|
|
46
|
-
//@ts-expect-error
|
|
47
45
|
id: window.location.hostname,
|
|
48
|
-
//@ts-expect-error
|
|
49
46
|
name: window.location.hostname,
|
|
50
47
|
},
|
|
51
48
|
authenticatorSelection: {
|
|
@@ -100,7 +97,6 @@ export async function createPasskeyOwner({
|
|
|
100
97
|
};
|
|
101
98
|
return owner;
|
|
102
99
|
} catch (e) {
|
|
103
|
-
//@ts-expect-error
|
|
104
100
|
if (e instanceof DOMException && e.name === "InvalidStateError") {
|
|
105
101
|
if (fallback) return await fallback();
|
|
106
102
|
}
|
|
@@ -28,7 +28,6 @@ export async function getAutocompletePasskeyOwner({
|
|
|
28
28
|
return;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
//@ts-expect-error
|
|
32
31
|
if (typeof window !== "undefined") {
|
|
33
32
|
const challenge = generateRandomBuffer();
|
|
34
33
|
try {
|
|
@@ -37,7 +36,6 @@ export async function getAutocompletePasskeyOwner({
|
|
|
37
36
|
await getWebAuthnAssertion(base64UrlEncode(challenge), {
|
|
38
37
|
mediation: "conditional",
|
|
39
38
|
publicKey: {
|
|
40
|
-
//@ts-expect-error
|
|
41
39
|
rpId: window.location.hostname,
|
|
42
40
|
userVerification: "required",
|
|
43
41
|
},
|
|
@@ -22,7 +22,6 @@ export async function getPasskeyOwner({
|
|
|
22
22
|
apiUrl?: string;
|
|
23
23
|
withCredentials?: boolean;
|
|
24
24
|
}): Promise<SmartAccountSigner | undefined> {
|
|
25
|
-
//@ts-expect-error
|
|
26
25
|
if (typeof window !== "undefined") {
|
|
27
26
|
const challenge = generateRandomBuffer();
|
|
28
27
|
try {
|
|
@@ -30,7 +29,6 @@ export async function getPasskeyOwner({
|
|
|
30
29
|
const assertion = JSON.parse(
|
|
31
30
|
await getWebAuthnAssertion(base64UrlEncode(challenge), {
|
|
32
31
|
publicKey: {
|
|
33
|
-
//@ts-expect-error
|
|
34
32
|
rpId: window.location.hostname,
|
|
35
33
|
userVerification: "required",
|
|
36
34
|
allowCredentials: withCredentials
|
|
@@ -36,45 +36,51 @@ export abstract class Paymaster {
|
|
|
36
36
|
paymasterProvider?: PaymasterAndBundlerProviders;
|
|
37
37
|
shouldOverrideFee?: boolean;
|
|
38
38
|
}): Promise<any> {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
resolvedERC20UserOp = await resolveProperties(erc20UserOp);
|
|
39
|
+
const hexifiedUserOp = deepHexlify(await resolveProperties(userOp));
|
|
40
|
+
let resolvedERC20UserOp;
|
|
41
|
+
let hexifiedERC20UserOp: any;
|
|
42
|
+
if (erc20UserOp) {
|
|
43
|
+
resolvedERC20UserOp = await resolveProperties(erc20UserOp);
|
|
45
44
|
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
const chainId = await getChainId(this.provider.getProjectId());
|
|
49
|
-
if (!chainId) throw new Error("ChainId not found");
|
|
50
|
-
let requestBodyParams = Object.fromEntries(
|
|
51
|
-
Object.entries({
|
|
52
|
-
projectId: this.provider.getProjectId(),
|
|
53
|
-
chainId,
|
|
54
|
-
userOp: hexifiedUserOp,
|
|
55
|
-
entryPointAddress: ENTRYPOINT_ADDRESS,
|
|
56
|
-
callData: callData instanceof Promise ? await callData : callData,
|
|
57
|
-
tokenAddress: gasTokenAddress,
|
|
58
|
-
erc20UserOp: hexifiedERC20UserOp,
|
|
59
|
-
erc20CallData:
|
|
60
|
-
erc20CallData instanceof Promise
|
|
61
|
-
? await erc20CallData
|
|
62
|
-
: erc20CallData,
|
|
63
|
-
paymasterProvider,
|
|
64
|
-
shouldOverrideFee,
|
|
65
|
-
}).filter(([_, value]) => value !== undefined)
|
|
66
|
-
);
|
|
67
|
-
const { data: paymasterResp } = await axios.post(
|
|
68
|
-
`${PAYMASTER_URL}/sign`,
|
|
69
|
-
{
|
|
70
|
-
...requestBodyParams,
|
|
71
|
-
},
|
|
72
|
-
{ headers: { "Content-Type": "application/json" } }
|
|
73
|
-
);
|
|
74
|
-
return paymasterResp;
|
|
75
|
-
} catch (error) {
|
|
76
|
-
console.log(error);
|
|
77
|
-
return undefined;
|
|
45
|
+
hexifiedERC20UserOp = hexifyUserOp(resolvedERC20UserOp);
|
|
78
46
|
}
|
|
47
|
+
const chainId = await getChainId(this.provider.getProjectId());
|
|
48
|
+
if (!chainId) throw new Error("ChainId not found");
|
|
49
|
+
let requestBodyParams = Object.fromEntries(
|
|
50
|
+
Object.entries({
|
|
51
|
+
projectId: this.provider.getProjectId(),
|
|
52
|
+
chainId,
|
|
53
|
+
userOp: hexifiedUserOp,
|
|
54
|
+
entryPointAddress: ENTRYPOINT_ADDRESS,
|
|
55
|
+
callData: callData instanceof Promise ? await callData : callData,
|
|
56
|
+
gasTokenData:
|
|
57
|
+
gasTokenAddress && hexifiedERC20UserOp && erc20CallData
|
|
58
|
+
? {
|
|
59
|
+
tokenAddress: gasTokenAddress,
|
|
60
|
+
erc20UserOp: hexifiedERC20UserOp,
|
|
61
|
+
erc20CallData:
|
|
62
|
+
erc20CallData instanceof Promise
|
|
63
|
+
? await erc20CallData
|
|
64
|
+
: erc20CallData,
|
|
65
|
+
}
|
|
66
|
+
: undefined,
|
|
67
|
+
tokenAddress: gasTokenAddress,
|
|
68
|
+
erc20UserOp: hexifiedERC20UserOp,
|
|
69
|
+
erc20CallData:
|
|
70
|
+
erc20CallData instanceof Promise
|
|
71
|
+
? await erc20CallData
|
|
72
|
+
: erc20CallData,
|
|
73
|
+
paymasterProvider,
|
|
74
|
+
shouldOverrideFee,
|
|
75
|
+
}).filter(([_, value]) => value !== undefined)
|
|
76
|
+
);
|
|
77
|
+
const { data: paymasterResp } = await axios.post(
|
|
78
|
+
`${PAYMASTER_URL}/getPaymasterAndData`,
|
|
79
|
+
{
|
|
80
|
+
...requestBodyParams,
|
|
81
|
+
},
|
|
82
|
+
{ headers: { "Content-Type": "application/json" } }
|
|
83
|
+
);
|
|
84
|
+
return paymasterResp;
|
|
79
85
|
}
|
|
80
86
|
}
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
type BytesLike,
|
|
4
4
|
type UserOperationCallData,
|
|
5
5
|
type UserOperationStruct,
|
|
6
|
+
type BatchUserOperationCallData,
|
|
6
7
|
} from "@alchemy/aa-core";
|
|
7
8
|
import axios from "axios";
|
|
8
9
|
import {
|
|
@@ -14,12 +15,11 @@ import {
|
|
|
14
15
|
} from "viem";
|
|
15
16
|
import { ERC20Abi } from "../abis/ERC20Abi.js";
|
|
16
17
|
import { KernelAccountAbi } from "../abis/KernelAccountAbi.js";
|
|
17
|
-
import { MultiSendAbi } from "../abis/MultiSendAbi.js";
|
|
18
18
|
import {
|
|
19
19
|
PAYMASTER_URL,
|
|
20
20
|
ENTRYPOINT_ADDRESS,
|
|
21
|
-
MULTISEND_ADDR,
|
|
22
21
|
ERC20_APPROVAL_AMOUNT,
|
|
22
|
+
MULTISEND_ADDR,
|
|
23
23
|
} from "../constants.js";
|
|
24
24
|
import {
|
|
25
25
|
AccountNotConnected,
|
|
@@ -36,7 +36,13 @@ import {
|
|
|
36
36
|
type PaymasterConfig,
|
|
37
37
|
} from "./types.js";
|
|
38
38
|
import { getChainId } from "../api/index.js";
|
|
39
|
+
import { MultiSendAbi } from "../abis/MultiSendAbi.js";
|
|
39
40
|
|
|
41
|
+
export function isBatchUserOperationCallData(
|
|
42
|
+
data: any
|
|
43
|
+
): data is BatchUserOperationCallData {
|
|
44
|
+
return data && Array.isArray(data);
|
|
45
|
+
}
|
|
40
46
|
export class TokenPaymaster extends Paymaster {
|
|
41
47
|
constructor(
|
|
42
48
|
provider: ZeroDevProvider,
|
|
@@ -68,7 +74,12 @@ export class TokenPaymaster extends Paymaster {
|
|
|
68
74
|
async decodeMainCallFromCallData(
|
|
69
75
|
kernelAddress: PromiseOrValue<string>,
|
|
70
76
|
callData: PromiseOrValue<BytesLike>
|
|
71
|
-
): Promise<
|
|
77
|
+
): Promise<
|
|
78
|
+
| UserOperationCallData
|
|
79
|
+
| BatchUserOperationCallData
|
|
80
|
+
| UserOperationCallDataWithDelegate
|
|
81
|
+
| undefined
|
|
82
|
+
> {
|
|
72
83
|
let data: Hex = "0x";
|
|
73
84
|
if (callData instanceof Promise) {
|
|
74
85
|
const _data = await callData;
|
|
@@ -113,6 +124,13 @@ export class TokenPaymaster extends Paymaster {
|
|
|
113
124
|
};
|
|
114
125
|
}
|
|
115
126
|
return mainCall;
|
|
127
|
+
} else if (functionName === "executeBatch") {
|
|
128
|
+
const [txs] = args;
|
|
129
|
+
return txs.map((tx) => ({
|
|
130
|
+
target: tx.to,
|
|
131
|
+
value: tx.value ?? 0n,
|
|
132
|
+
data: tx.data,
|
|
133
|
+
}));
|
|
116
134
|
}
|
|
117
135
|
} catch (error) {
|
|
118
136
|
return {
|
|
@@ -127,9 +145,11 @@ export class TokenPaymaster extends Paymaster {
|
|
|
127
145
|
return;
|
|
128
146
|
}
|
|
129
147
|
|
|
130
|
-
async getERC20UserOp
|
|
148
|
+
async getERC20UserOp<
|
|
149
|
+
T extends UserOperationCallData | BatchUserOperationCallData
|
|
150
|
+
>(
|
|
131
151
|
struct: UserOperationStruct,
|
|
132
|
-
mainCall:
|
|
152
|
+
mainCall: T,
|
|
133
153
|
gasTokenAddress: Hex,
|
|
134
154
|
paymasterAddress: Hex
|
|
135
155
|
): Promise<UserOperationStruct | undefined> {
|
|
@@ -146,10 +166,17 @@ export class TokenPaymaster extends Paymaster {
|
|
|
146
166
|
if (!this.provider.account) {
|
|
147
167
|
throw AccountNotConnected;
|
|
148
168
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
169
|
+
|
|
170
|
+
let calls: BatchUserOperationCallData;
|
|
171
|
+
|
|
172
|
+
if (isBatchUserOperationCallData(mainCall)) {
|
|
173
|
+
calls = [approveData, ...mainCall];
|
|
174
|
+
} else {
|
|
175
|
+
calls = [approveData, mainCall];
|
|
176
|
+
}
|
|
177
|
+
const erc20CallData = await this.provider.account.encodeBatchExecute(
|
|
178
|
+
calls
|
|
179
|
+
);
|
|
153
180
|
return {
|
|
154
181
|
...struct,
|
|
155
182
|
callData: erc20CallData,
|
|
@@ -176,52 +203,46 @@ export class TokenPaymaster extends Paymaster {
|
|
|
176
203
|
paymasterProvider?: PaymasterAndBundlerProviders,
|
|
177
204
|
shouldOverrideFee?: boolean
|
|
178
205
|
): Promise<UserOperationStruct | undefined> {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
206
|
+
const mainCall = await this.decodeMainCallFromCallData(
|
|
207
|
+
struct.sender,
|
|
208
|
+
struct.callData
|
|
209
|
+
);
|
|
210
|
+
if (!mainCall) {
|
|
211
|
+
throw IncorrectCallDataForTokenPaymaster;
|
|
212
|
+
}
|
|
213
|
+
const chainId = await getChainId(this.provider.getProjectId());
|
|
214
|
+
if (!chainId) {
|
|
215
|
+
throw new Error("ChainId not found");
|
|
216
|
+
}
|
|
217
|
+
const gasTokenAddress = getGasTokenAddress(
|
|
218
|
+
this.paymasterConfig.gasToken,
|
|
219
|
+
chainId
|
|
220
|
+
);
|
|
221
|
+
let paymasterAddress = await this.getPaymasterAddress(paymasterProvider);
|
|
222
|
+
if (
|
|
223
|
+
gasTokenAddress !== undefined &&
|
|
224
|
+
paymasterAddress !== undefined &&
|
|
225
|
+
isAddress(paymasterAddress)
|
|
226
|
+
) {
|
|
227
|
+
const erc20UserOp = await this.getERC20UserOp(
|
|
228
|
+
struct,
|
|
229
|
+
mainCall,
|
|
230
|
+
gasTokenAddress,
|
|
231
|
+
paymasterAddress
|
|
194
232
|
);
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
gasTokenAddress !== undefined &&
|
|
198
|
-
paymasterAddress !== undefined &&
|
|
199
|
-
isAddress(paymasterAddress)
|
|
200
|
-
) {
|
|
201
|
-
const erc20UserOp = await this.getERC20UserOp(
|
|
202
|
-
struct,
|
|
203
|
-
mainCall,
|
|
204
|
-
gasTokenAddress,
|
|
205
|
-
paymasterAddress
|
|
206
|
-
);
|
|
207
|
-
if (!erc20UserOp) {
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
const paymasterResp = await this.signUserOp({
|
|
211
|
-
userOp: struct,
|
|
212
|
-
callData: struct.callData,
|
|
213
|
-
gasTokenAddress,
|
|
214
|
-
erc20UserOp,
|
|
215
|
-
erc20CallData: erc20UserOp.callData,
|
|
216
|
-
paymasterProvider,
|
|
217
|
-
shouldOverrideFee,
|
|
218
|
-
});
|
|
219
|
-
if (paymasterResp) {
|
|
220
|
-
return paymasterResp;
|
|
221
|
-
}
|
|
233
|
+
if (!erc20UserOp) {
|
|
234
|
+
return;
|
|
222
235
|
}
|
|
223
|
-
|
|
224
|
-
|
|
236
|
+
const paymasterResp = await this.signUserOp({
|
|
237
|
+
userOp: struct,
|
|
238
|
+
callData: struct.callData,
|
|
239
|
+
gasTokenAddress,
|
|
240
|
+
erc20UserOp,
|
|
241
|
+
erc20CallData: erc20UserOp.callData,
|
|
242
|
+
paymasterProvider,
|
|
243
|
+
shouldOverrideFee,
|
|
244
|
+
});
|
|
245
|
+
return paymasterResp;
|
|
225
246
|
}
|
|
226
247
|
return;
|
|
227
248
|
}
|
|
@@ -19,19 +19,12 @@ export class VerifyingPaymaster extends Paymaster {
|
|
|
19
19
|
paymasterProvider?: PaymasterAndBundlerProviders,
|
|
20
20
|
shouldOverrideFee?: boolean
|
|
21
21
|
): Promise<UserOperationStruct | undefined> {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if (paymasterResp) {
|
|
30
|
-
return paymasterResp;
|
|
31
|
-
}
|
|
32
|
-
} catch (error) {
|
|
33
|
-
console.log(error);
|
|
34
|
-
}
|
|
35
|
-
return;
|
|
22
|
+
const hexifiedUserOp = deepHexlify(await resolveProperties(struct));
|
|
23
|
+
const paymasterResp = await this.signUserOp({
|
|
24
|
+
userOp: hexifiedUserOp,
|
|
25
|
+
paymasterProvider,
|
|
26
|
+
shouldOverrideFee,
|
|
27
|
+
});
|
|
28
|
+
return paymasterResp;
|
|
36
29
|
}
|
|
37
30
|
}
|
|
@@ -298,8 +298,7 @@ export class ZeroDevProvider extends SmartAccountProvider<HttpTransport> {
|
|
|
298
298
|
dummyPaymasterDataMiddleware: AccountMiddlewareFn = async (
|
|
299
299
|
struct: UserOperationStruct
|
|
300
300
|
): Promise<UserOperationStruct> => {
|
|
301
|
-
struct.paymasterAndData =
|
|
302
|
-
"0xfe7dbcab8aaee4eb67943c1e6be95b1d065985c6000000000000000000000000000000000000000000000000000001869aa31cf400000000000000000000000000000000000000000000000000000000000000007dfe2190f34af27b265bae608717cdc9368b471fc0c097ab7b4088f255b4961e57b039e7e571b15221081c5dce7bcb93459b27a3ab65d2f8a889f4a40b4022801b";
|
|
301
|
+
struct.paymasterAndData = "0x";
|
|
303
302
|
return struct;
|
|
304
303
|
};
|
|
305
304
|
|