@account-kit/wallet-client 0.0.1-alpha.1 → 0.1.0-alpha.0

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.
Files changed (72) hide show
  1. package/dist/esm/capabilities/index.d.ts +23 -0
  2. package/dist/esm/capabilities/index.js +2 -0
  3. package/dist/esm/capabilities/index.js.map +1 -1
  4. package/dist/esm/capabilities/overrides.d.ts +26 -0
  5. package/dist/esm/capabilities/overrides.js +14 -0
  6. package/dist/esm/capabilities/overrides.js.map +1 -0
  7. package/dist/esm/capabilities/permissions/index.d.ts +57 -17
  8. package/dist/esm/capabilities/permissions/index.js +25 -14
  9. package/dist/esm/capabilities/permissions/index.js.map +1 -1
  10. package/dist/esm/client/actions/grantPermissions.d.ts +1 -1
  11. package/dist/esm/client/actions/grantPermissions.js.map +1 -1
  12. package/dist/esm/client/actions/sendPreparedCalls.d.ts +2 -2
  13. package/dist/esm/client/actions/sendPreparedCalls.js.map +1 -1
  14. package/dist/esm/client/client.e2e-test.js +3 -4
  15. package/dist/esm/client/client.e2e-test.js.map +1 -1
  16. package/dist/esm/client/decorator.d.ts +1 -1
  17. package/dist/esm/client/decorator.js.map +1 -1
  18. package/dist/esm/isomorphic/actions/createSession.js +3 -1
  19. package/dist/esm/isomorphic/actions/createSession.js.map +1 -1
  20. package/dist/esm/isomorphic/actions/prepareCalls.js +2 -1
  21. package/dist/esm/isomorphic/actions/prepareCalls.js.map +1 -1
  22. package/dist/esm/isomorphic/actions/sendPreparedCalls.d.ts +2 -2
  23. package/dist/esm/isomorphic/actions/sendPreparedCalls.js +1 -1
  24. package/dist/esm/isomorphic/actions/sendPreparedCalls.js.map +1 -1
  25. package/dist/esm/isomorphic/client.d.ts +4 -3
  26. package/dist/esm/isomorphic/client.js +13 -6
  27. package/dist/esm/isomorphic/client.js.map +1 -1
  28. package/dist/esm/local/client.js +4 -3
  29. package/dist/esm/local/client.js.map +1 -1
  30. package/dist/esm/rpc/request.d.ts +32 -9
  31. package/dist/esm/rpc/request.js +14 -4
  32. package/dist/esm/rpc/request.js.map +1 -1
  33. package/dist/esm/rpc/schema.d.ts +32 -9
  34. package/dist/esm/rpc/schema.js.map +1 -1
  35. package/dist/types/capabilities/index.d.ts +23 -0
  36. package/dist/types/capabilities/index.d.ts.map +1 -1
  37. package/dist/types/capabilities/overrides.d.ts +27 -0
  38. package/dist/types/capabilities/overrides.d.ts.map +1 -0
  39. package/dist/types/capabilities/permissions/index.d.ts +57 -17
  40. package/dist/types/capabilities/permissions/index.d.ts.map +1 -1
  41. package/dist/types/client/actions/grantPermissions.d.ts +1 -1
  42. package/dist/types/client/actions/grantPermissions.d.ts.map +1 -1
  43. package/dist/types/client/actions/sendPreparedCalls.d.ts +2 -2
  44. package/dist/types/client/actions/sendPreparedCalls.d.ts.map +1 -1
  45. package/dist/types/client/decorator.d.ts +1 -1
  46. package/dist/types/client/decorator.d.ts.map +1 -1
  47. package/dist/types/isomorphic/actions/createSession.d.ts.map +1 -1
  48. package/dist/types/isomorphic/actions/prepareCalls.d.ts.map +1 -1
  49. package/dist/types/isomorphic/actions/sendPreparedCalls.d.ts +2 -2
  50. package/dist/types/isomorphic/actions/sendPreparedCalls.d.ts.map +1 -1
  51. package/dist/types/isomorphic/client.d.ts +4 -3
  52. package/dist/types/isomorphic/client.d.ts.map +1 -1
  53. package/dist/types/local/client.d.ts.map +1 -1
  54. package/dist/types/rpc/request.d.ts +32 -9
  55. package/dist/types/rpc/request.d.ts.map +1 -1
  56. package/dist/types/rpc/schema.d.ts +32 -9
  57. package/dist/types/rpc/schema.d.ts.map +1 -1
  58. package/package.json +2 -2
  59. package/src/capabilities/index.ts +2 -0
  60. package/src/capabilities/overrides.ts +20 -0
  61. package/src/capabilities/permissions/index.ts +41 -23
  62. package/src/client/actions/grantPermissions.ts +1 -1
  63. package/src/client/actions/sendPreparedCalls.ts +3 -3
  64. package/src/client/client.e2e-test.ts +3 -4
  65. package/src/client/decorator.ts +1 -1
  66. package/src/isomorphic/actions/createSession.ts +5 -1
  67. package/src/isomorphic/actions/prepareCalls.ts +3 -2
  68. package/src/isomorphic/actions/sendPreparedCalls.ts +3 -3
  69. package/src/isomorphic/client.ts +19 -9
  70. package/src/local/client.ts +7 -6
  71. package/src/rpc/request.ts +30 -15
  72. package/src/rpc/schema.ts +2 -2
