@account-kit/wallet-client 0.1.0-alpha.4 → 0.1.0-alpha.5
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/eip7702Auth.d.ts +4 -0
- package/dist/esm/capabilities/eip7702Auth.js +16 -0
- package/dist/esm/capabilities/eip7702Auth.js.map +1 -0
- package/dist/esm/capabilities/index.d.ts +4 -0
- package/dist/esm/capabilities/index.js +2 -0
- package/dist/esm/capabilities/index.js.map +1 -1
- package/dist/esm/capabilities/permissions/index.d.ts +1 -1
- package/dist/esm/capabilities/permissions/mav2.js +1 -0
- package/dist/esm/capabilities/permissions/mav2.js.map +1 -1
- package/dist/esm/client/actions/getCallsStatus.d.ts +1 -2
- package/dist/esm/client/actions/getCallsStatus.js +19 -0
- package/dist/esm/client/actions/getCallsStatus.js.map +1 -1
- package/dist/esm/client/actions/grantPermissions.d.ts +6 -6
- package/dist/esm/client/actions/grantPermissions.js +115 -3
- package/dist/esm/client/actions/grantPermissions.js.map +1 -1
- package/dist/esm/client/actions/prepareCalls.d.ts +4 -4
- package/dist/esm/client/actions/prepareCalls.js +38 -5
- package/dist/esm/client/actions/prepareCalls.js.map +1 -1
- package/dist/esm/client/actions/requestAccount.d.ts +3 -4
- package/dist/esm/client/actions/requestAccount.js +18 -1
- package/dist/esm/client/actions/requestAccount.js.map +1 -1
- package/dist/esm/client/actions/signMessage.d.ts +3 -3
- package/dist/esm/client/actions/signMessage.js +18 -0
- package/dist/esm/client/actions/signMessage.js.map +1 -1
- package/dist/esm/client/actions/signSignatureRequest.d.ts +3 -3
- package/dist/esm/client/actions/signSignatureRequest.js +2 -2
- package/dist/esm/client/actions/signSignatureRequest.js.map +1 -1
- package/dist/esm/client/actions/signTypedData.d.ts +2 -2
- package/dist/esm/client/actions/signTypedData.js +31 -0
- package/dist/esm/client/actions/signTypedData.js.map +1 -1
- package/dist/esm/client/client.e2e-test.js +19 -19
- package/dist/esm/client/client.e2e-test.js.map +1 -1
- package/dist/esm/client/decorator.d.ts +4 -4
- package/dist/esm/client/decorator.js.map +1 -1
- package/dist/esm/client/index.d.ts +35 -10
- package/dist/esm/client/index.js +0 -29
- package/dist/esm/client/index.js.map +1 -1
- package/dist/esm/isomorphic/actions/createSession.js +21 -10
- package/dist/esm/isomorphic/actions/createSession.js.map +1 -1
- package/dist/esm/isomorphic/actions/getCallsStatus.js +62 -9
- package/dist/esm/isomorphic/actions/getCallsStatus.js.map +1 -1
- package/dist/esm/isomorphic/actions/prepareCalls.js +18 -11
- package/dist/esm/isomorphic/actions/prepareCalls.js.map +1 -1
- package/dist/esm/isomorphic/actions/sendPreparedCalls.js +2 -2
- package/dist/esm/isomorphic/actions/sendPreparedCalls.js.map +1 -1
- package/dist/esm/isomorphic/client.d.ts +1 -1
- package/dist/esm/isomorphic/utils/7702.d.ts +9 -3
- package/dist/esm/isomorphic/utils/7702.js +35 -8
- package/dist/esm/isomorphic/utils/7702.js.map +1 -1
- package/dist/esm/isomorphic/utils/createAccount.d.ts +2 -2
- package/dist/esm/isomorphic/utils/createAccount.js +4 -3
- package/dist/esm/isomorphic/utils/createAccount.js.map +1 -1
- package/dist/esm/isomorphic/utils/parsePermissionsContext.d.ts +2 -2
- package/dist/esm/isomorphic/utils/parsePermissionsContext.js +8 -7
- package/dist/esm/isomorphic/utils/parsePermissionsContext.js.map +1 -1
- package/dist/esm/local/client.d.ts +2 -2
- package/dist/esm/local/client.js.map +1 -1
- package/dist/esm/remote/client.d.ts +8 -2
- package/dist/esm/remote/client.js +1 -7
- package/dist/esm/remote/client.js.map +1 -1
- package/dist/esm/rpc/request.d.ts +12 -2
- package/dist/esm/rpc/request.js +6 -9
- package/dist/esm/rpc/request.js.map +1 -1
- package/dist/esm/rpc/schema.d.ts +23 -13
- package/dist/esm/schemas.d.ts +3 -1
- package/dist/esm/schemas.js +6 -4
- package/dist/esm/schemas.js.map +1 -1
- package/dist/esm/types.d.ts +7 -10
- package/dist/esm/types.js.map +1 -1
- package/dist/types/capabilities/eip7702Auth.d.ts +5 -0
- package/dist/types/capabilities/eip7702Auth.d.ts.map +1 -0
- package/dist/types/capabilities/index.d.ts +4 -0
- package/dist/types/capabilities/index.d.ts.map +1 -1
- package/dist/types/capabilities/permissions/index.d.ts +1 -1
- package/dist/types/capabilities/permissions/mav2.d.ts.map +1 -1
- package/dist/types/client/actions/getCallsStatus.d.ts +1 -2
- package/dist/types/client/actions/getCallsStatus.d.ts.map +1 -1
- package/dist/types/client/actions/grantPermissions.d.ts +6 -6
- package/dist/types/client/actions/grantPermissions.d.ts.map +1 -1
- package/dist/types/client/actions/prepareCalls.d.ts +4 -4
- package/dist/types/client/actions/prepareCalls.d.ts.map +1 -1
- package/dist/types/client/actions/requestAccount.d.ts +3 -4
- package/dist/types/client/actions/requestAccount.d.ts.map +1 -1
- package/dist/types/client/actions/signMessage.d.ts +3 -3
- package/dist/types/client/actions/signMessage.d.ts.map +1 -1
- package/dist/types/client/actions/signSignatureRequest.d.ts +3 -3
- package/dist/types/client/actions/signSignatureRequest.d.ts.map +1 -1
- package/dist/types/client/actions/signTypedData.d.ts +2 -2
- package/dist/types/client/actions/signTypedData.d.ts.map +1 -1
- package/dist/types/client/decorator.d.ts +4 -4
- package/dist/types/client/decorator.d.ts.map +1 -1
- package/dist/types/client/index.d.ts +35 -10
- package/dist/types/client/index.d.ts.map +1 -1
- package/dist/types/isomorphic/actions/createSession.d.ts.map +1 -1
- package/dist/types/isomorphic/actions/getCallsStatus.d.ts.map +1 -1
- package/dist/types/isomorphic/actions/prepareCalls.d.ts.map +1 -1
- package/dist/types/isomorphic/client.d.ts +1 -1
- package/dist/types/isomorphic/utils/7702.d.ts +9 -3
- package/dist/types/isomorphic/utils/7702.d.ts.map +1 -1
- package/dist/types/isomorphic/utils/createAccount.d.ts +2 -2
- package/dist/types/isomorphic/utils/createAccount.d.ts.map +1 -1
- package/dist/types/isomorphic/utils/parsePermissionsContext.d.ts +2 -2
- package/dist/types/isomorphic/utils/parsePermissionsContext.d.ts.map +1 -1
- package/dist/types/local/client.d.ts +2 -2
- package/dist/types/local/client.d.ts.map +1 -1
- package/dist/types/remote/client.d.ts +8 -2
- package/dist/types/remote/client.d.ts.map +1 -1
- package/dist/types/rpc/request.d.ts +12 -2
- package/dist/types/rpc/request.d.ts.map +1 -1
- package/dist/types/rpc/schema.d.ts +23 -13
- package/dist/types/rpc/schema.d.ts.map +1 -1
- package/dist/types/schemas.d.ts +3 -1
- package/dist/types/schemas.d.ts.map +1 -1
- package/dist/types/types.d.ts +7 -10
- package/dist/types/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/capabilities/eip7702Auth.ts +19 -0
- package/src/capabilities/index.ts +2 -0
- package/src/capabilities/permissions/mav2.ts +1 -0
- package/src/client/actions/getCallsStatus.ts +0 -10
- package/src/client/actions/grantPermissions.ts +12 -25
- package/src/client/actions/prepareCalls.ts +18 -23
- package/src/client/actions/requestAccount.ts +9 -26
- package/src/client/actions/signMessage.ts +2 -17
- package/src/client/actions/signSignatureRequest.ts +5 -5
- package/src/client/actions/signTypedData.ts +1 -16
- package/src/client/client.e2e-test.ts +22 -22
- package/src/client/decorator.ts +5 -10
- package/src/client/index.ts +16 -39
- package/src/isomorphic/actions/createSession.ts +29 -10
- package/src/isomorphic/actions/getCallsStatus.ts +82 -10
- package/src/isomorphic/actions/prepareCalls.ts +19 -11
- package/src/isomorphic/actions/sendPreparedCalls.ts +2 -2
- package/src/isomorphic/utils/7702.ts +61 -13
- package/src/isomorphic/utils/createAccount.ts +5 -5
- package/src/isomorphic/utils/parsePermissionsContext.ts +9 -9
- package/src/local/client.ts +3 -5
- package/src/remote/client.ts +5 -13
- package/src/rpc/request.ts +8 -9
- package/src/schemas.ts +8 -4
- package/src/types.ts +5 -21
package/src/client/index.ts
CHANGED
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
import type { SmartAccountSigner } from "@aa-sdk/core";
|
|
2
2
|
import type { AlchemyTransport } from "@account-kit/infra";
|
|
3
|
-
import type {
|
|
4
|
-
Address,
|
|
5
|
-
Chain,
|
|
6
|
-
IsUndefined,
|
|
7
|
-
JsonRpcAccount,
|
|
8
|
-
Prettify,
|
|
9
|
-
} from "viem";
|
|
3
|
+
import type { Address, Chain, Prettify } from "viem";
|
|
10
4
|
import { createLocalClient } from "../local/client.js";
|
|
11
5
|
import { createRemoteClient } from "../remote/client.js";
|
|
12
6
|
import type { InnerWalletApiClient } from "../types.ts";
|
|
@@ -16,40 +10,19 @@ import {
|
|
|
16
10
|
} from "./decorator.js";
|
|
17
11
|
|
|
18
12
|
export type SmartWalletClientParams<
|
|
19
|
-
TAccount extends
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
policyId?: string;
|
|
29
|
-
} & (IsUndefined<TAccount> extends true
|
|
30
|
-
? {
|
|
31
|
-
account?: never;
|
|
32
|
-
}
|
|
33
|
-
: {
|
|
34
|
-
account: Address;
|
|
35
|
-
})
|
|
36
|
-
>;
|
|
13
|
+
TAccount extends Address | undefined = Address | undefined,
|
|
14
|
+
> = Prettify<{
|
|
15
|
+
transport: AlchemyTransport;
|
|
16
|
+
chain: Chain;
|
|
17
|
+
signer: SmartAccountSigner;
|
|
18
|
+
mode: "local" | "remote";
|
|
19
|
+
policyId?: string;
|
|
20
|
+
account?: TAccount | Address | undefined;
|
|
21
|
+
}>;
|
|
37
22
|
|
|
38
23
|
export type SmartWalletClient<
|
|
39
|
-
TAccount extends
|
|
40
|
-
|
|
41
|
-
| undefined,
|
|
42
|
-
> = InnerWalletApiClient<TAccount> & SmartWalletActions<TAccount>;
|
|
43
|
-
|
|
44
|
-
export function createSmartWalletClient<
|
|
45
|
-
TAccount extends JsonRpcAccount<Address> | undefined =
|
|
46
|
-
| JsonRpcAccount<Address>
|
|
47
|
-
| undefined,
|
|
48
|
-
>(params: SmartWalletClientParams<TAccount>): SmartWalletClient<TAccount>;
|
|
49
|
-
|
|
50
|
-
export function createSmartWalletClient<
|
|
51
|
-
TAccount extends JsonRpcAccount<Address> = JsonRpcAccount<Address>,
|
|
52
|
-
>(params: SmartWalletClientParams<TAccount>): SmartWalletClient<TAccount>;
|
|
24
|
+
TAccount extends Address | undefined = Address | undefined,
|
|
25
|
+
> = InnerWalletApiClient & SmartWalletActions<TAccount>;
|
|
53
26
|
|
|
54
27
|
/**
|
|
55
28
|
* Creates a smart wallet client that can be used to interact with a smart account.
|
|
@@ -80,6 +53,10 @@ export function createSmartWalletClient<
|
|
|
80
53
|
* signer,
|
|
81
54
|
* });
|
|
82
55
|
*/
|
|
56
|
+
export function createSmartWalletClient<
|
|
57
|
+
TAccount extends Address | undefined = undefined,
|
|
58
|
+
>(params: SmartWalletClientParams<TAccount>): SmartWalletClient<TAccount>;
|
|
59
|
+
|
|
83
60
|
export function createSmartWalletClient(
|
|
84
61
|
params: SmartWalletClientParams,
|
|
85
62
|
): SmartWalletClient {
|
|
@@ -26,6 +26,10 @@ import { createAccount, isModularAccountV2 } from "../utils/createAccount.js";
|
|
|
26
26
|
import { createDummySigner } from "../utils/createDummySigner.js";
|
|
27
27
|
import { createAuthorization } from "../utils/7702.js";
|
|
28
28
|
import { InvalidRequestError } from "ox/RpcResponse";
|
|
29
|
+
import {
|
|
30
|
+
parseDelegation,
|
|
31
|
+
assertValid7702AccountAddress,
|
|
32
|
+
} from "../utils/7702.js";
|
|
29
33
|
|
|
30
34
|
export type CreateSessionParams = Omit<
|
|
31
35
|
Static<
|
|
@@ -59,15 +63,26 @@ export async function createSession(
|
|
|
59
63
|
throw new ChainNotFoundError();
|
|
60
64
|
}
|
|
61
65
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
params
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
66
|
+
assertValid7702AccountAddress(
|
|
67
|
+
params.account,
|
|
68
|
+
params.capabilities?.eip7702Auth,
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
const { counterfactualInfo, delegation } = params.capabilities?.eip7702Auth
|
|
72
|
+
? {
|
|
73
|
+
counterfactualInfo: undefined,
|
|
74
|
+
delegation: parseDelegation(params.capabilities.eip7702Auth),
|
|
75
|
+
}
|
|
76
|
+
: await client.request({
|
|
77
|
+
method: "wallet_requestAccount",
|
|
78
|
+
params: [
|
|
79
|
+
{
|
|
80
|
+
accountAddress: params.account,
|
|
81
|
+
includeCounterfactualInfo: true,
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
});
|
|
85
|
+
|
|
71
86
|
if (!counterfactualInfo && !delegation) {
|
|
72
87
|
throw new InvalidRequestError({
|
|
73
88
|
message:
|
|
@@ -104,7 +119,11 @@ export async function createSession(
|
|
|
104
119
|
const { typedData, fullPreSignatureDeferredActionDigest } =
|
|
105
120
|
await new PermissionBuilder({
|
|
106
121
|
client: _client,
|
|
107
|
-
key:
|
|
122
|
+
key: {
|
|
123
|
+
...params.key,
|
|
124
|
+
// Alias 'ecdsa' to 'secp256k1'
|
|
125
|
+
type: params.key.type === "ecdsa" ? "secp256k1" : params.key.type,
|
|
126
|
+
},
|
|
108
127
|
entityId,
|
|
109
128
|
nonce,
|
|
110
129
|
deadline: params.expiry,
|
|
@@ -6,6 +6,7 @@ import type { Static } from "@sinclair/typebox";
|
|
|
6
6
|
import { Value } from "@sinclair/typebox/value";
|
|
7
7
|
import {
|
|
8
8
|
ChainNotFoundError,
|
|
9
|
+
hexToNumber,
|
|
9
10
|
isHex,
|
|
10
11
|
type Chain,
|
|
11
12
|
type Hex,
|
|
@@ -16,6 +17,21 @@ import type { wallet_getCallsStatus } from "../../rpc/request.js";
|
|
|
16
17
|
import type { WalletServerViemRpcSchema } from "../../rpc/schema.js";
|
|
17
18
|
import { TypeCallId } from "../../schemas.js";
|
|
18
19
|
import { castToHex } from "../../utils.js";
|
|
20
|
+
import { InternalError, BaseError } from "ox/RpcResponse";
|
|
21
|
+
import {
|
|
22
|
+
polygon,
|
|
23
|
+
mainnet,
|
|
24
|
+
base,
|
|
25
|
+
worldchain,
|
|
26
|
+
optimism,
|
|
27
|
+
arbitrum,
|
|
28
|
+
sepolia,
|
|
29
|
+
polygonAmoy,
|
|
30
|
+
baseSepolia,
|
|
31
|
+
optimismSepolia,
|
|
32
|
+
worldchainSepolia,
|
|
33
|
+
arbitrumSepolia,
|
|
34
|
+
} from "viem/chains";
|
|
19
35
|
|
|
20
36
|
export type GetCallsStatusParams = Static<
|
|
21
37
|
(typeof wallet_getCallsStatus)["properties"]["Request"]["properties"]["params"]
|
|
@@ -44,6 +60,29 @@ export const CallStatusCode = {
|
|
|
44
60
|
PARTIAL_CHAIN_RULES_FAILURE: 600,
|
|
45
61
|
} as const;
|
|
46
62
|
|
|
63
|
+
// https://eips.ethereum.org/EIPS/eip-5792#error-codes
|
|
64
|
+
const ErrorCode = {
|
|
65
|
+
UNKNOWN_BUNDLE_ID: 5730,
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// "eth_getUserOperationByHash" is limited to the last 150 blocks
|
|
69
|
+
// for all networks except those in this list.
|
|
70
|
+
// https://www.alchemy.com/docs/node/bundler-api/bundler-api-endpoints/eth-get-user-operation-by-hash
|
|
71
|
+
const GET_USER_OP_BY_HASH_UNLIMITED_RANGE_NETWORKS: number[] = [
|
|
72
|
+
mainnet.id,
|
|
73
|
+
sepolia.id,
|
|
74
|
+
polygon.id,
|
|
75
|
+
polygonAmoy.id,
|
|
76
|
+
base.id,
|
|
77
|
+
baseSepolia.id,
|
|
78
|
+
optimism.id,
|
|
79
|
+
optimismSepolia.id,
|
|
80
|
+
worldchain.id,
|
|
81
|
+
worldchainSepolia.id,
|
|
82
|
+
arbitrum.id,
|
|
83
|
+
arbitrumSepolia.id,
|
|
84
|
+
];
|
|
85
|
+
|
|
47
86
|
export async function getCallsStatus(
|
|
48
87
|
client: SmartAccountClient<
|
|
49
88
|
Transport,
|
|
@@ -57,21 +96,54 @@ export async function getCallsStatus(
|
|
|
57
96
|
if (!client.chain) {
|
|
58
97
|
throw new ChainNotFoundError();
|
|
59
98
|
}
|
|
60
|
-
|
|
61
99
|
const { chainId, hash } = Value.Decode(TypeCallId, callId);
|
|
62
100
|
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
return {
|
|
101
|
+
const baseResp = {
|
|
66
102
|
id: callId,
|
|
67
103
|
chainId,
|
|
68
104
|
atomic: true,
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const result = await client.getUserOperationByHash(hash);
|
|
108
|
+
if (
|
|
109
|
+
!result &&
|
|
110
|
+
GET_USER_OP_BY_HASH_UNLIMITED_RANGE_NETWORKS.includes(hexToNumber(chainId))
|
|
111
|
+
) {
|
|
112
|
+
// This network has unlimited range, so we should always have a result here if the callId is valid.
|
|
113
|
+
throw new BaseError({
|
|
114
|
+
message: `callId ${callId} not found`,
|
|
115
|
+
code: ErrorCode.UNKNOWN_BUNDLE_ID,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
if (result && !result.transactionHash) {
|
|
119
|
+
// A result but no txn hash means it's valid but pending.
|
|
120
|
+
return {
|
|
121
|
+
...baseResp,
|
|
122
|
+
status: CallStatusCode.PENDING,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const receipt = await client.getUserOperationReceipt(hash);
|
|
127
|
+
if (result?.transactionHash && !receipt) {
|
|
128
|
+
// This should never happen.
|
|
129
|
+
throw new InternalError({
|
|
130
|
+
message: `Failed to get receipt for callId ${callId}`,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
if (!receipt) {
|
|
134
|
+
// This covers txns older than 150 blocks which were not retrievable by "eth_getUserOperationByHash".
|
|
135
|
+
throw new BaseError({
|
|
136
|
+
message: `callId ${callId} not found`,
|
|
137
|
+
code: ErrorCode.UNKNOWN_BUNDLE_ID,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return {
|
|
142
|
+
...baseResp,
|
|
143
|
+
status: receipt.success
|
|
144
|
+
? CallStatusCode.CONFIRMED
|
|
145
|
+
: CallStatusCode.CHAIN_RULES_FAILURE,
|
|
146
|
+
receipts: [transformReceipt(receipt.receipt)],
|
|
75
147
|
};
|
|
76
148
|
}
|
|
77
149
|
|
|
@@ -17,8 +17,9 @@ 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";
|
|
20
|
+
import { createAuthorization, parseDelegation } from "../utils/7702.js";
|
|
21
21
|
import { InvalidRequestError } from "ox/RpcResponse";
|
|
22
|
+
import { assertValid7702AccountAddress } from "../utils/7702.js";
|
|
22
23
|
|
|
23
24
|
export type PrepareCallsParams = Omit<
|
|
24
25
|
Static<
|
|
@@ -45,16 +46,23 @@ export async function prepareCalls(
|
|
|
45
46
|
throw new ChainNotFoundError();
|
|
46
47
|
}
|
|
47
48
|
|
|
49
|
+
assertValid7702AccountAddress(params.from, params.capabilities?.eip7702Auth);
|
|
50
|
+
|
|
48
51
|
// in local mode, we probably want some kind of caching for this
|
|
49
|
-
const { counterfactualInfo, delegation } =
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
52
|
+
const { counterfactualInfo, delegation } = params.capabilities?.eip7702Auth
|
|
53
|
+
? {
|
|
54
|
+
counterfactualInfo: undefined,
|
|
55
|
+
delegation: parseDelegation(params.capabilities.eip7702Auth),
|
|
56
|
+
}
|
|
57
|
+
: await client.request({
|
|
58
|
+
method: "wallet_requestAccount",
|
|
59
|
+
params: [
|
|
60
|
+
{
|
|
61
|
+
accountAddress: params.from,
|
|
62
|
+
includeCounterfactualInfo: true,
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
});
|
|
58
66
|
|
|
59
67
|
if (!counterfactualInfo && !delegation) {
|
|
60
68
|
throw new InvalidRequestError({
|
|
@@ -69,7 +77,7 @@ export async function prepareCalls(
|
|
|
69
77
|
signer: createDummySigner(params.from),
|
|
70
78
|
accountAddress: params.from,
|
|
71
79
|
counterfactualInfo,
|
|
72
|
-
|
|
80
|
+
permissions: params.capabilities?.permissions,
|
|
73
81
|
delegation,
|
|
74
82
|
});
|
|
75
83
|
|
|
@@ -19,7 +19,7 @@ import { decodePermissionsContext } from "../../capabilities/permissions/mav2.js
|
|
|
19
19
|
import type { wallet_sendPreparedCalls } from "../../rpc/request.js";
|
|
20
20
|
import type { WalletServerViemRpcSchema } from "../../rpc/schema.js";
|
|
21
21
|
import { TypeCallId } from "../../schemas.js";
|
|
22
|
-
import {
|
|
22
|
+
import { isSupportedDelegationAddress7702 } from "../utils/7702.js";
|
|
23
23
|
import { InvalidRequestError } from "ox/RpcResponse";
|
|
24
24
|
|
|
25
25
|
export type SendPreparedCallsParams = Omit<
|
|
@@ -51,7 +51,7 @@ export async function sendPreparedCalls(
|
|
|
51
51
|
// One last safety check to be sure the UO wasn't modified to include an unsupported 7702 delegation address.
|
|
52
52
|
if (
|
|
53
53
|
params.signedAuthorization &&
|
|
54
|
-
!
|
|
54
|
+
!isSupportedDelegationAddress7702(params.signedAuthorization.address)
|
|
55
55
|
) {
|
|
56
56
|
throw new InvalidRequestError({
|
|
57
57
|
message: `Unsupported 7702 delegation address: ${params.signedAuthorization.address}`,
|
|
@@ -5,8 +5,12 @@ import {
|
|
|
5
5
|
type Address,
|
|
6
6
|
type Chain,
|
|
7
7
|
type Transport,
|
|
8
|
+
isAddress,
|
|
8
9
|
} from "viem";
|
|
9
10
|
import type { WalletServerViemRpcSchema } from "../../rpc/schema.js";
|
|
11
|
+
import type { Eip7702AuthCapability } from "../../capabilities/eip7702Auth.ts";
|
|
12
|
+
import type { Static } from "@sinclair/typebox";
|
|
13
|
+
import { InvalidRequestError } from "ox/RpcResponse";
|
|
10
14
|
|
|
11
15
|
export const createAuthorization = async (
|
|
12
16
|
client: SmartAccountClient<
|
|
@@ -32,27 +36,71 @@ export const createAuthorization = async (
|
|
|
32
36
|
};
|
|
33
37
|
};
|
|
34
38
|
|
|
35
|
-
|
|
39
|
+
export const EIP_7702_ACCOUNT_TYPE = ["ModularAccountV2"] as const;
|
|
36
40
|
|
|
37
|
-
|
|
41
|
+
type Supported7702AccountType = (typeof EIP_7702_ACCOUNT_TYPE)[number];
|
|
42
|
+
|
|
43
|
+
const Eip7702AccountTypeToDelegationAddress = {
|
|
44
|
+
ModularAccountV2: "0x69007702764179f14F51cdce752f4f775d74E139",
|
|
45
|
+
} as const satisfies Record<Supported7702AccountType, Address>;
|
|
46
|
+
|
|
47
|
+
const DelegationAddressToAccountType: Record<
|
|
38
48
|
Address,
|
|
39
49
|
Supported7702AccountType
|
|
40
|
-
> =
|
|
41
|
-
|
|
50
|
+
> = Object.fromEntries(
|
|
51
|
+
Object.entries(Eip7702AccountTypeToDelegationAddress).map(([key, value]) => [
|
|
52
|
+
value,
|
|
53
|
+
key,
|
|
54
|
+
]),
|
|
55
|
+
) as Record<Address, Supported7702AccountType>;
|
|
56
|
+
|
|
57
|
+
export const SUPPORTED_DELEGATION_ADDRESSES = Object.values(
|
|
58
|
+
Eip7702AccountTypeToDelegationAddress,
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
export const isSupportedDelegationAddress7702 = (address: Address): boolean => {
|
|
62
|
+
return (SUPPORTED_DELEGATION_ADDRESSES as Address[]).includes(address);
|
|
42
63
|
};
|
|
43
64
|
|
|
44
|
-
export const
|
|
65
|
+
export const getAccountTypeForDelegationAddress7702 = (
|
|
45
66
|
address: Address,
|
|
46
67
|
): Supported7702AccountType | undefined => {
|
|
47
|
-
return
|
|
68
|
+
return DelegationAddressToAccountType[address];
|
|
48
69
|
};
|
|
49
70
|
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
)
|
|
71
|
+
const getDelegationAddressForAccountType7702 = (
|
|
72
|
+
accountType: Supported7702AccountType,
|
|
73
|
+
): (typeof SUPPORTED_DELEGATION_ADDRESSES)[number] => {
|
|
74
|
+
return Eip7702AccountTypeToDelegationAddress[accountType];
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const DEFAULT_7702_DELEGATION_ADDR =
|
|
78
|
+
Eip7702AccountTypeToDelegationAddress["ModularAccountV2"];
|
|
53
79
|
|
|
54
|
-
export const
|
|
55
|
-
|
|
56
|
-
)
|
|
57
|
-
return
|
|
80
|
+
export const parseDelegation = (
|
|
81
|
+
eip7702AuthCapability: Static<typeof Eip7702AuthCapability>,
|
|
82
|
+
) => {
|
|
83
|
+
return eip7702AuthCapability === true
|
|
84
|
+
? DEFAULT_7702_DELEGATION_ADDR
|
|
85
|
+
: isAddress(eip7702AuthCapability.delegation)
|
|
86
|
+
? eip7702AuthCapability.delegation
|
|
87
|
+
: getDelegationAddressForAccountType7702(
|
|
88
|
+
eip7702AuthCapability.delegation,
|
|
89
|
+
);
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export const assertValid7702AccountAddress = (
|
|
93
|
+
fromAddress: Address,
|
|
94
|
+
eip7702AuthCapability: Static<typeof Eip7702AuthCapability> | undefined,
|
|
95
|
+
) => {
|
|
96
|
+
if (
|
|
97
|
+
eip7702AuthCapability &&
|
|
98
|
+
typeof eip7702AuthCapability === "object" &&
|
|
99
|
+
"account" in eip7702AuthCapability &&
|
|
100
|
+
eip7702AuthCapability?.account !== fromAddress
|
|
101
|
+
) {
|
|
102
|
+
throw new InvalidRequestError({
|
|
103
|
+
message: `EIP-7702 delegation account ${eip7702AuthCapability.account} must match 'from' address ${fromAddress}.`,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
58
106
|
};
|
|
@@ -6,12 +6,12 @@ import {
|
|
|
6
6
|
import type { StaticDecode } from "@sinclair/typebox";
|
|
7
7
|
import type { Address, Chain, Transport } from "viem";
|
|
8
8
|
import { concatHex, hexToNumber } from "viem";
|
|
9
|
-
import type { Capabilities } from "../../capabilities/index.js";
|
|
10
9
|
import type { TypeSerializedInitcode } from "../../schemas.js";
|
|
11
10
|
import { parsePermissionsContext } from "./parsePermissionsContext.js";
|
|
12
11
|
import { assertNever } from "../../utils.js";
|
|
13
|
-
import {
|
|
12
|
+
import { getAccountTypeForDelegationAddress7702 } from "./7702.js";
|
|
14
13
|
import { InternalError } from "ox/RpcResponse";
|
|
14
|
+
import { PermissionsCapability } from "../../capabilities/permissions/index.js";
|
|
15
15
|
|
|
16
16
|
type CreateAccountParams = {
|
|
17
17
|
chain: Chain;
|
|
@@ -19,8 +19,8 @@ type CreateAccountParams = {
|
|
|
19
19
|
signer: SmartAccountSigner;
|
|
20
20
|
accountAddress: Address;
|
|
21
21
|
counterfactualInfo?: StaticDecode<typeof TypeSerializedInitcode>; // undefined for 7702 accounts
|
|
22
|
+
permissions?: StaticDecode<typeof PermissionsCapability>;
|
|
22
23
|
delegation?: Address;
|
|
23
|
-
capabilities?: StaticDecode<typeof Capabilities>;
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
/**
|
|
@@ -47,7 +47,7 @@ export async function createAccount(
|
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
49
|
} else if (mode === "7702") {
|
|
50
|
-
const accountType =
|
|
50
|
+
const accountType = getAccountTypeForDelegationAddress7702(
|
|
51
51
|
params.delegation!,
|
|
52
52
|
);
|
|
53
53
|
if (accountType !== "ModularAccountV2") {
|
|
@@ -60,7 +60,7 @@ export async function createAccount(
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
const parsedContext = parsePermissionsContext(
|
|
63
|
-
params.
|
|
63
|
+
params.permissions,
|
|
64
64
|
ci,
|
|
65
65
|
params.delegation,
|
|
66
66
|
);
|
|
@@ -2,33 +2,33 @@ import type { StaticDecode } from "@sinclair/typebox";
|
|
|
2
2
|
import { InvalidRequestError } from "ox/RpcResponse";
|
|
3
3
|
import { decodePermissionsContext } from "../../capabilities/permissions/mav2.js";
|
|
4
4
|
import type { TypeSerializedInitcode } from "../../schemas.js";
|
|
5
|
-
import type { PrepareCallsParams } from "../actions/prepareCalls.js";
|
|
6
5
|
import type { Address } from "viem";
|
|
7
|
-
import {
|
|
6
|
+
import { getAccountTypeForDelegationAddress7702 } from "./7702.js";
|
|
7
|
+
import { PermissionsCapability } from "../../capabilities/permissions/index.js";
|
|
8
8
|
|
|
9
9
|
export function parsePermissionsContext(
|
|
10
|
-
|
|
11
|
-
parsedCi
|
|
10
|
+
permissions?: StaticDecode<typeof PermissionsCapability>,
|
|
11
|
+
parsedCi?: StaticDecode<typeof TypeSerializedInitcode> | undefined,
|
|
12
12
|
delegation7702?: Address,
|
|
13
13
|
) {
|
|
14
|
-
if (!
|
|
14
|
+
if (!permissions) {
|
|
15
15
|
return undefined;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
if ("sessionId" in
|
|
18
|
+
if ("sessionId" in permissions) {
|
|
19
19
|
throw new InvalidRequestError({
|
|
20
20
|
message: "Remote permissions are not supported in isomorphic client",
|
|
21
21
|
});
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
if (!("context" in
|
|
24
|
+
if (!("context" in permissions)) {
|
|
25
25
|
return undefined;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
const isMAV2 =
|
|
29
29
|
(parsedCi && parsedCi.factoryType === "MAv2.0.0-sma-b") ||
|
|
30
30
|
(delegation7702 &&
|
|
31
|
-
|
|
31
|
+
getAccountTypeForDelegationAddress7702(delegation7702) ===
|
|
32
32
|
"ModularAccountV2");
|
|
33
33
|
|
|
34
34
|
if (!isMAV2) {
|
|
@@ -37,7 +37,7 @@ export function parsePermissionsContext(
|
|
|
37
37
|
});
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
const context = decodePermissionsContext(
|
|
40
|
+
const context = decodePermissionsContext(permissions);
|
|
41
41
|
|
|
42
42
|
if (context?.contextVersion === "REMOTE_MODE_DEFERRED_ACTION") {
|
|
43
43
|
throw new InvalidRequestError({
|
package/src/local/client.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { split } from "@aa-sdk/core";
|
|
2
2
|
import { buildDeferredActionDigest } from "@account-kit/smart-contracts/experimental";
|
|
3
|
-
import { createClient, custom, type Address
|
|
3
|
+
import { createClient, custom, type Address } from "viem";
|
|
4
4
|
import {
|
|
5
5
|
encodePermissionsContext,
|
|
6
6
|
prefixSignatureKeyType,
|
|
@@ -28,10 +28,8 @@ const localMethods = [
|
|
|
28
28
|
type LocalMethod = (typeof localMethods)[number];
|
|
29
29
|
|
|
30
30
|
export function createLocalClient<
|
|
31
|
-
TAccount extends
|
|
32
|
-
|
|
33
|
-
| undefined,
|
|
34
|
-
>(params: CreateInnerClientParams<TAccount>): InnerWalletApiClient<TAccount>;
|
|
31
|
+
TAccount extends Address | undefined = Address | undefined,
|
|
32
|
+
>(params: CreateInnerClientParams<TAccount>): InnerWalletApiClient;
|
|
35
33
|
|
|
36
34
|
export function createLocalClient(
|
|
37
35
|
params: CreateInnerClientParams,
|
package/src/remote/client.ts
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import { Provider } from "ox";
|
|
2
|
-
import {
|
|
3
|
-
BaseError,
|
|
4
|
-
createClient,
|
|
5
|
-
custom,
|
|
6
|
-
type Address,
|
|
7
|
-
type JsonRpcAccount,
|
|
8
|
-
} from "viem";
|
|
2
|
+
import { BaseError, createClient, custom, type Address } from "viem";
|
|
9
3
|
import { encodePermissionsContext } from "../capabilities/permissions/mav2.js";
|
|
10
4
|
import { signSignatureRequest } from "../client/actions/signSignatureRequest.js";
|
|
11
5
|
import { internalStateDecorator } from "../internal/decorator.js";
|
|
@@ -17,18 +11,16 @@ import type {
|
|
|
17
11
|
InnerWalletApiClientBase,
|
|
18
12
|
} from "../types.ts";
|
|
19
13
|
|
|
20
|
-
export function createRemoteClient<
|
|
21
|
-
TAccount extends JsonRpcAccount<Address> | undefined =
|
|
22
|
-
| JsonRpcAccount<Address>
|
|
23
|
-
| undefined,
|
|
24
|
-
>(params: CreateInnerClientParams<TAccount>): InnerWalletApiClient<TAccount>;
|
|
25
|
-
|
|
26
14
|
/**
|
|
27
15
|
* This is a low-level client just used to make RPC requests in remote mode
|
|
28
16
|
* This should be wrapped by a higher-level smart account client that provides actions
|
|
29
17
|
* that uses this client under the hood
|
|
30
18
|
* @returns
|
|
31
19
|
*/
|
|
20
|
+
export function createRemoteClient<
|
|
21
|
+
TAccount extends Address | undefined = Address | undefined,
|
|
22
|
+
>(params: CreateInnerClientParams<TAccount>): InnerWalletApiClient;
|
|
23
|
+
|
|
32
24
|
export function createRemoteClient(
|
|
33
25
|
params: CreateInnerClientParams,
|
|
34
26
|
): InnerWalletApiClient {
|
package/src/rpc/request.ts
CHANGED
|
@@ -16,8 +16,10 @@ import {
|
|
|
16
16
|
TypeUserOperationRequest_v6,
|
|
17
17
|
TypeUserOperationRequest_v7,
|
|
18
18
|
TypeUuid,
|
|
19
|
+
TypeSignatureType,
|
|
19
20
|
} from "../schemas.js";
|
|
20
21
|
import { Examples } from "./examples.js";
|
|
22
|
+
import { Eip7702AuthCapability } from "../capabilities/eip7702Auth.js";
|
|
21
23
|
|
|
22
24
|
export const wallet_sendPreparedCalls = Type.Object(
|
|
23
25
|
{
|
|
@@ -43,15 +45,7 @@ export const wallet_sendPreparedCalls = Type.Object(
|
|
|
43
45
|
]),
|
|
44
46
|
chainId: TypeHex(),
|
|
45
47
|
signature: Type.Object({
|
|
46
|
-
type: Type.
|
|
47
|
-
.Decode((value) => {
|
|
48
|
-
if (value.toLowerCase() !== "ecdsa") {
|
|
49
|
-
throw new Error("Invalid signature type, must be 'ecdsa'");
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return "ecdsa" as const;
|
|
53
|
-
})
|
|
54
|
-
.Encode((value) => value),
|
|
48
|
+
type: Type.Exclude(TypeSignatureType, Type.Literal("contract")),
|
|
55
49
|
signature: TypeHex(),
|
|
56
50
|
}),
|
|
57
51
|
signedAuthorization: Type.Optional(TypeEip7702AuthExtendedFields),
|
|
@@ -235,6 +229,11 @@ export const wallet_createSession = Type.Object(
|
|
|
235
229
|
PermissionsData,
|
|
236
230
|
Type.Object({
|
|
237
231
|
account: TypeAddress,
|
|
232
|
+
capabilities: Type.Optional(
|
|
233
|
+
Type.Object({
|
|
234
|
+
eip7702Auth: Type.Optional(Eip7702AuthCapability),
|
|
235
|
+
}),
|
|
236
|
+
),
|
|
238
237
|
}),
|
|
239
238
|
]),
|
|
240
239
|
]),
|
package/src/schemas.ts
CHANGED
|
@@ -287,11 +287,15 @@ export type TypeAccountType = Exclude<
|
|
|
287
287
|
undefined
|
|
288
288
|
>["accountType"];
|
|
289
289
|
|
|
290
|
+
export const TypeSignatureType = Type.Union([
|
|
291
|
+
Type.Literal("secp256k1", { title: "Secp256k1" }),
|
|
292
|
+
Type.Literal("ecdsa", { title: "ECDSA (alias for secp256k1)" }),
|
|
293
|
+
Type.Literal("contract", { title: "Contract" }),
|
|
294
|
+
]);
|
|
295
|
+
export type TypeSignatureType = Static<typeof TypeSignatureType>;
|
|
296
|
+
|
|
290
297
|
export const KeySigner = Type.Object({
|
|
291
|
-
type:
|
|
292
|
-
Type.Literal("secp256k1", { title: "Secp256k1" }),
|
|
293
|
-
Type.Literal("contract", { title: "Contract" }),
|
|
294
|
-
]),
|
|
298
|
+
type: TypeSignatureType,
|
|
295
299
|
publicKey: TypeHex({}),
|
|
296
300
|
});
|
|
297
301
|
export type KeySigner = Static<typeof KeySigner>;
|