@mentaproject/core 0.5.15 → 0.6.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.
- package/dist/clients/index.js +62 -1
- package/dist/clients/index.js.map +1 -1
- package/dist/clients/index.mjs +62 -1
- package/dist/clients/index.mjs.map +1 -1
- package/dist/types/CoreClient.d.ts +10 -1
- package/dist/types/MentaAccount.d.ts +3 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/utils/createRoutedTransport.d.ts +22 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +59 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/index.mjs +59 -1
- package/dist/utils/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/clients/createMentaAccount.ts +9 -1
- package/src/types/CoreClient.ts +13 -1
- package/src/types/MentaAccount.ts +3 -0
- package/src/types/index.ts +1 -1
- package/src/utils/createRoutedTransport.ts +65 -0
- package/src/utils/index.ts +2 -1
|
@@ -9,5 +9,14 @@ export type PermissionlessClientProperties<client extends ViemClient | undefined
|
|
|
9
9
|
paymasterContext: BundlerClientConfig["paymasterContext"] | undefined;
|
|
10
10
|
userOperation: BundlerClientConfig["userOperation"] | undefined;
|
|
11
11
|
};
|
|
12
|
-
|
|
12
|
+
/**
|
|
13
|
+
* A basic viem Client used for standard RPC operations.
|
|
14
|
+
* This is the type returned by createClient before smart account setup.
|
|
15
|
+
*/
|
|
16
|
+
export type CoreClient<TChain extends Chain | undefined = Chain | undefined> = ViemClient<Transport, TChain>;
|
|
17
|
+
/**
|
|
18
|
+
* A SmartAccountClient with permissionless properties.
|
|
19
|
+
* This is the type returned after setting up the smart account.
|
|
20
|
+
*/
|
|
21
|
+
export type SmartAccountCoreClient<TChain extends Chain | undefined = Chain | undefined, TAccount extends SmartAccount | undefined = SmartAccount | undefined> = ViemClient<Transport, TChain, TAccount> & PermissionlessClientProperties;
|
|
13
22
|
export type CoreClientConfig = RenameProperty<SmartAccountClientConfig, "bundlerTransport", "transport">;
|
|
@@ -10,6 +10,9 @@ export interface PasskeySigner extends LocalAccount {
|
|
|
10
10
|
}
|
|
11
11
|
export interface MentaAccountParams {
|
|
12
12
|
signer: PasskeySigner;
|
|
13
|
+
/** Transport for ERC-4337 bundler calls */
|
|
13
14
|
bundlerTransport: Transport;
|
|
15
|
+
/** Transport for standard Ethereum RPC calls (eth_getBlock, etc.) */
|
|
16
|
+
publicTransport: Transport;
|
|
14
17
|
}
|
|
15
18
|
export type MentaAccountClient = Awaited<ReturnType<typeof createMentaAccount>>;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export type { AccessList, Address, Hash, Hex, BlockTag, Chain, Log, TransactionType, Quantity, AbiItem, Transport, Withdrawal, Transaction, } from "viem";
|
|
2
2
|
export type { GetEnsAddressReturnType, GetEnsAvatarReturnType, GetEnsNameReturnType, GetEnsResolverReturnType, GetEnsTextReturnType, CallReturnType, CreateAccessListReturnType, CreateBlockFilterReturnType, CreateContractEventFilterReturnType, CreateEventFilterReturnType, CreatePendingTransactionFilterReturnType, EstimateContractGasReturnType, EstimateFeesPerGasReturnType, EstimateMaxPriorityFeePerGasReturnType, EstimateGasReturnType, GetBalanceReturnType, GetBlobBaseFeeReturnType, GetBlockReturnType, GetBlockNumberReturnType, GetBlockTransactionCountReturnType, GetChainIdReturnType, GetCodeReturnType, GetBytecodeReturnType, GetContractEventsReturnType, GetEip712DomainReturnType, GetFeeHistoryReturnType, GetFilterChangesReturnType, GetFilterLogsReturnType, GetGasPriceReturnType, GetLogsReturnType, GetStorageAtReturnType, GetTransactionConfirmationsReturnType, GetTransactionCountReturnType, GetTransactionReturnType, GetTransactionReceiptReturnType, MulticallReturnType, SimulateBlocksReturnType, SimulateContractReturnType, SimulateCallsReturnType, WatchBlocksReturnType, WatchBlockNumberReturnType, WatchEventReturnType, WatchContractEventReturnType, WatchPendingTransactionsReturnType, ReadContractReturnType, GetProofReturnType, WaitForTransactionReceiptReturnType, SendTransactionReturnType, SignMessageReturnType, SignTypedDataReturnType, WriteContractReturnType, GetEnsAddressParameters, GetEnsAvatarParameters, GetEnsNameParameters, GetEnsResolverParameters, GetEnsTextParameters, CallParameters, CreateAccessListParameters, CreateContractEventFilterParameters, CreateEventFilterParameters, EstimateContractGasParameters, EstimateFeesPerGasParameters, EstimateMaxPriorityFeePerGasParameters, EstimateGasParameters, GetBalanceParameters, GetBlockParameters, GetBlockNumberParameters, GetBlockTransactionCountParameters, GetCodeParameters, GetBytecodeParameters, GetContractEventsParameters, GetEip712DomainParameters, GetFeeHistoryParameters, GetFilterChangesParameters, GetFilterLogsParameters, GetLogsParameters, GetStorageAtParameters, GetTransactionConfirmationsParameters, GetTransactionCountParameters, GetTransactionParameters, GetTransactionReceiptParameters, MulticallParameters, SimulateBlocksParameters, SimulateContractParameters, SimulateCallsParameters, WatchBlocksParameters, WatchBlockNumberParameters, WatchEventParameters, WatchContractEventParameters, WatchPendingTransactionsParameters, ReadContractParameters, GetProofParameters, WaitForTransactionReceiptParameters, SendTransactionParameters, SignMessageParameters, SignTypedDataParameters, WriteContractParameters, } from "viem";
|
|
3
3
|
export type { AbiError, AbiConstructor, AbiFunction, AbiEvent, AbiParameter, AbiParameterToPrimitiveType, } from "abitype";
|
|
4
|
-
export type { CoreClient, CoreClientConfig } from "./CoreClient";
|
|
4
|
+
export type { CoreClient, SmartAccountCoreClient, CoreClientConfig } from "./CoreClient";
|
|
5
5
|
export { TraceFilterParameters, TraceFilterReturnType, TraceTransactionParameters, TraceTransactionReturnType, TraceBlockParameters, TraceBlockReturnType, TraceAction, TraceActionResult, TraceEntry, } from "./Trace";
|
|
6
6
|
export { FetchBlockRangeParameters, onBlockRangeCallback, BlockRange, } from "./BlockRangeFetcher";
|
|
7
7
|
export { TransactionOptions } from "./Transaction";
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Transport } from "viem";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a transport that routes requests between a public RPC and a bundler RPC.
|
|
4
|
+
*
|
|
5
|
+
* Bundler-specific methods (ERC-4337) are routed to the bundler transport,
|
|
6
|
+
* while all other methods (eth_getBlockByNumber, eth_call, etc.) are routed
|
|
7
|
+
* to the public transport.
|
|
8
|
+
*
|
|
9
|
+
* @param publicTransport - Transport for standard Ethereum RPC calls
|
|
10
|
+
* @param bundlerTransport - Transport for ERC-4337 bundler calls
|
|
11
|
+
* @returns A unified transport that routes requests appropriately
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* import { http } from 'viem';
|
|
15
|
+
* import { createRoutedTransport } from '@mentaproject/core/utils';
|
|
16
|
+
*
|
|
17
|
+
* const transport = createRoutedTransport(
|
|
18
|
+
* http('https://eth-mainnet.g.alchemy.com/v2/...'),
|
|
19
|
+
* http('https://api.pimlico.io/v2/1/rpc?apikey=...')
|
|
20
|
+
* );
|
|
21
|
+
*/
|
|
22
|
+
export declare function createRoutedTransport(publicTransport: Transport, bundlerTransport: Transport): Transport;
|
package/dist/utils/index.d.ts
CHANGED
package/dist/utils/index.js
CHANGED
|
@@ -33,8 +33,67 @@ const bytes32ToAddress = (bytes) => {
|
|
|
33
33
|
|
|
34
34
|
const nonZeroAddress = (address) => address === viem.zeroAddress ? undefined : address;
|
|
35
35
|
|
|
36
|
+
/**
|
|
37
|
+
* RPC methods that should be routed to the bundler.
|
|
38
|
+
* All other methods will be routed to the public RPC.
|
|
39
|
+
*/
|
|
40
|
+
const BUNDLER_METHODS = new Set([
|
|
41
|
+
// ERC-4337 standard methods
|
|
42
|
+
"eth_sendUserOperation",
|
|
43
|
+
"eth_estimateUserOperationGas",
|
|
44
|
+
"eth_getUserOperationByHash",
|
|
45
|
+
"eth_getUserOperationReceipt",
|
|
46
|
+
"eth_supportedEntryPoints",
|
|
47
|
+
// Pimlico-specific methods
|
|
48
|
+
"pimlico_getUserOperationGasPrice",
|
|
49
|
+
"pimlico_getUserOperationStatus",
|
|
50
|
+
"pimlico_sendCompressedUserOperation",
|
|
51
|
+
// pm_ paymaster methods (used by some bundlers)
|
|
52
|
+
"pm_getPaymasterData",
|
|
53
|
+
"pm_getPaymasterStubData",
|
|
54
|
+
"pm_sponsorUserOperation",
|
|
55
|
+
"pm_validateSponsorshipPolicies",
|
|
56
|
+
]);
|
|
57
|
+
/**
|
|
58
|
+
* Creates a transport that routes requests between a public RPC and a bundler RPC.
|
|
59
|
+
*
|
|
60
|
+
* Bundler-specific methods (ERC-4337) are routed to the bundler transport,
|
|
61
|
+
* while all other methods (eth_getBlockByNumber, eth_call, etc.) are routed
|
|
62
|
+
* to the public transport.
|
|
63
|
+
*
|
|
64
|
+
* @param publicTransport - Transport for standard Ethereum RPC calls
|
|
65
|
+
* @param bundlerTransport - Transport for ERC-4337 bundler calls
|
|
66
|
+
* @returns A unified transport that routes requests appropriately
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* import { http } from 'viem';
|
|
70
|
+
* import { createRoutedTransport } from '@mentaproject/core/utils';
|
|
71
|
+
*
|
|
72
|
+
* const transport = createRoutedTransport(
|
|
73
|
+
* http('https://eth-mainnet.g.alchemy.com/v2/...'),
|
|
74
|
+
* http('https://api.pimlico.io/v2/1/rpc?apikey=...')
|
|
75
|
+
* );
|
|
76
|
+
*/
|
|
77
|
+
function createRoutedTransport(publicTransport, bundlerTransport) {
|
|
78
|
+
return (params) => {
|
|
79
|
+
const publicClient = publicTransport(params);
|
|
80
|
+
const bundlerClient = bundlerTransport(params);
|
|
81
|
+
const request = async ({ method, params: reqParams }) => {
|
|
82
|
+
if (BUNDLER_METHODS.has(method)) {
|
|
83
|
+
return bundlerClient.request({ method, params: reqParams });
|
|
84
|
+
}
|
|
85
|
+
return publicClient.request({ method, params: reqParams });
|
|
86
|
+
};
|
|
87
|
+
return {
|
|
88
|
+
...publicClient,
|
|
89
|
+
request,
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
36
94
|
exports.bytes32ToAddress = bytes32ToAddress;
|
|
37
95
|
exports.bytesToAddress = bytesToAddress;
|
|
96
|
+
exports.createRoutedTransport = createRoutedTransport;
|
|
38
97
|
exports.nonZeroAddress = nonZeroAddress;
|
|
39
98
|
Object.keys(utils).forEach(function (k) {
|
|
40
99
|
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
package/dist/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/utils/bytesToAddress.ts","../../src/utils/nonZeroAddress.ts"],"sourcesContent":["import { getAddress, slice } from \".\";\nimport { Address, Hex } from \"../types\";\n\n/**\n * Helper function to convert a bytes value to an address.\n * @param bytes The bytes value to convert.\n * @param startByteIndex The index of the first byte to extract from the bytes value.\n * @returns The address or undefined if the conversion failed.\n */\nexport const bytesToAddress = (bytes: Hex, startByteIndex: number): Address => {\n if (startByteIndex < 0) throw new Error(`startByteIndex must be greater than or equal to 0, got ${startByteIndex}`);\n if (!bytes || bytes.length < startByteIndex + 20) throw new Error(`Bytes value must be at least ${startByteIndex + 20} characters long, got ${bytes?.length ?? 0}`);\n\n // Extracts 20 bytes starting from startByteIndex\n const addressBytes = slice(bytes, startByteIndex, startByteIndex + 20);\n\n if (addressBytes.length !== 42) throw new Error(`Address bytes must be 42 characters long, got ${addressBytes.length}`);\n return getAddress(addressBytes);\n};\n\n/**\n * Helper function to convert a bytes32 value to an address.\n * @param bytes The bytes32 value to convert.\n * @returns The address or undefined if the conversion failed.\n */\nexport const bytes32ToAddress = (bytes: Hex): Address => {\n if (!bytes || bytes.length !== 66) throw new Error(`Bytes32 value must be 66 characters long, got ${bytes?.length ?? 0}`);\n\n return bytesToAddress(bytes, 12);\n};","import { zeroAddress } from \"..\";\nimport { Address } from \"../types\";\n\nexport const nonZeroAddress = (address: Address): Address | undefined => address === zeroAddress ? undefined : address;"],"names":["slice","getAddress","zeroAddress"],"mappings":";;;;;AAGA;;;;;AAKG;MACU,cAAc,GAAG,CAAC,KAAU,EAAE,cAAsB,KAAa;IAC1E,IAAI,cAAc,GAAG,CAAC;AAAE,QAAA,MAAM,IAAI,KAAK,CAAC,0DAA0D,cAAc,CAAA,CAAE,CAAC;IACnH,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,cAAc,GAAG,EAAE;AAAE,QAAA,MAAM,IAAI,KAAK,CAAC,CAAA,6BAAA,EAAgC,cAAc,GAAG,EAAE,CAAA,sBAAA,EAAyB,KAAK,EAAE,MAAM,IAAI,CAAC,CAAA,CAAE,CAAC;;AAGnK,IAAA,MAAM,YAAY,GAAGA,WAAK,CAAC,KAAK,EAAE,cAAc,EAAE,cAAc,GAAG,EAAE,CAAC;AAEtE,IAAA,IAAI,YAAY,CAAC,MAAM,KAAK,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,CAAA,8CAAA,EAAiD,YAAY,CAAC,MAAM,CAAA,CAAE,CAAC;AACvH,IAAA,OAAOC,gBAAU,CAAC,YAAY,CAAC;AACnC;AAEA;;;;AAIG;AACI,MAAM,gBAAgB,GAAG,CAAC,KAAU,KAAa;AACpD,IAAA,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,CAAA,8CAAA,EAAiD,KAAK,EAAE,MAAM,IAAI,CAAC,CAAA,CAAE,CAAC;AAEzH,IAAA,OAAO,cAAc,CAAC,KAAK,EAAE,EAAE,CAAC;AACpC;;MC1Ba,cAAc,GAAG,CAAC,OAAgB,KAA0B,OAAO,KAAKC,gBAAW,GAAG,SAAS,GAAG
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/utils/bytesToAddress.ts","../../src/utils/nonZeroAddress.ts","../../src/utils/createRoutedTransport.ts"],"sourcesContent":["import { getAddress, slice } from \".\";\nimport { Address, Hex } from \"../types\";\n\n/**\n * Helper function to convert a bytes value to an address.\n * @param bytes The bytes value to convert.\n * @param startByteIndex The index of the first byte to extract from the bytes value.\n * @returns The address or undefined if the conversion failed.\n */\nexport const bytesToAddress = (bytes: Hex, startByteIndex: number): Address => {\n if (startByteIndex < 0) throw new Error(`startByteIndex must be greater than or equal to 0, got ${startByteIndex}`);\n if (!bytes || bytes.length < startByteIndex + 20) throw new Error(`Bytes value must be at least ${startByteIndex + 20} characters long, got ${bytes?.length ?? 0}`);\n\n // Extracts 20 bytes starting from startByteIndex\n const addressBytes = slice(bytes, startByteIndex, startByteIndex + 20);\n\n if (addressBytes.length !== 42) throw new Error(`Address bytes must be 42 characters long, got ${addressBytes.length}`);\n return getAddress(addressBytes);\n};\n\n/**\n * Helper function to convert a bytes32 value to an address.\n * @param bytes The bytes32 value to convert.\n * @returns The address or undefined if the conversion failed.\n */\nexport const bytes32ToAddress = (bytes: Hex): Address => {\n if (!bytes || bytes.length !== 66) throw new Error(`Bytes32 value must be 66 characters long, got ${bytes?.length ?? 0}`);\n\n return bytesToAddress(bytes, 12);\n};","import { zeroAddress } from \"..\";\nimport { Address } from \"../types\";\n\nexport const nonZeroAddress = (address: Address): Address | undefined => address === zeroAddress ? undefined : address;","import type { EIP1193RequestFn, Transport } from \"viem\";\n\n/**\n * RPC methods that should be routed to the bundler.\n * All other methods will be routed to the public RPC.\n */\nconst BUNDLER_METHODS = new Set([\n // ERC-4337 standard methods\n \"eth_sendUserOperation\",\n \"eth_estimateUserOperationGas\",\n \"eth_getUserOperationByHash\",\n \"eth_getUserOperationReceipt\",\n \"eth_supportedEntryPoints\",\n // Pimlico-specific methods\n \"pimlico_getUserOperationGasPrice\",\n \"pimlico_getUserOperationStatus\",\n \"pimlico_sendCompressedUserOperation\",\n // pm_ paymaster methods (used by some bundlers)\n \"pm_getPaymasterData\",\n \"pm_getPaymasterStubData\",\n \"pm_sponsorUserOperation\",\n \"pm_validateSponsorshipPolicies\",\n]);\n\n/**\n * Creates a transport that routes requests between a public RPC and a bundler RPC.\n *\n * Bundler-specific methods (ERC-4337) are routed to the bundler transport,\n * while all other methods (eth_getBlockByNumber, eth_call, etc.) are routed\n * to the public transport.\n *\n * @param publicTransport - Transport for standard Ethereum RPC calls\n * @param bundlerTransport - Transport for ERC-4337 bundler calls\n * @returns A unified transport that routes requests appropriately\n *\n * @example\n * import { http } from 'viem';\n * import { createRoutedTransport } from '@mentaproject/core/utils';\n *\n * const transport = createRoutedTransport(\n * http('https://eth-mainnet.g.alchemy.com/v2/...'),\n * http('https://api.pimlico.io/v2/1/rpc?apikey=...')\n * );\n */\nexport function createRoutedTransport(\n publicTransport: Transport,\n bundlerTransport: Transport,\n): Transport {\n return (params) => {\n const publicClient = publicTransport(params);\n const bundlerClient = bundlerTransport(params);\n\n const request: EIP1193RequestFn = async ({ method, params: reqParams }) => {\n if (BUNDLER_METHODS.has(method)) {\n return bundlerClient.request({ method, params: reqParams } as any);\n }\n return publicClient.request({ method, params: reqParams } as any);\n };\n\n return {\n ...publicClient,\n request,\n };\n };\n}\n"],"names":["slice","getAddress","zeroAddress"],"mappings":";;;;;AAGA;;;;;AAKG;MACU,cAAc,GAAG,CAAC,KAAU,EAAE,cAAsB,KAAa;IAC1E,IAAI,cAAc,GAAG,CAAC;AAAE,QAAA,MAAM,IAAI,KAAK,CAAC,0DAA0D,cAAc,CAAA,CAAE,CAAC;IACnH,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,cAAc,GAAG,EAAE;AAAE,QAAA,MAAM,IAAI,KAAK,CAAC,CAAA,6BAAA,EAAgC,cAAc,GAAG,EAAE,CAAA,sBAAA,EAAyB,KAAK,EAAE,MAAM,IAAI,CAAC,CAAA,CAAE,CAAC;;AAGnK,IAAA,MAAM,YAAY,GAAGA,WAAK,CAAC,KAAK,EAAE,cAAc,EAAE,cAAc,GAAG,EAAE,CAAC;AAEtE,IAAA,IAAI,YAAY,CAAC,MAAM,KAAK,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,CAAA,8CAAA,EAAiD,YAAY,CAAC,MAAM,CAAA,CAAE,CAAC;AACvH,IAAA,OAAOC,gBAAU,CAAC,YAAY,CAAC;AACnC;AAEA;;;;AAIG;AACI,MAAM,gBAAgB,GAAG,CAAC,KAAU,KAAa;AACpD,IAAA,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,CAAA,8CAAA,EAAiD,KAAK,EAAE,MAAM,IAAI,CAAC,CAAA,CAAE,CAAC;AAEzH,IAAA,OAAO,cAAc,CAAC,KAAK,EAAE,EAAE,CAAC;AACpC;;MC1Ba,cAAc,GAAG,CAAC,OAAgB,KAA0B,OAAO,KAAKC,gBAAW,GAAG,SAAS,GAAG;;ACD/G;;;AAGG;AACH,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC;;IAE9B,uBAAuB;IACvB,8BAA8B;IAC9B,4BAA4B;IAC5B,6BAA6B;IAC7B,0BAA0B;;IAE1B,kCAAkC;IAClC,gCAAgC;IAChC,qCAAqC;;IAErC,qBAAqB;IACrB,yBAAyB;IACzB,yBAAyB;IACzB,gCAAgC;AACjC,CAAA,CAAC;AAEF;;;;;;;;;;;;;;;;;;;AAmBG;AACG,SAAU,qBAAqB,CACnC,eAA0B,EAC1B,gBAA2B,EAAA;IAE3B,OAAO,CAAC,MAAM,KAAI;AAChB,QAAA,MAAM,YAAY,GAAG,eAAe,CAAC,MAAM,CAAC;AAC5C,QAAA,MAAM,aAAa,GAAG,gBAAgB,CAAC,MAAM,CAAC;AAE9C,QAAA,MAAM,OAAO,GAAqB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,KAAI;AACxE,YAAA,IAAI,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;AAC/B,gBAAA,OAAO,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAS,CAAC;YACpE;AACA,YAAA,OAAO,YAAY,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAS,CAAC;AACnE,QAAA,CAAC;QAED,OAAO;AACL,YAAA,GAAG,YAAY;YACf,OAAO;SACR;AACH,IAAA,CAAC;AACH;;;;;;;;;;;;;"}
|
package/dist/utils/index.mjs
CHANGED
|
@@ -32,5 +32,63 @@ const bytes32ToAddress = (bytes) => {
|
|
|
32
32
|
|
|
33
33
|
const nonZeroAddress = (address) => address === zeroAddress ? undefined : address;
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
/**
|
|
36
|
+
* RPC methods that should be routed to the bundler.
|
|
37
|
+
* All other methods will be routed to the public RPC.
|
|
38
|
+
*/
|
|
39
|
+
const BUNDLER_METHODS = new Set([
|
|
40
|
+
// ERC-4337 standard methods
|
|
41
|
+
"eth_sendUserOperation",
|
|
42
|
+
"eth_estimateUserOperationGas",
|
|
43
|
+
"eth_getUserOperationByHash",
|
|
44
|
+
"eth_getUserOperationReceipt",
|
|
45
|
+
"eth_supportedEntryPoints",
|
|
46
|
+
// Pimlico-specific methods
|
|
47
|
+
"pimlico_getUserOperationGasPrice",
|
|
48
|
+
"pimlico_getUserOperationStatus",
|
|
49
|
+
"pimlico_sendCompressedUserOperation",
|
|
50
|
+
// pm_ paymaster methods (used by some bundlers)
|
|
51
|
+
"pm_getPaymasterData",
|
|
52
|
+
"pm_getPaymasterStubData",
|
|
53
|
+
"pm_sponsorUserOperation",
|
|
54
|
+
"pm_validateSponsorshipPolicies",
|
|
55
|
+
]);
|
|
56
|
+
/**
|
|
57
|
+
* Creates a transport that routes requests between a public RPC and a bundler RPC.
|
|
58
|
+
*
|
|
59
|
+
* Bundler-specific methods (ERC-4337) are routed to the bundler transport,
|
|
60
|
+
* while all other methods (eth_getBlockByNumber, eth_call, etc.) are routed
|
|
61
|
+
* to the public transport.
|
|
62
|
+
*
|
|
63
|
+
* @param publicTransport - Transport for standard Ethereum RPC calls
|
|
64
|
+
* @param bundlerTransport - Transport for ERC-4337 bundler calls
|
|
65
|
+
* @returns A unified transport that routes requests appropriately
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* import { http } from 'viem';
|
|
69
|
+
* import { createRoutedTransport } from '@mentaproject/core/utils';
|
|
70
|
+
*
|
|
71
|
+
* const transport = createRoutedTransport(
|
|
72
|
+
* http('https://eth-mainnet.g.alchemy.com/v2/...'),
|
|
73
|
+
* http('https://api.pimlico.io/v2/1/rpc?apikey=...')
|
|
74
|
+
* );
|
|
75
|
+
*/
|
|
76
|
+
function createRoutedTransport(publicTransport, bundlerTransport) {
|
|
77
|
+
return (params) => {
|
|
78
|
+
const publicClient = publicTransport(params);
|
|
79
|
+
const bundlerClient = bundlerTransport(params);
|
|
80
|
+
const request = async ({ method, params: reqParams }) => {
|
|
81
|
+
if (BUNDLER_METHODS.has(method)) {
|
|
82
|
+
return bundlerClient.request({ method, params: reqParams });
|
|
83
|
+
}
|
|
84
|
+
return publicClient.request({ method, params: reqParams });
|
|
85
|
+
};
|
|
86
|
+
return {
|
|
87
|
+
...publicClient,
|
|
88
|
+
request,
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export { bytes32ToAddress, bytesToAddress, createRoutedTransport, nonZeroAddress };
|
|
36
94
|
//# sourceMappingURL=index.mjs.map
|
package/dist/utils/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../../src/utils/bytesToAddress.ts","../../src/utils/nonZeroAddress.ts"],"sourcesContent":["import { getAddress, slice } from \".\";\nimport { Address, Hex } from \"../types\";\n\n/**\n * Helper function to convert a bytes value to an address.\n * @param bytes The bytes value to convert.\n * @param startByteIndex The index of the first byte to extract from the bytes value.\n * @returns The address or undefined if the conversion failed.\n */\nexport const bytesToAddress = (bytes: Hex, startByteIndex: number): Address => {\n if (startByteIndex < 0) throw new Error(`startByteIndex must be greater than or equal to 0, got ${startByteIndex}`);\n if (!bytes || bytes.length < startByteIndex + 20) throw new Error(`Bytes value must be at least ${startByteIndex + 20} characters long, got ${bytes?.length ?? 0}`);\n\n // Extracts 20 bytes starting from startByteIndex\n const addressBytes = slice(bytes, startByteIndex, startByteIndex + 20);\n\n if (addressBytes.length !== 42) throw new Error(`Address bytes must be 42 characters long, got ${addressBytes.length}`);\n return getAddress(addressBytes);\n};\n\n/**\n * Helper function to convert a bytes32 value to an address.\n * @param bytes The bytes32 value to convert.\n * @returns The address or undefined if the conversion failed.\n */\nexport const bytes32ToAddress = (bytes: Hex): Address => {\n if (!bytes || bytes.length !== 66) throw new Error(`Bytes32 value must be 66 characters long, got ${bytes?.length ?? 0}`);\n\n return bytesToAddress(bytes, 12);\n};","import { zeroAddress } from \"..\";\nimport { Address } from \"../types\";\n\nexport const nonZeroAddress = (address: Address): Address | undefined => address === zeroAddress ? undefined : address;"],"names":[],"mappings":";;;;AAGA;;;;;AAKG;MACU,cAAc,GAAG,CAAC,KAAU,EAAE,cAAsB,KAAa;IAC1E,IAAI,cAAc,GAAG,CAAC;AAAE,QAAA,MAAM,IAAI,KAAK,CAAC,0DAA0D,cAAc,CAAA,CAAE,CAAC;IACnH,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,cAAc,GAAG,EAAE;AAAE,QAAA,MAAM,IAAI,KAAK,CAAC,CAAA,6BAAA,EAAgC,cAAc,GAAG,EAAE,CAAA,sBAAA,EAAyB,KAAK,EAAE,MAAM,IAAI,CAAC,CAAA,CAAE,CAAC;;AAGnK,IAAA,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK,EAAE,cAAc,EAAE,cAAc,GAAG,EAAE,CAAC;AAEtE,IAAA,IAAI,YAAY,CAAC,MAAM,KAAK,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,CAAA,8CAAA,EAAiD,YAAY,CAAC,MAAM,CAAA,CAAE,CAAC;AACvH,IAAA,OAAO,UAAU,CAAC,YAAY,CAAC;AACnC;AAEA;;;;AAIG;AACI,MAAM,gBAAgB,GAAG,CAAC,KAAU,KAAa;AACpD,IAAA,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,CAAA,8CAAA,EAAiD,KAAK,EAAE,MAAM,IAAI,CAAC,CAAA,CAAE,CAAC;AAEzH,IAAA,OAAO,cAAc,CAAC,KAAK,EAAE,EAAE,CAAC;AACpC;;MC1Ba,cAAc,GAAG,CAAC,OAAgB,KAA0B,OAAO,KAAK,WAAW,GAAG,SAAS,GAAG;;;;"}
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../../src/utils/bytesToAddress.ts","../../src/utils/nonZeroAddress.ts","../../src/utils/createRoutedTransport.ts"],"sourcesContent":["import { getAddress, slice } from \".\";\nimport { Address, Hex } from \"../types\";\n\n/**\n * Helper function to convert a bytes value to an address.\n * @param bytes The bytes value to convert.\n * @param startByteIndex The index of the first byte to extract from the bytes value.\n * @returns The address or undefined if the conversion failed.\n */\nexport const bytesToAddress = (bytes: Hex, startByteIndex: number): Address => {\n if (startByteIndex < 0) throw new Error(`startByteIndex must be greater than or equal to 0, got ${startByteIndex}`);\n if (!bytes || bytes.length < startByteIndex + 20) throw new Error(`Bytes value must be at least ${startByteIndex + 20} characters long, got ${bytes?.length ?? 0}`);\n\n // Extracts 20 bytes starting from startByteIndex\n const addressBytes = slice(bytes, startByteIndex, startByteIndex + 20);\n\n if (addressBytes.length !== 42) throw new Error(`Address bytes must be 42 characters long, got ${addressBytes.length}`);\n return getAddress(addressBytes);\n};\n\n/**\n * Helper function to convert a bytes32 value to an address.\n * @param bytes The bytes32 value to convert.\n * @returns The address or undefined if the conversion failed.\n */\nexport const bytes32ToAddress = (bytes: Hex): Address => {\n if (!bytes || bytes.length !== 66) throw new Error(`Bytes32 value must be 66 characters long, got ${bytes?.length ?? 0}`);\n\n return bytesToAddress(bytes, 12);\n};","import { zeroAddress } from \"..\";\nimport { Address } from \"../types\";\n\nexport const nonZeroAddress = (address: Address): Address | undefined => address === zeroAddress ? undefined : address;","import type { EIP1193RequestFn, Transport } from \"viem\";\n\n/**\n * RPC methods that should be routed to the bundler.\n * All other methods will be routed to the public RPC.\n */\nconst BUNDLER_METHODS = new Set([\n // ERC-4337 standard methods\n \"eth_sendUserOperation\",\n \"eth_estimateUserOperationGas\",\n \"eth_getUserOperationByHash\",\n \"eth_getUserOperationReceipt\",\n \"eth_supportedEntryPoints\",\n // Pimlico-specific methods\n \"pimlico_getUserOperationGasPrice\",\n \"pimlico_getUserOperationStatus\",\n \"pimlico_sendCompressedUserOperation\",\n // pm_ paymaster methods (used by some bundlers)\n \"pm_getPaymasterData\",\n \"pm_getPaymasterStubData\",\n \"pm_sponsorUserOperation\",\n \"pm_validateSponsorshipPolicies\",\n]);\n\n/**\n * Creates a transport that routes requests between a public RPC and a bundler RPC.\n *\n * Bundler-specific methods (ERC-4337) are routed to the bundler transport,\n * while all other methods (eth_getBlockByNumber, eth_call, etc.) are routed\n * to the public transport.\n *\n * @param publicTransport - Transport for standard Ethereum RPC calls\n * @param bundlerTransport - Transport for ERC-4337 bundler calls\n * @returns A unified transport that routes requests appropriately\n *\n * @example\n * import { http } from 'viem';\n * import { createRoutedTransport } from '@mentaproject/core/utils';\n *\n * const transport = createRoutedTransport(\n * http('https://eth-mainnet.g.alchemy.com/v2/...'),\n * http('https://api.pimlico.io/v2/1/rpc?apikey=...')\n * );\n */\nexport function createRoutedTransport(\n publicTransport: Transport,\n bundlerTransport: Transport,\n): Transport {\n return (params) => {\n const publicClient = publicTransport(params);\n const bundlerClient = bundlerTransport(params);\n\n const request: EIP1193RequestFn = async ({ method, params: reqParams }) => {\n if (BUNDLER_METHODS.has(method)) {\n return bundlerClient.request({ method, params: reqParams } as any);\n }\n return publicClient.request({ method, params: reqParams } as any);\n };\n\n return {\n ...publicClient,\n request,\n };\n };\n}\n"],"names":[],"mappings":";;;;AAGA;;;;;AAKG;MACU,cAAc,GAAG,CAAC,KAAU,EAAE,cAAsB,KAAa;IAC1E,IAAI,cAAc,GAAG,CAAC;AAAE,QAAA,MAAM,IAAI,KAAK,CAAC,0DAA0D,cAAc,CAAA,CAAE,CAAC;IACnH,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,cAAc,GAAG,EAAE;AAAE,QAAA,MAAM,IAAI,KAAK,CAAC,CAAA,6BAAA,EAAgC,cAAc,GAAG,EAAE,CAAA,sBAAA,EAAyB,KAAK,EAAE,MAAM,IAAI,CAAC,CAAA,CAAE,CAAC;;AAGnK,IAAA,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK,EAAE,cAAc,EAAE,cAAc,GAAG,EAAE,CAAC;AAEtE,IAAA,IAAI,YAAY,CAAC,MAAM,KAAK,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,CAAA,8CAAA,EAAiD,YAAY,CAAC,MAAM,CAAA,CAAE,CAAC;AACvH,IAAA,OAAO,UAAU,CAAC,YAAY,CAAC;AACnC;AAEA;;;;AAIG;AACI,MAAM,gBAAgB,GAAG,CAAC,KAAU,KAAa;AACpD,IAAA,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,CAAA,8CAAA,EAAiD,KAAK,EAAE,MAAM,IAAI,CAAC,CAAA,CAAE,CAAC;AAEzH,IAAA,OAAO,cAAc,CAAC,KAAK,EAAE,EAAE,CAAC;AACpC;;MC1Ba,cAAc,GAAG,CAAC,OAAgB,KAA0B,OAAO,KAAK,WAAW,GAAG,SAAS,GAAG;;ACD/G;;;AAGG;AACH,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC;;IAE9B,uBAAuB;IACvB,8BAA8B;IAC9B,4BAA4B;IAC5B,6BAA6B;IAC7B,0BAA0B;;IAE1B,kCAAkC;IAClC,gCAAgC;IAChC,qCAAqC;;IAErC,qBAAqB;IACrB,yBAAyB;IACzB,yBAAyB;IACzB,gCAAgC;AACjC,CAAA,CAAC;AAEF;;;;;;;;;;;;;;;;;;;AAmBG;AACG,SAAU,qBAAqB,CACnC,eAA0B,EAC1B,gBAA2B,EAAA;IAE3B,OAAO,CAAC,MAAM,KAAI;AAChB,QAAA,MAAM,YAAY,GAAG,eAAe,CAAC,MAAM,CAAC;AAC5C,QAAA,MAAM,aAAa,GAAG,gBAAgB,CAAC,MAAM,CAAC;AAE9C,QAAA,MAAM,OAAO,GAAqB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,KAAI;AACxE,YAAA,IAAI,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;AAC/B,gBAAA,OAAO,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAS,CAAC;YACpE;AACA,YAAA,OAAO,YAAY,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAS,CAAC;AACnE,QAAA,CAAC;QAED,OAAO;AACL,YAAA,GAAG,YAAY;YACf,OAAO;SACR;AACH,IAAA,CAAC;AACH;;;;"}
|
package/package.json
CHANGED
|
@@ -7,6 +7,7 @@ import { entryPoint07Address } from "../account-abstraction";
|
|
|
7
7
|
import { toKernelSmartAccount } from "permissionless/accounts";
|
|
8
8
|
import { createSmartAccountClient } from "permissionless";
|
|
9
9
|
import { erc7579Actions } from "permissionless/actions/erc7579";
|
|
10
|
+
import { createRoutedTransport } from "../utils/createRoutedTransport";
|
|
10
11
|
import type {
|
|
11
12
|
Client,
|
|
12
13
|
Transport,
|
|
@@ -34,8 +35,15 @@ export async function createMentaAccount<TChain extends Chain | undefined>(
|
|
|
34
35
|
client: client,
|
|
35
36
|
});
|
|
36
37
|
|
|
38
|
+
// Create a routed transport that sends bundler methods to the bundler
|
|
39
|
+
// and all other RPC calls to the public transport
|
|
40
|
+
const routedTransport = createRoutedTransport(
|
|
41
|
+
params.publicTransport,
|
|
42
|
+
params.bundlerTransport,
|
|
43
|
+
);
|
|
44
|
+
|
|
37
45
|
return createSmartAccountClient({
|
|
38
46
|
account: kernel,
|
|
39
|
-
bundlerTransport:
|
|
47
|
+
bundlerTransport: routedTransport,
|
|
40
48
|
}).extend(erc7579Actions());
|
|
41
49
|
}
|
package/src/types/CoreClient.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type{ RenameProperty } from './Utils';
|
|
1
|
+
import type { RenameProperty } from './Utils';
|
|
2
2
|
import type { Transport, Chain } from './';
|
|
3
3
|
|
|
4
4
|
import type { Client as ViemClient } from 'viem';
|
|
@@ -14,8 +14,20 @@ export type PermissionlessClientProperties<
|
|
|
14
14
|
userOperation: BundlerClientConfig["userOperation"] | undefined
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
* A basic viem Client used for standard RPC operations.
|
|
19
|
+
* This is the type returned by createClient before smart account setup.
|
|
20
|
+
*/
|
|
17
21
|
export type CoreClient<
|
|
18
22
|
TChain extends Chain | undefined = Chain | undefined,
|
|
23
|
+
> = ViemClient<Transport, TChain>;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* A SmartAccountClient with permissionless properties.
|
|
27
|
+
* This is the type returned after setting up the smart account.
|
|
28
|
+
*/
|
|
29
|
+
export type SmartAccountCoreClient<
|
|
30
|
+
TChain extends Chain | undefined = Chain | undefined,
|
|
19
31
|
TAccount extends SmartAccount | undefined = SmartAccount | undefined,
|
|
20
32
|
> = ViemClient<Transport, TChain, TAccount> & PermissionlessClientProperties;
|
|
21
33
|
|
|
@@ -12,7 +12,10 @@ export interface PasskeySigner extends LocalAccount {
|
|
|
12
12
|
|
|
13
13
|
export interface MentaAccountParams {
|
|
14
14
|
signer: PasskeySigner;
|
|
15
|
+
/** Transport for ERC-4337 bundler calls */
|
|
15
16
|
bundlerTransport: Transport;
|
|
17
|
+
/** Transport for standard Ethereum RPC calls (eth_getBlock, etc.) */
|
|
18
|
+
publicTransport: Transport;
|
|
16
19
|
}
|
|
17
20
|
|
|
18
21
|
export type MentaAccountClient = Awaited<ReturnType<typeof createMentaAccount>>;
|
package/src/types/index.ts
CHANGED
|
@@ -128,7 +128,7 @@ export type {
|
|
|
128
128
|
AbiParameterToPrimitiveType,
|
|
129
129
|
} from "abitype";
|
|
130
130
|
|
|
131
|
-
export type { CoreClient, CoreClientConfig } from "./CoreClient";
|
|
131
|
+
export type { CoreClient, SmartAccountCoreClient, CoreClientConfig } from "./CoreClient";
|
|
132
132
|
|
|
133
133
|
export {
|
|
134
134
|
TraceFilterParameters,
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { EIP1193RequestFn, Transport } from "viem";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* RPC methods that should be routed to the bundler.
|
|
5
|
+
* All other methods will be routed to the public RPC.
|
|
6
|
+
*/
|
|
7
|
+
const BUNDLER_METHODS = new Set([
|
|
8
|
+
// ERC-4337 standard methods
|
|
9
|
+
"eth_sendUserOperation",
|
|
10
|
+
"eth_estimateUserOperationGas",
|
|
11
|
+
"eth_getUserOperationByHash",
|
|
12
|
+
"eth_getUserOperationReceipt",
|
|
13
|
+
"eth_supportedEntryPoints",
|
|
14
|
+
// Pimlico-specific methods
|
|
15
|
+
"pimlico_getUserOperationGasPrice",
|
|
16
|
+
"pimlico_getUserOperationStatus",
|
|
17
|
+
"pimlico_sendCompressedUserOperation",
|
|
18
|
+
// pm_ paymaster methods (used by some bundlers)
|
|
19
|
+
"pm_getPaymasterData",
|
|
20
|
+
"pm_getPaymasterStubData",
|
|
21
|
+
"pm_sponsorUserOperation",
|
|
22
|
+
"pm_validateSponsorshipPolicies",
|
|
23
|
+
]);
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Creates a transport that routes requests between a public RPC and a bundler RPC.
|
|
27
|
+
*
|
|
28
|
+
* Bundler-specific methods (ERC-4337) are routed to the bundler transport,
|
|
29
|
+
* while all other methods (eth_getBlockByNumber, eth_call, etc.) are routed
|
|
30
|
+
* to the public transport.
|
|
31
|
+
*
|
|
32
|
+
* @param publicTransport - Transport for standard Ethereum RPC calls
|
|
33
|
+
* @param bundlerTransport - Transport for ERC-4337 bundler calls
|
|
34
|
+
* @returns A unified transport that routes requests appropriately
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* import { http } from 'viem';
|
|
38
|
+
* import { createRoutedTransport } from '@mentaproject/core/utils';
|
|
39
|
+
*
|
|
40
|
+
* const transport = createRoutedTransport(
|
|
41
|
+
* http('https://eth-mainnet.g.alchemy.com/v2/...'),
|
|
42
|
+
* http('https://api.pimlico.io/v2/1/rpc?apikey=...')
|
|
43
|
+
* );
|
|
44
|
+
*/
|
|
45
|
+
export function createRoutedTransport(
|
|
46
|
+
publicTransport: Transport,
|
|
47
|
+
bundlerTransport: Transport,
|
|
48
|
+
): Transport {
|
|
49
|
+
return (params) => {
|
|
50
|
+
const publicClient = publicTransport(params);
|
|
51
|
+
const bundlerClient = bundlerTransport(params);
|
|
52
|
+
|
|
53
|
+
const request: EIP1193RequestFn = async ({ method, params: reqParams }) => {
|
|
54
|
+
if (BUNDLER_METHODS.has(method)) {
|
|
55
|
+
return bundlerClient.request({ method, params: reqParams } as any);
|
|
56
|
+
}
|
|
57
|
+
return publicClient.request({ method, params: reqParams } as any);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
...publicClient,
|
|
62
|
+
request,
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
}
|
package/src/utils/index.ts
CHANGED