@@ -13,20 +13,32 @@ const Permission = <
13
13
  TLiteralVal extends TLiteralValue,
14
14
  TType extends TLiteral<TLiteralVal>,
15
15
  >(
16
- type: TLiteralVal,
16
+ typeString: TLiteralVal, // e.g., "root"
17
+ typeEnum: TLiteralVal, // e.g., PermissionType.ROOT
17
18
  data: TData,
18
19
  description: string,
19
20
  ): TObject<{ type: TType; data: TData }> => {
20
- return Type.Object(
21
- {
22
- type: Type.Literal(type),
23
- data,
24
- },
25
- { description: description },
26
- ) as never;
21
+ return Type.Transform(
22
+ Type.Object(
23
+ {
24
+ type: Type.Literal(typeEnum),
25
+ data,
26
+ },
27
+ { description },
28
+ ),
29
+ )
30
+ .Decode((value) => ({
31
+ ...value,
32
+ type: typeString, // enum → string
33
+ }))
34
+ .Encode((value) => ({
35
+ ...value,
36
+ type: typeEnum, // string → enum
37
+ })) as never;
27
38
  };
28
39
 
29
40
  const NativeTokenTransfer = Permission(
41
+ "native-token-transfer",
30
42
  PermissionType.NATIVE_TOKEN_TRANSFER,
31
43
  Type.Object({
32
44
  allowance: TypeHex(),
@@ -35,6 +47,7 @@ const NativeTokenTransfer = Permission(
35
47
  );
36
48
 
37
49
  const Erc20TokenTransfer = Permission(
50
+ "erc20-token-transfer",
38
51
  PermissionType.ERC20_TOKEN_TRANSFER,
39
52
  Type.Object({
40
53
  allowance: TypeHex(),
@@ -44,6 +57,7 @@ const Erc20TokenTransfer = Permission(
44
57
  );
45
58
 
46
59
  const GasLimit = Permission(
60
+ "gas-limit",
47
61
  PermissionType.GAS_LIMIT,
48
62
  Type.Object({
49
63
  limit: TypeHex(),
@@ -52,6 +66,7 @@ const GasLimit = Permission(
52
66
  );
53
67
 
54
68
  const ContractAccess = Permission(
69
+ "contract-access",
55
70
  PermissionType.CONTRACT_ACCESS,
56
71
  Type.Object({
57
72
  address: TypeAddress,
@@ -60,6 +75,7 @@ const ContractAccess = Permission(
60
75
  );
61
76
 
62
77
  const AccountFunction = Permission(
78
+ "account-functions",
63
79
  PermissionType.ACCOUNT_FUNCTIONS,
64
80
  Type.Object({
65
81
  functions: Type.Array(TypeHex(), { minItems: 1 }),
@@ -68,6 +84,7 @@ const AccountFunction = Permission(
68
84
  );
69
85
 
70
86
  const AllExternalFunctionAccess = Permission(
87
+ "functions-on-all-contracts",
71
88
  PermissionType.FUNCTIONS_ON_ALL_CONTRACTS,
72
89
  Type.Object({
73
90
  functions: Type.Array(TypeHex(), { minItems: 1 }),
@@ -76,6 +93,7 @@ const AllExternalFunctionAccess = Permission(
76
93
  );
77
94
 
78
95
  const ContractFunctionAccess = Permission(
96
+ "functions-on-contract",
79
97
  PermissionType.FUNCTIONS_ON_CONTRACT,
80
98
  Type.Object({
81
99
  address: TypeAddress,
@@ -85,26 +103,26 @@ const ContractFunctionAccess = Permission(
85
103
  );
86
104
 
87
105
  const Root = Permission(
106
+ "root",
88
107
  PermissionType.ROOT,
89
108
  Type.Optional(Type.Never()),
90
109
  "grants full access to everything",
91
110
  );
92
111
 
93
- export const PermissionsArray = Type.Array(
94
- Type.Union([
95
- // 7715 permissions
96
- NativeTokenTransfer,
97
- Erc20TokenTransfer,
98
- GasLimit,
99
- // additional permissions
100
- ContractAccess,
101
- AccountFunction,
102
- AllExternalFunctionAccess,
103
- ContractFunctionAccess,
104
- Root,
105
- ]),
106
- { minItems: 1 },
107
- );
112
+ export const TypePermission = Type.Union([
113
+ // 7715 permissions
114
+ NativeTokenTransfer,
115
+ Erc20TokenTransfer,
116
+ GasLimit,
117
+ // additional permissions
118
+ ContractAccess,
119
+ AccountFunction,
120
+ AllExternalFunctionAccess,
121
+ ContractFunctionAccess,
122
+ Root,
123
+ ]);
124
+
125
+ export const PermissionsArray = Type.Array(TypePermission, { minItems: 1 });
108
126
 
109
127
  export const PermissionsContext = Type.Object({
110
128
  context: TypeHex(),
@@ -27,7 +27,7 @@ export async function grantPermissions<
27
27
  | JsonRpcAccount<Address>
28
28
  | undefined,
29
29
  >(
30
- client: InnerWalletApiClient,
30
+ client: InnerWalletApiClient<TAccount>,
31
31
  signer: SmartAccountSigner,
32
32
  params: GrantPermissionsParams<TAccount>,
33
33
  ): Promise<GrantPermissionsResult>;
@@ -1,10 +1,10 @@
1
- import type { Static } from "@sinclair/typebox";
1
+ import type { Static, StaticDecode } from "@sinclair/typebox";
2
+ import { toHex } from "viem";
2
3
  import type { wallet_sendPreparedCalls } from "../../rpc/request";
3
4
  import type { InnerWalletApiClient } from "../../types";
4
- import { toHex } from "viem";
5
5
 
6
6
  export type SendPreparedCallsParams = Omit<
7
- Static<typeof wallet_sendPreparedCalls>["Request"]["params"][0],
7
+ StaticDecode<typeof wallet_sendPreparedCalls>["Request"]["params"][0],
8
8
  "chainId"
9
9
  >;
10
10
 
@@ -3,7 +3,6 @@ import { alchemy, arbitrumSepolia } from "@account-kit/infra";
3
3
  import { describe, expect, it } from "bun:test";
4
4
  import { createPublicClient, zeroAddress, type Address } from "viem";
5
5
  import { createSmartWalletClient } from ".";
6
- import { PermissionType } from "@account-kit/smart-contracts/experimental";
7
6
  import { signSignatureRequest } from "./actions/signSignatureRequest";
8
7
 
9
8
  describe("Client E2E Tests", () => {
@@ -90,7 +89,7 @@ describe("Client E2E Tests", () => {
90
89
  const result = await client.sendPreparedCalls({
91
90
  ...preparedUO,
92
91
  signature: {
93
- type: "ECDSA",
92
+ type: "ecdsa",
94
93
  signature,
95
94
  },
96
95
  });
@@ -110,7 +109,7 @@ describe("Client E2E Tests", () => {
110
109
  publicKey: await sessionKey.getAddress(),
111
110
  type: "secp256k1",
112
111
  },
113
- permissions: [{ type: PermissionType.ROOT }],
112
+ permissions: [{ type: "root" }],
114
113
  });
115
114
 
116
115
  const preparedUO = await client.prepareCalls({
@@ -228,7 +227,7 @@ describe("Client E2E Tests", () => {
228
227
  publicKey: await sessionKey.getAddress(),
229
228
  type: "secp256k1",
230
229
  },
231
- permissions: [{ type: PermissionType.ROOT }],
230
+ permissions: [{ type: "root" }],
232
231
  });
233
232
 
234
233
  const preparedUO = await client.prepareCalls({
@@ -72,7 +72,7 @@ export type SmartWalletActions<
72
72
  signMessage: (params: SignableMessage) => Promise<Hex>;
73
73
  signTypedData: (params: TypedDataDefinition) => Promise<Hex>;
74
74
  grantPermissions: (
75
- params: GrantPermissionsParams,
75
+ params: GrantPermissionsParams<TAccount>,
76
76
  ) => Promise<GrantPermissionsResult>;
77
77
  };
78
78
 
@@ -22,6 +22,8 @@ import {
22
22
  } from "@account-kit/smart-contracts/experimental";
23
23
  import { createDummySigner } from "../utils/createDummySigner";
24
24
  import { createAccount, isModularAccountV2 } from "../utils/createAccount";
25
+ import { Value } from "@sinclair/typebox/value";
26
+ import { TypePermission } from "../../capabilities/permissions";
25
27
 
26
28
  export type CreateSessionParams = Omit<
27
29
  Static<
@@ -100,7 +102,9 @@ export async function createSession(
100
102
  deadline: params.expiry,
101
103
  })
102
104
  .addPermissions({
103
- permissions: params.permissions,
105
+ permissions: params.permissions.map((permission) =>
106
+ Value.Encode(TypePermission, permission),
107
+ ),
104
108
  })
105
109
  .compileDeferred();
106
110
 
@@ -5,13 +5,13 @@ import {
5
5
  } from "@aa-sdk/core";
6
6
  import type { Static } from "@sinclair/typebox";
7
7
  import {
8
+ ChainNotFoundError,
8
9
  custom,
9
10
  fromHex,
11
+ toHex,
10
12
  zeroAddress,
11
13
  type Chain,
12
14
  type Transport,
13
- ChainNotFoundError,
14
- toHex,
15
15
  } from "viem";
16
16
  import type { wallet_prepareCalls } from "../../rpc/request";
17
17
  import type { WalletServerViemRpcSchema } from "../../rpc/schema";
@@ -76,6 +76,7 @@ export async function prepareCalls(
76
76
  value: x.value ? fromHex(x.value, "bigint") : undefined,
77
77
  })),
78
78
  account,
79
+ overrides: params.capabilities?.gasParamsOverride,
79
80
  });
80
81
 
81
82
  const uoRequest = deepHexlify(builtUo);
@@ -3,6 +3,8 @@ import {
3
3
  type SmartAccountClient,
4
4
  type SmartContractAccount,
5
5
  } from "@aa-sdk/core";
6
+ import type { Static, StaticDecode } from "@sinclair/typebox";
7
+ import { Value } from "@sinclair/typebox/value";
6
8
  import {
7
9
  ChainNotFoundError,
8
10
  concat,
@@ -15,12 +17,10 @@ import {
15
17
  import { decodePermissionsContext } from "../../capabilities/permissions/mav2";
16
18
  import type { wallet_sendPreparedCalls } from "../../rpc/request";
17
19
  import type { WalletServerViemRpcSchema } from "../../rpc/schema";
18
- import { Value } from "@sinclair/typebox/value";
19
20
  import { TypeCallId } from "../../schemas";
20
- import type { Static } from "@sinclair/typebox";
21
21
 
22
22
  export type SendPreparedCallsParams = Omit<
23
- Static<
23
+ StaticDecode<
24
24
  (typeof wallet_sendPreparedCalls)["properties"]["Request"]["properties"]["params"]
25
25
  >[0],
26
26
  "chainId"
@@ -6,30 +6,32 @@ import {
6
6
  } from "@aa-sdk/core";
7
7
  import {
8
8
  alchemyFeeEstimator,
9
+ alchemyGasAndPaymasterAndDataMiddleware,
9
10
  alchemyGasManagerMiddleware,
10
11
  type AlchemyTransport,
11
12
  } from "@account-kit/infra";
12
13
  import { type Chain, type Transport } from "viem";
13
14
  import type { WalletServerViemRpcSchema } from "../rpc/schema";
14
- import { prepareCalls, type PrepareCallsParams } from "./actions/prepareCalls";
15
15
  import {
16
- sendPreparedCalls,
17
- type SendPreparedCallsParams,
18
- } from "./actions/sendPreparedCalls";
16
+ createSession,
17
+ type CreateSessionParams,
18
+ } from "./actions/createSession";
19
19
  import {
20
20
  getCallsStatus,
21
21
  type GetCallsStatusParams,
22
22
  } from "./actions/getCallsStatus";
23
+ import { prepareCalls, type PrepareCallsParams } from "./actions/prepareCalls";
23
24
  import {
24
- createSession,
25
- type CreateSessionParams,
26
- } from "./actions/createSession";
25
+ sendPreparedCalls,
26
+ type SendPreparedCallsParams,
27
+ } from "./actions/sendPreparedCalls";
27
28
 
28
29
  // let's start with something that takes in as many params as possible, then we can eliminate them as we don't need them
29
30
  type ClientParams = {
30
31
  chain: Chain;
31
32
  transport: Transport;
32
33
  policyId?: string;
34
+ useErc7677middleware?: boolean;
33
35
  };
34
36
 
35
37
  export function isomorphicClientActions(
@@ -58,6 +60,7 @@ export function createIsomorphicClient({
58
60
  chain,
59
61
  transport,
60
62
  policyId,
63
+ useErc7677middleware = true,
61
64
  }: ClientParams): SmartAccountClient<
62
65
  Transport,
63
66
  Chain,
@@ -71,8 +74,15 @@ export function createIsomorphicClient({
71
74
  chain,
72
75
  // TODO: we will want to enforce alchemy transport here probably
73
76
  feeEstimator: alchemyFeeEstimator(transport as AlchemyTransport),
74
- // TODO: we need to use the other middleware that does gas estimation as well here
75
- ...(policyId ? alchemyGasManagerMiddleware(policyId) : {}),
77
+ ...(policyId
78
+ ? useErc7677middleware
79
+ ? alchemyGasManagerMiddleware(policyId)
80
+ : // NOTE: DO NOT USE THIS MIDDLEWARE in the server, currently we require using the erc7677 middleware
81
+ alchemyGasAndPaymasterAndDataMiddleware({
82
+ policyId,
83
+ transport: transport as AlchemyTransport,
84
+ })
85
+ : {}),
76
86
  }).extend(isomorphicClientActions);
77
87
 
78
88
  return client;
@@ -1,5 +1,11 @@
1
1
  import { split } from "@aa-sdk/core";
2
+ import { buildDeferredActionDigest } from "@account-kit/smart-contracts/experimental";
2
3
  import { createClient, custom, type Address, type JsonRpcAccount } from "viem";
4
+ import {
5
+ encodePermissionsContext,
6
+ prefixSignatureKeyType,
7
+ } from "../capabilities/permissions/mav2";
8
+ import { signSignatureRequest } from "../client/actions/signSignatureRequest";
3
9
  import type { PrepareCallsParams } from "../isomorphic/actions/prepareCalls";
4
10
  import {
5
11
  createIsomorphicClient,
@@ -11,12 +17,6 @@ import type {
11
17
  InnerWalletApiClient,
12
18
  } from "../types";
13
19
  import { assertNever } from "../utils";
14
- import { signSignatureRequest } from "../client/actions/signSignatureRequest";
15
- import {
16
- encodePermissionsContext,
17
- prefixSignatureKeyType,
18
- } from "../capabilities/permissions/mav2";
19
- import { buildDeferredActionDigest } from "@account-kit/smart-contracts/experimental";
20
20
 
21
21
  const localMethods = [
22
22
  "wallet_prepareCalls",
@@ -40,6 +40,7 @@ export function createLocalClient(
40
40
  transport,
41
41
  chain,
42
42
  policyId,
43
+ useErc7677middleware: false,
43
44
  });
44
45
 
45
46
  const clientMap: Record<string, ReturnType<typeof createIsomorphicClient>> = {
@@ -32,9 +32,15 @@ export const wallet_sendPreparedCalls = Type.Object(
32
32
  ]),
33
33
  chainId: TypeHex(),
34
34
  signature: Type.Object({
35
- // ignored, but in the spec can be used when the signature on the UO needs to be formatted differently
36
- // potentially useful for deferred actions?
37
- type: Type.String(),
35
+ type: Type.Transform(Type.String())
36
+ .Decode((value) => {
37
+ if (value.toLowerCase() !== "ecdsa") {
38
+ throw new Error("Invalid signature type, must be 'ecdsa'");
39
+ }
40
+
41
+ return "ecdsa" as const;
42
+ })
43
+ .Encode((value) => value),
38
44
  signature: TypeHex(),
39
45
  }),
40
46
  capabilities: Type.Optional(
@@ -180,18 +186,27 @@ export const wallet_listAccounts = Type.Object(
180
186
  },
181
187
  );
182
188
 
183
- export const wallet_createSession = Type.Object({
184
- Request: Type.Object({
185
- method: Type.Literal("wallet_createSession"),
186
- params: Type.Tuple([
187
- Type.Intersect([PermissionsData, Type.Object({ account: TypeAddress })]),
188
- ]),
189
- }),
190
- ReturnType: Type.Object({
191
- sessionId: TypeHex(),
192
- signatureRequest: TypeSignatureRequest,
193
- }),
194
- });
189
+ export const wallet_createSession = Type.Object(
190
+ {
191
+ Request: Type.Object({
192
+ method: Type.Literal("wallet_createSession"),
193
+ params: Type.Tuple([
194
+ Type.Intersect([
195
+ PermissionsData,
196
+ Type.Object({ account: TypeAddress }),
197
+ ]),
198
+ ]),
199
+ }),
200
+ ReturnType: Type.Object({
201
+ sessionId: TypeHex(),
202
+ signatureRequest: TypeSignatureRequest,
203
+ }),
204
+ },
205
+ {
206
+ description:
207
+ "This method is used to create a session for a given address with specified permissions.",
208
+ },
209
+ );
195
210
 
196
211
  export const wallet_getCallsStatus = Type.Object(
197
212
  {
package/src/rpc/schema.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { type Static } from "@sinclair/typebox";
1
+ import { type Static, type StaticDecode } from "@sinclair/typebox";
2
2
  import { RpcSchema } from "ox";
3
3
  import * as Requests from "./request";
4
4
 
5
5
  export const WalletServerRpcSchema = RpcSchema.from<
6
6
  | Static<typeof Requests.wallet_prepareCalls>
7
- | Static<typeof Requests.wallet_sendPreparedCalls>
7
+ | StaticDecode<typeof Requests.wallet_sendPreparedCalls>
8
8
  | Static<typeof Requests.wallet_createAccount>
9
9
  | Static<typeof Requests.wallet_requestAccount>
10
10
  | Static<typeof Requests.wallet_listAccounts>