@account-kit/wallet-client 0.1.0-alpha.1 → 0.1.0-alpha.3
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/esm/capabilities/index.d.ts +5 -2
- package/dist/esm/capabilities/index.js +1 -1
- package/dist/esm/capabilities/index.js.map +1 -1
- package/dist/esm/capabilities/overrides.js +8 -8
- package/dist/esm/capabilities/overrides.js.map +1 -1
- package/dist/esm/capabilities/permissions/index.d.ts +10 -3
- package/dist/esm/capabilities/permissions/index.js +11 -2
- package/dist/esm/capabilities/permissions/index.js.map +1 -1
- package/dist/esm/capabilities/permissions/mav2.d.ts +3 -3
- package/dist/esm/capabilities/permissions/mav2.js +9 -1
- package/dist/esm/capabilities/permissions/mav2.js.map +1 -1
- package/dist/esm/client/actions/createAccount.d.ts +27 -2
- package/dist/esm/client/actions/createAccount.js +25 -0
- package/dist/esm/client/actions/createAccount.js.map +1 -1
- package/dist/esm/client/actions/getCallsStatus.d.ts +21 -2
- package/dist/esm/client/actions/getCallsStatus.js.map +1 -1
- package/dist/esm/client/actions/grantPermissions.d.ts +114 -2
- package/dist/esm/client/actions/grantPermissions.js +1 -0
- package/dist/esm/client/actions/grantPermissions.js.map +1 -1
- package/dist/esm/client/actions/listAccounts.d.ts +26 -2
- package/dist/esm/client/actions/listAccounts.js +24 -0
- package/dist/esm/client/actions/listAccounts.js.map +1 -1
- package/dist/esm/client/actions/prepareCalls.d.ts +28 -2
- package/dist/esm/client/actions/prepareCalls.js.map +1 -1
- package/dist/esm/client/actions/requestAccount.d.ts +21 -2
- package/dist/esm/client/actions/requestAccount.js +15 -4
- package/dist/esm/client/actions/requestAccount.js.map +1 -1
- package/dist/esm/client/actions/sendPreparedCalls.d.ts +39 -2
- package/dist/esm/client/actions/sendPreparedCalls.js +37 -0
- package/dist/esm/client/actions/sendPreparedCalls.js.map +1 -1
- package/dist/esm/client/actions/signMessage.d.ts +22 -2
- package/dist/esm/client/actions/signMessage.js +4 -2
- package/dist/esm/client/actions/signMessage.js.map +1 -1
- package/dist/esm/client/actions/signSignatureRequest.d.ts +34 -0
- package/dist/esm/client/actions/signSignatureRequest.js +22 -1
- package/dist/esm/client/actions/signSignatureRequest.js.map +1 -1
- package/dist/esm/client/actions/signTypedData.d.ts +35 -2
- package/dist/esm/client/actions/signTypedData.js +3 -1
- package/dist/esm/client/actions/signTypedData.js.map +1 -1
- package/dist/esm/client/client.e2e-test.js +112 -30
- package/dist/esm/client/client.e2e-test.js.map +1 -1
- package/dist/esm/client/decorator.d.ts +7 -5
- package/dist/esm/client/decorator.js +1 -1
- package/dist/esm/client/decorator.js.map +1 -1
- package/dist/esm/client/index.d.ts +4 -4
- package/dist/esm/client/index.js +29 -3
- package/dist/esm/client/index.js.map +1 -1
- package/dist/esm/exports/index.d.ts +1 -0
- package/dist/esm/exports/index.js +1 -0
- package/dist/esm/exports/index.js.map +1 -1
- package/dist/esm/exports/internal.d.ts +1 -1
- package/dist/esm/exports/internal.js.map +1 -1
- package/dist/esm/internal/decorator.d.ts +2 -0
- package/dist/esm/internal/decorator.js +10 -0
- package/dist/esm/internal/decorator.js.map +1 -0
- package/dist/esm/isomorphic/actions/createSession.js +25 -7
- package/dist/esm/isomorphic/actions/createSession.js.map +1 -1
- package/dist/esm/isomorphic/actions/prepareCalls.js +35 -12
- package/dist/esm/isomorphic/actions/prepareCalls.js.map +1 -1
- package/dist/esm/isomorphic/actions/sendPreparedCalls.js +26 -6
- package/dist/esm/isomorphic/actions/sendPreparedCalls.js.map +1 -1
- package/dist/esm/isomorphic/client.d.ts +11 -5
- package/dist/esm/isomorphic/utils/7702.d.ts +11 -0
- package/dist/esm/isomorphic/utils/7702.js +26 -0
- package/dist/esm/isomorphic/utils/7702.js.map +1 -0
- package/dist/esm/isomorphic/utils/createAccount.d.ts +2 -1
- package/dist/esm/isomorphic/utils/createAccount.js +30 -5
- package/dist/esm/isomorphic/utils/createAccount.js.map +1 -1
- package/dist/esm/isomorphic/utils/createDummySigner.js +3 -3
- package/dist/esm/isomorphic/utils/createDummySigner.js.map +1 -1
- package/dist/esm/isomorphic/utils/parsePermissionsContext.d.ts +2 -1
- package/dist/esm/isomorphic/utils/parsePermissionsContext.js +17 -5
- package/dist/esm/isomorphic/utils/parsePermissionsContext.js.map +1 -1
- package/dist/esm/local/client.d.ts +1 -1
- package/dist/esm/local/client.js +10 -2
- package/dist/esm/local/client.js.map +1 -1
- package/dist/esm/remote/client.d.ts +1 -1
- package/dist/esm/remote/client.js +12 -3
- package/dist/esm/remote/client.js.map +1 -1
- package/dist/esm/rpc/examples.d.ts +230 -0
- package/dist/esm/rpc/examples.js +314 -0
- package/dist/esm/rpc/examples.js.map +1 -0
- package/dist/esm/rpc/request.d.ts +48 -17
- package/dist/esm/rpc/request.js +53 -14
- package/dist/esm/rpc/request.js.map +1 -1
- package/dist/esm/rpc/schema.d.ts +43 -12
- package/dist/esm/schemas.d.ts +29 -7
- package/dist/esm/schemas.js +120 -38
- package/dist/esm/schemas.js.map +1 -1
- package/dist/esm/types.d.ts +15 -4
- package/dist/esm/types.js.map +1 -1
- package/dist/types/capabilities/index.d.ts +5 -2
- package/dist/types/capabilities/index.d.ts.map +1 -1
- package/dist/types/capabilities/overrides.d.ts.map +1 -1
- package/dist/types/capabilities/permissions/index.d.ts +10 -3
- package/dist/types/capabilities/permissions/index.d.ts.map +1 -1
- package/dist/types/capabilities/permissions/mav2.d.ts +3 -3
- package/dist/types/capabilities/permissions/mav2.d.ts.map +1 -1
- package/dist/types/client/actions/createAccount.d.ts +27 -2
- package/dist/types/client/actions/createAccount.d.ts.map +1 -1
- package/dist/types/client/actions/getCallsStatus.d.ts +21 -2
- package/dist/types/client/actions/getCallsStatus.d.ts.map +1 -1
- package/dist/types/client/actions/grantPermissions.d.ts +114 -2
- package/dist/types/client/actions/grantPermissions.d.ts.map +1 -1
- package/dist/types/client/actions/listAccounts.d.ts +26 -2
- package/dist/types/client/actions/listAccounts.d.ts.map +1 -1
- package/dist/types/client/actions/prepareCalls.d.ts +28 -2
- package/dist/types/client/actions/prepareCalls.d.ts.map +1 -1
- package/dist/types/client/actions/requestAccount.d.ts +21 -2
- package/dist/types/client/actions/requestAccount.d.ts.map +1 -1
- package/dist/types/client/actions/sendPreparedCalls.d.ts +39 -2
- package/dist/types/client/actions/sendPreparedCalls.d.ts.map +1 -1
- package/dist/types/client/actions/signMessage.d.ts +22 -2
- package/dist/types/client/actions/signMessage.d.ts.map +1 -1
- package/dist/types/client/actions/signSignatureRequest.d.ts +34 -0
- package/dist/types/client/actions/signSignatureRequest.d.ts.map +1 -1
- package/dist/types/client/actions/signTypedData.d.ts +35 -2
- package/dist/types/client/actions/signTypedData.d.ts.map +1 -1
- package/dist/types/client/decorator.d.ts +7 -5
- package/dist/types/client/decorator.d.ts.map +1 -1
- package/dist/types/client/index.d.ts +4 -4
- package/dist/types/client/index.d.ts.map +1 -1
- package/dist/types/exports/index.d.ts +1 -0
- package/dist/types/exports/index.d.ts.map +1 -1
- package/dist/types/exports/internal.d.ts +1 -1
- package/dist/types/exports/internal.d.ts.map +1 -1
- package/dist/types/internal/decorator.d.ts +3 -0
- package/dist/types/internal/decorator.d.ts.map +1 -0
- package/dist/types/isomorphic/actions/createSession.d.ts.map +1 -1
- package/dist/types/isomorphic/actions/prepareCalls.d.ts.map +1 -1
- package/dist/types/isomorphic/actions/sendPreparedCalls.d.ts.map +1 -1
- package/dist/types/isomorphic/client.d.ts +11 -5
- package/dist/types/isomorphic/client.d.ts.map +1 -1
- package/dist/types/isomorphic/utils/7702.d.ts +12 -0
- package/dist/types/isomorphic/utils/7702.d.ts.map +1 -0
- package/dist/types/isomorphic/utils/createAccount.d.ts +2 -1
- package/dist/types/isomorphic/utils/createAccount.d.ts.map +1 -1
- package/dist/types/isomorphic/utils/createDummySigner.d.ts.map +1 -1
- package/dist/types/isomorphic/utils/parsePermissionsContext.d.ts +2 -1
- package/dist/types/isomorphic/utils/parsePermissionsContext.d.ts.map +1 -1
- package/dist/types/local/client.d.ts +1 -1
- package/dist/types/local/client.d.ts.map +1 -1
- package/dist/types/remote/client.d.ts +1 -1
- package/dist/types/remote/client.d.ts.map +1 -1
- package/dist/types/rpc/examples.d.ts +231 -0
- package/dist/types/rpc/examples.d.ts.map +1 -0
- package/dist/types/rpc/request.d.ts +48 -17
- package/dist/types/rpc/request.d.ts.map +1 -1
- package/dist/types/rpc/schema.d.ts +43 -12
- package/dist/types/rpc/schema.d.ts.map +1 -1
- package/dist/types/schemas.d.ts +29 -7
- package/dist/types/schemas.d.ts.map +1 -1
- package/dist/types/types.d.ts +15 -4
- package/dist/types/types.d.ts.map +1 -1
- package/package.json +8 -6
- package/src/capabilities/index.ts +5 -8
- package/src/capabilities/overrides.ts +23 -8
- package/src/capabilities/permissions/index.ts +21 -5
- package/src/capabilities/permissions/mav2.ts +13 -3
- package/src/client/actions/createAccount.ts +27 -2
- package/src/client/actions/getCallsStatus.ts +21 -2
- package/src/client/actions/grantPermissions.ts +114 -2
- package/src/client/actions/listAccounts.ts +26 -2
- package/src/client/actions/prepareCalls.ts +28 -2
- package/src/client/actions/requestAccount.ts +41 -7
- package/src/client/actions/sendPreparedCalls.ts +39 -2
- package/src/client/actions/signMessage.ts +24 -4
- package/src/client/actions/signSignatureRequest.ts +61 -2
- package/src/client/actions/signTypedData.ts +39 -3
- package/src/client/client.e2e-test.ts +134 -32
- package/src/client/decorator.ts +10 -12
- package/src/client/index.ts +41 -10
- package/src/exports/index.ts +1 -0
- package/src/exports/internal.ts +1 -1
- package/src/internal/decorator.ts +12 -0
- package/src/isomorphic/actions/createSession.ts +28 -7
- package/src/isomorphic/actions/prepareCalls.ts +38 -11
- package/src/isomorphic/actions/sendPreparedCalls.ts +47 -20
- package/src/isomorphic/utils/7702.ts +58 -0
- package/src/isomorphic/utils/createAccount.ts +38 -6
- package/src/isomorphic/utils/createDummySigner.ts +3 -2
- package/src/isomorphic/utils/parsePermissionsContext.ts +23 -7
- package/src/local/client.ts +54 -45
- package/src/remote/client.ts +22 -7
- package/src/rpc/examples.ts +343 -0
- package/src/rpc/request.ts +75 -26
- package/src/schemas.ts +218 -87
- package/src/types.ts +18 -4
|
@@ -5,13 +5,46 @@ import {
|
|
|
5
5
|
type JsonRpcAccount,
|
|
6
6
|
type TypedDataDefinition,
|
|
7
7
|
} from "viem";
|
|
8
|
-
import type { InnerWalletApiClient } from "../../types";
|
|
8
|
+
import type { InnerWalletApiClient } from "../../types.ts";
|
|
9
9
|
import { requestAccount } from "./requestAccount.js";
|
|
10
10
|
|
|
11
|
-
export type SignTypedDataParams = TypedDataDefinition
|
|
11
|
+
export type SignTypedDataParams = TypedDataDefinition & {
|
|
12
|
+
account?: Address;
|
|
13
|
+
};
|
|
12
14
|
|
|
13
15
|
export type SignTypedDataResult = Hex;
|
|
14
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Signs typed data (EIP-712) using the smart account.
|
|
19
|
+
* This method requests the account associated with the signer and uses it to sign the typed data.
|
|
20
|
+
*
|
|
21
|
+
* @param {InnerWalletApiClient} client - The wallet API client to use for the request
|
|
22
|
+
* @param {SmartAccountSigner} signer - The signer of the smart account
|
|
23
|
+
* @param {TypedDataDefinition} params - The typed data to sign, following EIP-712 format
|
|
24
|
+
* @returns {Promise<SignTypedDataResult>} A Promise that resolves to the signature as a hex string
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* // Sign typed data
|
|
28
|
+
* const signature = await client.signTypedData({
|
|
29
|
+
* domain: {
|
|
30
|
+
* name: 'Example DApp',
|
|
31
|
+
* version: '1',
|
|
32
|
+
* chainId: 1,
|
|
33
|
+
* verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC'
|
|
34
|
+
* },
|
|
35
|
+
* types: {
|
|
36
|
+
* Person: [
|
|
37
|
+
* { name: 'name', type: 'string' },
|
|
38
|
+
* { name: 'wallet', type: 'address' }
|
|
39
|
+
* ]
|
|
40
|
+
* },
|
|
41
|
+
* primaryType: 'Person',
|
|
42
|
+
* message: {
|
|
43
|
+
* name: 'John Doe',
|
|
44
|
+
* wallet: '0xAaAaAaAaAaAaAaAaAaAAAAAAAAaaaAaAaAaaAaAa'
|
|
45
|
+
* }
|
|
46
|
+
* });
|
|
47
|
+
*/
|
|
15
48
|
export async function signTypedData<
|
|
16
49
|
TAccount extends JsonRpcAccount<Address> | undefined =
|
|
17
50
|
| JsonRpcAccount<Address>
|
|
@@ -27,6 +60,9 @@ export async function signTypedData(
|
|
|
27
60
|
signer: SmartAccountSigner,
|
|
28
61
|
params: SignTypedDataParams,
|
|
29
62
|
): Promise<SignTypedDataResult> {
|
|
30
|
-
const account = await requestAccount(client, signer
|
|
63
|
+
const account = await requestAccount(client, signer, {
|
|
64
|
+
accountAddress: params.account ?? client.account?.address,
|
|
65
|
+
});
|
|
66
|
+
|
|
31
67
|
return account.signTypedDataWith6492(params);
|
|
32
68
|
}
|
|
@@ -32,6 +32,27 @@ describe("Client E2E Tests", () => {
|
|
|
32
32
|
transport,
|
|
33
33
|
});
|
|
34
34
|
|
|
35
|
+
it("should successfully request account with different salt", async () => {
|
|
36
|
+
const account = await client.requestAccount({
|
|
37
|
+
id: "2d00c64e-2e55-4925-832e-e288dbf1139e",
|
|
38
|
+
creationHint: { salt: "0x1" },
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
expect(account.address).toMatchInlineSnapshot(
|
|
42
|
+
`"0x569bCECaC47Ef9706c4b2370f2891bccd4cdE30c"`,
|
|
43
|
+
);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("should not cache account if different inputs provided", async () => {
|
|
47
|
+
const account = await client.requestAccount();
|
|
48
|
+
const account2 = await client.requestAccount({
|
|
49
|
+
id: "2d00c64e-2e55-4925-832e-e288dbf1139e",
|
|
50
|
+
creationHint: { salt: "0x1" },
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
expect(account.address).not.toEqual(account2.address);
|
|
54
|
+
});
|
|
55
|
+
|
|
35
56
|
it("should successfully get a counterfactual address", async () => {
|
|
36
57
|
const account = await client.requestAccount();
|
|
37
58
|
expect(account.address).toMatchInlineSnapshot(
|
|
@@ -42,14 +63,10 @@ describe("Client E2E Tests", () => {
|
|
|
42
63
|
it("can correctly sign a message", async () => {
|
|
43
64
|
const account = await client.requestAccount();
|
|
44
65
|
const message = "hello world";
|
|
45
|
-
const signature = await client.signMessage(message);
|
|
46
|
-
const publicClient = createPublicClient({
|
|
47
|
-
chain: arbitrumSepolia,
|
|
48
|
-
transport,
|
|
49
|
-
});
|
|
66
|
+
const signature = await client.signMessage({ message });
|
|
50
67
|
const isValid = await publicClient.verifyMessage({
|
|
51
68
|
address: account.address,
|
|
52
|
-
message
|
|
69
|
+
message,
|
|
53
70
|
signature,
|
|
54
71
|
});
|
|
55
72
|
expect(isValid).toBeTrue();
|
|
@@ -66,9 +83,46 @@ describe("Client E2E Tests", () => {
|
|
|
66
83
|
expect(isValid).toBeTrue();
|
|
67
84
|
});
|
|
68
85
|
|
|
86
|
+
it("can correctly sign a message with a different account", async () => {
|
|
87
|
+
const account = await client.requestAccount({
|
|
88
|
+
id: "2d00c64e-2e55-4925-832e-e288dbf1139e",
|
|
89
|
+
creationHint: { salt: "0x1" },
|
|
90
|
+
});
|
|
91
|
+
const message = "hello world";
|
|
92
|
+
|
|
93
|
+
const signature = await client.signMessage({
|
|
94
|
+
message,
|
|
95
|
+
account: account.address,
|
|
96
|
+
});
|
|
97
|
+
const isValid = await publicClient.verifyMessage({
|
|
98
|
+
address: account.address,
|
|
99
|
+
message,
|
|
100
|
+
signature,
|
|
101
|
+
});
|
|
102
|
+
expect(isValid).toBeTrue();
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it("can correctly sign typed data with a different account", async () => {
|
|
106
|
+
const account = await client.requestAccount({
|
|
107
|
+
id: "2d00c64e-2e55-4925-832e-e288dbf1139e",
|
|
108
|
+
creationHint: { salt: "0x1" },
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
const signature = await client.signTypedData({
|
|
112
|
+
...givenTypedData,
|
|
113
|
+
account: account.address,
|
|
114
|
+
});
|
|
115
|
+
const isValid = await publicClient.verifyTypedData({
|
|
116
|
+
...givenTypedData,
|
|
117
|
+
signature,
|
|
118
|
+
address: account.address,
|
|
119
|
+
});
|
|
120
|
+
expect(isValid).toBeTrue();
|
|
121
|
+
});
|
|
122
|
+
|
|
69
123
|
it("should successfully send a UO with paymaster", async () => {
|
|
70
124
|
const account = await client.requestAccount();
|
|
71
|
-
const
|
|
125
|
+
const preparedCall = await client.prepareCalls({
|
|
72
126
|
calls: [{ to: zeroAddress, value: "0x0" }],
|
|
73
127
|
from: account.address,
|
|
74
128
|
capabilities: {
|
|
@@ -78,20 +132,13 @@ describe("Client E2E Tests", () => {
|
|
|
78
132
|
},
|
|
79
133
|
});
|
|
80
134
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const signature = await signer.signMessage(
|
|
86
|
-
preparedUO.signatureRequest.data,
|
|
135
|
+
const signature = await client.signSignatureRequest(
|
|
136
|
+
preparedCall.signatureRequest,
|
|
87
137
|
);
|
|
88
138
|
|
|
89
139
|
const result = await client.sendPreparedCalls({
|
|
90
|
-
...
|
|
91
|
-
signature
|
|
92
|
-
type: "ecdsa",
|
|
93
|
-
signature,
|
|
94
|
-
},
|
|
140
|
+
...preparedCall,
|
|
141
|
+
signature,
|
|
95
142
|
});
|
|
96
143
|
|
|
97
144
|
expect(result.preparedCallIds).toBeArrayOfSize(1);
|
|
@@ -112,7 +159,7 @@ describe("Client E2E Tests", () => {
|
|
|
112
159
|
permissions: [{ type: "root" }],
|
|
113
160
|
});
|
|
114
161
|
|
|
115
|
-
const
|
|
162
|
+
const preparedCall = await client.prepareCalls({
|
|
116
163
|
calls: [{ to: zeroAddress, value: "0x0" }],
|
|
117
164
|
from: account.address,
|
|
118
165
|
capabilities: {
|
|
@@ -125,11 +172,11 @@ describe("Client E2E Tests", () => {
|
|
|
125
172
|
|
|
126
173
|
const signature = await signSignatureRequest(
|
|
127
174
|
sessionKey,
|
|
128
|
-
|
|
175
|
+
preparedCall.signatureRequest,
|
|
129
176
|
);
|
|
130
177
|
|
|
131
178
|
const result = await client.sendPreparedCalls({
|
|
132
|
-
...
|
|
179
|
+
...preparedCall,
|
|
133
180
|
signature,
|
|
134
181
|
capabilities: {
|
|
135
182
|
permissions,
|
|
@@ -164,14 +211,31 @@ describe("Client E2E Tests", () => {
|
|
|
164
211
|
);
|
|
165
212
|
});
|
|
166
213
|
|
|
214
|
+
it("should successfully request account with different salt", async () => {
|
|
215
|
+
const account = await client.requestAccount({
|
|
216
|
+
id: "8670d2d8-2781-49e9-a75c-1eb980271ca9",
|
|
217
|
+
creationHint: { salt: "0x1" },
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
expect(account.address).toMatchInlineSnapshot(
|
|
221
|
+
`"0xC9B8271E44f14be83CecfDE1dDb325e9fa15e9Ff"`,
|
|
222
|
+
);
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it("should not cache account if different inputs provided", async () => {
|
|
226
|
+
const account = await client.requestAccount();
|
|
227
|
+
const account2 = await client.requestAccount({
|
|
228
|
+
id: "8670d2d8-2781-49e9-a75c-1eb980271ca9",
|
|
229
|
+
creationHint: { salt: "0x1" },
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
expect(account.address).not.toEqual(account2.address);
|
|
233
|
+
});
|
|
234
|
+
|
|
167
235
|
it("can correctly sign a message", async () => {
|
|
168
236
|
const account = await client.requestAccount();
|
|
169
237
|
const message = "hello world";
|
|
170
|
-
const signature = await client.signMessage(message);
|
|
171
|
-
const publicClient = createPublicClient({
|
|
172
|
-
chain: arbitrumSepolia,
|
|
173
|
-
transport,
|
|
174
|
-
});
|
|
238
|
+
const signature = await client.signMessage({ message });
|
|
175
239
|
const isValid = await publicClient.verifyMessage({
|
|
176
240
|
address: account.address,
|
|
177
241
|
message: "hello world",
|
|
@@ -191,9 +255,47 @@ describe("Client E2E Tests", () => {
|
|
|
191
255
|
expect(isValid).toBeTrue();
|
|
192
256
|
});
|
|
193
257
|
|
|
258
|
+
it("can correctly sign a message with a different account", async () => {
|
|
259
|
+
const account = await client.requestAccount({
|
|
260
|
+
id: "8670d2d8-2781-49e9-a75c-1eb980271ca9",
|
|
261
|
+
creationHint: { salt: "0x1" },
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
const message = "hello world";
|
|
265
|
+
const signature = await client.signMessage({
|
|
266
|
+
message,
|
|
267
|
+
account: account.address,
|
|
268
|
+
});
|
|
269
|
+
const isValid = await publicClient.verifyMessage({
|
|
270
|
+
address: account.address,
|
|
271
|
+
message: "hello world",
|
|
272
|
+
signature,
|
|
273
|
+
});
|
|
274
|
+
expect(isValid).toBeTrue();
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
it("can correctly sign typed data with a different account", async () => {
|
|
278
|
+
const account = await client.requestAccount({
|
|
279
|
+
id: "8670d2d8-2781-49e9-a75c-1eb980271ca9",
|
|
280
|
+
creationHint: { salt: "0x1" },
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
const signature = await client.signTypedData({
|
|
284
|
+
...givenTypedData,
|
|
285
|
+
account: account.address,
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
const isValid = await publicClient.verifyTypedData({
|
|
289
|
+
...givenTypedData,
|
|
290
|
+
signature,
|
|
291
|
+
address: account.address,
|
|
292
|
+
});
|
|
293
|
+
expect(isValid).toBeTrue();
|
|
294
|
+
});
|
|
295
|
+
|
|
194
296
|
it("should successfully send a UO with paymaster", async () => {
|
|
195
297
|
const account = await client.requestAccount();
|
|
196
|
-
const
|
|
298
|
+
const preparedCall = await client.prepareCalls({
|
|
197
299
|
calls: [{ to: zeroAddress, value: "0x0" }],
|
|
198
300
|
from: account.address,
|
|
199
301
|
capabilities: {
|
|
@@ -204,11 +306,11 @@ describe("Client E2E Tests", () => {
|
|
|
204
306
|
});
|
|
205
307
|
|
|
206
308
|
const signature = await client.signSignatureRequest(
|
|
207
|
-
|
|
309
|
+
preparedCall.signatureRequest,
|
|
208
310
|
);
|
|
209
311
|
|
|
210
312
|
const result = await client.sendPreparedCalls({
|
|
211
|
-
...
|
|
313
|
+
...preparedCall,
|
|
212
314
|
signature,
|
|
213
315
|
});
|
|
214
316
|
|
|
@@ -230,7 +332,7 @@ describe("Client E2E Tests", () => {
|
|
|
230
332
|
permissions: [{ type: "root" }],
|
|
231
333
|
});
|
|
232
334
|
|
|
233
|
-
const
|
|
335
|
+
const preparedCall = await client.prepareCalls({
|
|
234
336
|
calls: [{ to: zeroAddress, value: "0x0" }],
|
|
235
337
|
from: account.address,
|
|
236
338
|
capabilities: {
|
|
@@ -243,11 +345,11 @@ describe("Client E2E Tests", () => {
|
|
|
243
345
|
|
|
244
346
|
const signature = await signSignatureRequest(
|
|
245
347
|
sessionKey,
|
|
246
|
-
|
|
348
|
+
preparedCall.signatureRequest,
|
|
247
349
|
);
|
|
248
350
|
|
|
249
351
|
const result = await client.sendPreparedCalls({
|
|
250
|
-
...
|
|
352
|
+
...preparedCall,
|
|
251
353
|
signature,
|
|
252
354
|
capabilities: {
|
|
253
355
|
permissions,
|
package/src/client/decorator.ts
CHANGED
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
import type { SmartAccountSigner } from "@aa-sdk/core";
|
|
2
|
-
import type {
|
|
3
|
-
Hex,
|
|
4
|
-
JsonRpcAccount,
|
|
5
|
-
SignableMessage,
|
|
6
|
-
TypedDataDefinition,
|
|
7
|
-
} from "viem";
|
|
2
|
+
import type { Hex, JsonRpcAccount } from "viem";
|
|
8
3
|
import type {
|
|
9
4
|
SendPreparedCallsParams,
|
|
10
5
|
SendPreparedCallsResult,
|
|
11
|
-
} from "../isomorphic/actions/sendPreparedCalls";
|
|
12
|
-
import type { InnerWalletApiClient } from "../types";
|
|
6
|
+
} from "../isomorphic/actions/sendPreparedCalls.ts";
|
|
7
|
+
import type { InnerWalletApiClient } from "../types.ts";
|
|
13
8
|
import {
|
|
14
9
|
createAccount,
|
|
15
10
|
type CreateAccountParams,
|
|
@@ -41,13 +36,16 @@ import {
|
|
|
41
36
|
type RequestAccountResult,
|
|
42
37
|
} from "./actions/requestAccount.js";
|
|
43
38
|
import { sendPreparedCalls } from "./actions/sendPreparedCalls.js";
|
|
44
|
-
import { signMessage } from "./actions/signMessage.js";
|
|
39
|
+
import { signMessage, type SignMessageParams } from "./actions/signMessage.js";
|
|
45
40
|
import {
|
|
46
41
|
signSignatureRequest,
|
|
47
42
|
type SignSignatureRequestParams,
|
|
48
43
|
type SignSignatureRequestResult,
|
|
49
44
|
} from "./actions/signSignatureRequest.js";
|
|
50
|
-
import {
|
|
45
|
+
import {
|
|
46
|
+
signTypedData,
|
|
47
|
+
type SignTypedDataParams,
|
|
48
|
+
} from "./actions/signTypedData.js";
|
|
51
49
|
|
|
52
50
|
export type SmartWalletActions<
|
|
53
51
|
TAccount extends JsonRpcAccount | undefined = JsonRpcAccount | undefined,
|
|
@@ -69,8 +67,8 @@ export type SmartWalletActions<
|
|
|
69
67
|
signSignatureRequest: (
|
|
70
68
|
params: SignSignatureRequestParams,
|
|
71
69
|
) => Promise<SignSignatureRequestResult>;
|
|
72
|
-
signMessage: (params:
|
|
73
|
-
signTypedData: (params:
|
|
70
|
+
signMessage: (params: SignMessageParams) => Promise<Hex>;
|
|
71
|
+
signTypedData: (params: SignTypedDataParams) => Promise<Hex>;
|
|
74
72
|
grantPermissions: (
|
|
75
73
|
params: GrantPermissionsParams<TAccount>,
|
|
76
74
|
) => Promise<GrantPermissionsResult>;
|
package/src/client/index.ts
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
type Prettify,
|
|
1
|
+
import type { SmartAccountSigner } from "@aa-sdk/core";
|
|
2
|
+
import type {
|
|
3
|
+
Address,
|
|
4
|
+
Chain,
|
|
5
|
+
IsUndefined,
|
|
6
|
+
JsonRpcAccount,
|
|
7
|
+
Prettify,
|
|
9
8
|
} from "viem";
|
|
10
9
|
import { createLocalClient } from "../local/client.js";
|
|
11
10
|
import { createRemoteClient } from "../remote/client.js";
|
|
12
|
-
import type { InnerWalletApiClient } from "../types";
|
|
11
|
+
import type { InnerWalletApiClient } from "../types.ts";
|
|
13
12
|
import {
|
|
14
13
|
smartWalletClientActions,
|
|
15
14
|
type SmartWalletActions,
|
|
16
15
|
} from "./decorator.js";
|
|
16
|
+
import type { AlchemyTransport } from "@account-kit/infra";
|
|
17
17
|
|
|
18
18
|
export type SmartWalletClientParams<
|
|
19
19
|
TAccount extends JsonRpcAccount<Address> | undefined =
|
|
@@ -49,7 +49,38 @@ export function createSmartWalletClient<
|
|
|
49
49
|
params: SmartWalletClientParams<TAccount>,
|
|
50
50
|
): InnerWalletApiClient<TAccount> & SmartWalletActions<TAccount>;
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
/**
|
|
53
|
+
* Creates a smart wallet client that can be used to interact with a smart account.
|
|
54
|
+
*
|
|
55
|
+
* @param {SmartWalletClientParams} params - The parameters for creating the smart wallet client
|
|
56
|
+
* @param {AlchemyTransport} params.transport - The Alchemy transport to use
|
|
57
|
+
* @param {Chain} params.chain - The chain to use
|
|
58
|
+
* @param {SmartAccountSigner} params.signer - The signer to use for the smart account
|
|
59
|
+
* @param {"local" | "remote"} params.mode - The client's mode (local or remote).
|
|
60
|
+
* @param {string} [params.policyId] - The policy ID for gas sponsorship (optional)
|
|
61
|
+
* @param {Address} [params.account] - The smart account address to use (optional)
|
|
62
|
+
* @returns {InnerWalletApiClient & SmartWalletActions} - A viem-compatible client
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* import { LocalAccountSigner } from "@aa-sdk/core";
|
|
66
|
+
* import { alchemy, arbitrumSepolia } from "@account-kit/infra";
|
|
67
|
+
* import { generatePrivateKey } from "viem/accounts";
|
|
68
|
+
* import { createSmartWalletClient } from "@account-kit/wallet-client";
|
|
69
|
+
*
|
|
70
|
+
* const signer = LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey());
|
|
71
|
+
* const transport = alchemy({
|
|
72
|
+
* apiKey: "your-alchemy-api-key",
|
|
73
|
+
* });
|
|
74
|
+
* const client = createSmartWalletClient({
|
|
75
|
+
* transport,
|
|
76
|
+
* chain: arbitrumSepolia,
|
|
77
|
+
* mode: "remote",
|
|
78
|
+
* signer,
|
|
79
|
+
* });
|
|
80
|
+
*/
|
|
81
|
+
export function createSmartWalletClient(
|
|
82
|
+
params: SmartWalletClientParams,
|
|
83
|
+
): InnerWalletApiClient & SmartWalletActions {
|
|
53
84
|
const { transport, chain, policyId, mode, account, signer } = params;
|
|
54
85
|
|
|
55
86
|
const innerClient =
|
package/src/exports/index.ts
CHANGED
|
@@ -30,3 +30,4 @@ export { requestAccount } from "../client/actions/requestAccount.js";
|
|
|
30
30
|
export { signMessage } from "../client/actions/signMessage.js";
|
|
31
31
|
export { signSignatureRequest } from "../client/actions/signSignatureRequest.js";
|
|
32
32
|
export { signTypedData } from "../client/actions/signTypedData.js";
|
|
33
|
+
export { grantPermissions } from "../client/actions/grantPermissions.js";
|
package/src/exports/internal.ts
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CachedAccount, InternalState } from "../types.ts";
|
|
2
|
+
|
|
3
|
+
export function internalStateDecorator(): InternalState {
|
|
4
|
+
let account: CachedAccount | undefined = undefined;
|
|
5
|
+
|
|
6
|
+
return {
|
|
7
|
+
setAccount: (newAccount: CachedAccount) => {
|
|
8
|
+
account = newAccount;
|
|
9
|
+
},
|
|
10
|
+
getAccount: () => account,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
@@ -24,6 +24,8 @@ import type { wallet_createSession } from "../../rpc/request.js";
|
|
|
24
24
|
import type { WalletServerViemRpcSchema } from "../../rpc/schema.js";
|
|
25
25
|
import { createAccount, isModularAccountV2 } from "../utils/createAccount.js";
|
|
26
26
|
import { createDummySigner } from "../utils/createDummySigner.js";
|
|
27
|
+
import { createAuthorization } from "../utils/7702.js";
|
|
28
|
+
import { InvalidRequestError } from "ox/RpcResponse";
|
|
27
29
|
|
|
28
30
|
export type CreateSessionParams = Omit<
|
|
29
31
|
Static<
|
|
@@ -57,17 +59,20 @@ export async function createSession(
|
|
|
57
59
|
throw new ChainNotFoundError();
|
|
58
60
|
}
|
|
59
61
|
|
|
60
|
-
const { counterfactualInfo } = await client.request({
|
|
62
|
+
const { counterfactualInfo, delegation } = await client.request({
|
|
61
63
|
method: "wallet_requestAccount",
|
|
62
64
|
params: [
|
|
63
65
|
{
|
|
64
|
-
includeCounterfactualInfo: true,
|
|
65
66
|
accountAddress: params.account,
|
|
67
|
+
includeCounterfactualInfo: true,
|
|
66
68
|
},
|
|
67
69
|
],
|
|
68
70
|
});
|
|
69
|
-
if (!counterfactualInfo) {
|
|
70
|
-
throw new
|
|
71
|
+
if (!counterfactualInfo && !delegation) {
|
|
72
|
+
throw new InvalidRequestError({
|
|
73
|
+
message:
|
|
74
|
+
"No counterfactual info or delegated implementation address found.",
|
|
75
|
+
});
|
|
71
76
|
}
|
|
72
77
|
|
|
73
78
|
const account = await createAccount({
|
|
@@ -76,10 +81,13 @@ export async function createSession(
|
|
|
76
81
|
signer: createDummySigner(params.account),
|
|
77
82
|
accountAddress: params.account,
|
|
78
83
|
counterfactualInfo,
|
|
84
|
+
delegation,
|
|
79
85
|
});
|
|
80
86
|
|
|
81
87
|
if (!isModularAccountV2(account)) {
|
|
82
|
-
throw new
|
|
88
|
+
throw new InvalidRequestError({
|
|
89
|
+
message: "Sessions are currently only supported by MAv2 accounts.",
|
|
90
|
+
});
|
|
83
91
|
}
|
|
84
92
|
|
|
85
93
|
const _client = createSmartAccountClient({
|
|
@@ -108,12 +116,25 @@ export async function createSession(
|
|
|
108
116
|
})
|
|
109
117
|
.compileDeferred();
|
|
110
118
|
|
|
119
|
+
// If using 7702, we need an Authorization (unless it's already authorized).
|
|
120
|
+
const authorizationRequest = delegation
|
|
121
|
+
? await createAuthorization(client, {
|
|
122
|
+
address: account.address,
|
|
123
|
+
delegation,
|
|
124
|
+
})
|
|
125
|
+
: undefined;
|
|
126
|
+
|
|
127
|
+
const signatureRequest = {
|
|
128
|
+
type: "eth_signTypedData_v4" as const,
|
|
129
|
+
data: typedData,
|
|
130
|
+
};
|
|
131
|
+
|
|
111
132
|
return {
|
|
112
133
|
sessionId: null, // In remote mode, the server will set this later.
|
|
113
134
|
entityId: toHex(entityId),
|
|
114
135
|
signatureRequest: {
|
|
115
|
-
|
|
116
|
-
|
|
136
|
+
...signatureRequest,
|
|
137
|
+
...(authorizationRequest ? { authorizationRequest } : {}),
|
|
117
138
|
},
|
|
118
139
|
fullPreSignatureDeferredActionDigest,
|
|
119
140
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
deepHexlify,
|
|
3
|
+
default7702GasEstimator,
|
|
3
4
|
type SmartAccountClient,
|
|
4
5
|
type SmartContractAccount,
|
|
5
6
|
} from "@aa-sdk/core";
|
|
@@ -9,7 +10,6 @@ import {
|
|
|
9
10
|
custom,
|
|
10
11
|
fromHex,
|
|
11
12
|
toHex,
|
|
12
|
-
zeroAddress,
|
|
13
13
|
type Chain,
|
|
14
14
|
type Transport,
|
|
15
15
|
} from "viem";
|
|
@@ -17,6 +17,8 @@ import type { wallet_prepareCalls } from "../../rpc/request.js";
|
|
|
17
17
|
import type { WalletServerViemRpcSchema } from "../../rpc/schema.js";
|
|
18
18
|
import { createAccount } from "../utils/createAccount.js";
|
|
19
19
|
import { createDummySigner } from "../utils/createDummySigner.js";
|
|
20
|
+
import { createAuthorization } from "../utils/7702.js";
|
|
21
|
+
import { InvalidRequestError } from "ox/RpcResponse";
|
|
20
22
|
|
|
21
23
|
export type PrepareCallsParams = Omit<
|
|
22
24
|
Static<
|
|
@@ -29,7 +31,6 @@ export type PrepareCallsResult = Static<
|
|
|
29
31
|
(typeof wallet_prepareCalls)["properties"]["ReturnType"]
|
|
30
32
|
>;
|
|
31
33
|
|
|
32
|
-
// TODO: handle capabilities like permissions and paymaster here
|
|
33
34
|
export async function prepareCalls(
|
|
34
35
|
client: SmartAccountClient<
|
|
35
36
|
Transport,
|
|
@@ -45,7 +46,7 @@ export async function prepareCalls(
|
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
// in local mode, we probably want some kind of caching for this
|
|
48
|
-
const { counterfactualInfo } = await client.request({
|
|
49
|
+
const { counterfactualInfo, delegation } = await client.request({
|
|
49
50
|
method: "wallet_requestAccount",
|
|
50
51
|
params: [
|
|
51
52
|
{
|
|
@@ -54,19 +55,37 @@ export async function prepareCalls(
|
|
|
54
55
|
},
|
|
55
56
|
],
|
|
56
57
|
});
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
|
|
59
|
+
if (!counterfactualInfo && !delegation) {
|
|
60
|
+
throw new InvalidRequestError({
|
|
61
|
+
message:
|
|
62
|
+
"No counterfactual info or delegated implementation address found.",
|
|
63
|
+
});
|
|
59
64
|
}
|
|
60
65
|
|
|
61
66
|
const account = await createAccount({
|
|
62
67
|
chain: client.chain,
|
|
63
68
|
transport: custom(client.transport),
|
|
64
|
-
signer: createDummySigner(
|
|
69
|
+
signer: createDummySigner(params.from),
|
|
65
70
|
accountAddress: params.from,
|
|
66
71
|
counterfactualInfo,
|
|
67
72
|
capabilities: params.capabilities,
|
|
73
|
+
delegation,
|
|
68
74
|
});
|
|
69
75
|
|
|
76
|
+
// If using 7702, we need an Authorization (unless it's already authorized).
|
|
77
|
+
const authorizationRequest = delegation
|
|
78
|
+
? await createAuthorization(client, {
|
|
79
|
+
address: account.address,
|
|
80
|
+
delegation,
|
|
81
|
+
})
|
|
82
|
+
: undefined;
|
|
83
|
+
|
|
84
|
+
if (authorizationRequest) {
|
|
85
|
+
// @ts-expect-error - this is available but not typed as public
|
|
86
|
+
client.middleware.gasEstimator = default7702GasEstimator();
|
|
87
|
+
}
|
|
88
|
+
|
|
70
89
|
// TODO: oops we don't actually support setting the policyId as an override here
|
|
71
90
|
// if we assume that the the isomorphic client is never used directly, then we can assume that this is handled upstream correctly
|
|
72
91
|
const builtUo = await client.buildUserOperation({
|
|
@@ -79,9 +98,19 @@ export async function prepareCalls(
|
|
|
79
98
|
overrides: params.capabilities?.gasParamsOverride,
|
|
80
99
|
});
|
|
81
100
|
|
|
101
|
+
// The eip7702Auth field should never be included in the UO sig
|
|
102
|
+
// request. It's handled by the separate authorization request.
|
|
103
|
+
if ("eip7702Auth" in builtUo) {
|
|
104
|
+
builtUo.eip7702Auth = undefined;
|
|
105
|
+
}
|
|
82
106
|
const uoRequest = deepHexlify(builtUo);
|
|
83
107
|
|
|
84
|
-
const
|
|
108
|
+
const signatureRequest = {
|
|
109
|
+
type: "personal_sign" as const,
|
|
110
|
+
data: {
|
|
111
|
+
raw: account.getEntryPoint().getUserOperationHash(uoRequest),
|
|
112
|
+
},
|
|
113
|
+
};
|
|
85
114
|
|
|
86
115
|
return {
|
|
87
116
|
type:
|
|
@@ -91,10 +120,8 @@ export async function prepareCalls(
|
|
|
91
120
|
data: uoRequest,
|
|
92
121
|
chainId: toHex(client.chain.id),
|
|
93
122
|
signatureRequest: {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
raw: hash,
|
|
97
|
-
},
|
|
123
|
+
...signatureRequest,
|
|
124
|
+
...(authorizationRequest ? { authorizationRequest } : {}),
|
|
98
125
|
},
|
|
99
126
|
};
|
|
100
127
|
}
|