@mentaproject/client 0.1.24 → 0.1.28

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.
@@ -1,16 +1,21 @@
1
1
  /**
2
2
  * @module MentaClient
3
3
  */
4
- import type { CoreClient } from "@mentaproject/core/types";
5
- import { createClient } from "@mentaproject/core";
4
+ import type { MentaAccountClient } from "@mentaproject/core/types";
5
+ import { createMentaAccount } from "@mentaproject/core/clients";
6
6
 
7
7
  import { BlockManager } from "../managers/BlockManager";
8
8
  import { TransactionManager } from "../managers/TransactionManager";
9
9
  import { ContractManager } from "../managers/ContractManager";
10
10
  import { AccountManager } from "../managers/AccountManager";
11
11
  import { PersistenceManager } from "../managers/PersistenceManager";
12
- import { ClientEvents, GetListenerCallback, MentaClientConfig } from "../types/MentaClient";
12
+ import {
13
+ ClientEvents,
14
+ GetListenerCallback,
15
+ MentaClientConfig,
16
+ } from "../types/MentaClient";
13
17
  import { withCache } from "../utils/withCache";
18
+ import { createClient } from "@mentaproject/core";
14
19
 
15
20
  /**
16
21
  * The main client for interacting with the Menta API.
@@ -21,107 +26,128 @@ import { withCache } from "../utils/withCache";
21
26
  * simplifying common operations.
22
27
  */
23
28
  export class MentaClient {
24
- /**
25
- * The underlying RPC client used for blockchain interactions.
26
- * @description This client is responsible for low-level communication with the RPC node.
27
- */
28
- public rpc: CoreClient;
29
+ protected _rpc?: MentaAccountClient;
30
+ /**
31
+ * The underlying RPC client used for blockchain interactions.
32
+ * @description This client is responsible for low-level communication with the RPC node.
33
+ */
34
+ public get rpc(): MentaAccountClient {
35
+ if (!this._rpc) {
36
+ throw new Error("RPC client not initialized");
37
+ }
38
+ return this._rpc;
39
+ }
29
40
 
30
- /**
31
- * Manager for block-related operations.
32
- * @description Provides methods to query and interact with blockchain blocks.
33
- */
34
- public blocks!: BlockManager;
35
- /**
36
- * Manager for transaction-related operations.
37
- * @description Provides methods to send, query, and manage blockchain transactions.
38
- */
39
- public transactions!: TransactionManager;
40
- /**
41
- * Manager for contract-related operations.
42
- * @description Provides methods to deploy, interact with, and query smart contracts.
43
- */
44
- public contracts!: ContractManager;
45
- /**
46
- * Manager for account-related operations.
47
- * @description Provides methods to manage and interact with blockchain accounts.
48
- */
49
- public accounts!: AccountManager;
41
+ /**
42
+ * Manager for block-related operations.
43
+ * @description Provides methods to query and interact with blockchain blocks.
44
+ */
45
+ public blocks!: BlockManager;
46
+ /**
47
+ * Manager for transaction-related operations.
48
+ * @description Provides methods to send, query, and manage blockchain transactions.
49
+ */
50
+ public transactions!: TransactionManager;
51
+ /**
52
+ * Manager for contract-related operations.
53
+ * @description Provides methods to deploy, interact with, and query smart contracts.
54
+ */
55
+ public contracts!: ContractManager;
56
+ /**
57
+ * Manager for account-related operations.
58
+ * @description Provides methods to manage and interact with blockchain accounts.
59
+ */
60
+ public accounts!: AccountManager;
50
61
 
51
- /**
52
- * Subscribes to a specific client event.
53
- * @template TEvent The type of the event to listen for.
54
- * @param {TEvent} event - The event to listen for (e.g., 'block', 'transaction').
55
- * @param {GetListenerCallback<TEvent>} callback - The callback function to execute when the event is triggered.
56
- * @returns {() => void} An unsubscribe function to stop listening to the event.
57
- * @description This method allows the client to listen for real-time events from the blockchain, such as new blocks or transactions.
58
- * @example
59
- * import { MentaClient } from '@mentaproject/client';
60
- *
61
- * const client = new MentaClient({ url: 'http://rpcurlhere.com' });
62
- *
63
- * // Subscribe to new blocks
64
- * const unsubscribe = client.on('block', (block) => {
65
- * console.log('New block received:', block);
66
- * });
67
- *
68
- * // To stop listening
69
- * // unsubscribe();
70
- */
71
- on<TEvent extends keyof typeof ClientEvents>(
72
- event: TEvent,
73
- callback: GetListenerCallback<TEvent>
74
- ) {
75
- const eventFunction = ClientEvents[event];
76
- const capitalizedEvent = event.charAt(0).toUpperCase() + event.slice(1);
77
- const params = {
78
- [`on${capitalizedEvent}`]: callback,
79
- pollingInterval: 1000,
80
- };
62
+ /**
63
+ * Subscribes to a specific client event.
64
+ * @template TEvent The type of the event to listen for.
65
+ * @param {TEvent} event - The event to listen for (e.g., 'block', 'transaction').
66
+ * @param {GetListenerCallback<TEvent>} callback - The callback function to execute when the event is triggered.
67
+ * @returns {() => void} An unsubscribe function to stop listening to the event.
68
+ * @description This method allows the client to listen for real-time events from the blockchain, such as new blocks or transactions.
69
+ * @example
70
+ * import { MentaClient } from '@mentaproject/client';
71
+ *
72
+ * const client = new MentaClient({ url: 'http://rpcurlhere.com' });
73
+ *
74
+ * // Subscribe to new blocks
75
+ * const unsubscribe = client.on('block', (block) => {
76
+ * console.log('New block received:', block);
77
+ * });
78
+ *
79
+ * // To stop listening
80
+ * // unsubscribe();
81
+ */
82
+ on<TEvent extends keyof typeof ClientEvents>(
83
+ event: TEvent,
84
+ callback: GetListenerCallback<TEvent>,
85
+ ) {
86
+ const eventFunction = ClientEvents[event];
87
+ const capitalizedEvent = event.charAt(0).toUpperCase() + event.slice(1);
88
+ const params = {
89
+ [`on${capitalizedEvent}`]: callback,
90
+ pollingInterval: 1000,
91
+ };
81
92
 
82
- return (eventFunction as any)(this.rpc, params);
93
+ return (eventFunction as any)(this.rpc, params);
94
+ }
95
+
96
+ /**
97
+ * Creates an instance of MentaClient.
98
+ * @param {MentaClientConfig} params - The configuration parameters for the client.
99
+ * @description The constructor initializes the RPC client and the various managers based on the provided configuration.
100
+ * It also applies caching and persistence if specified in the configuration.
101
+ * @example
102
+ * import { MentaClient } from '@mentaproject/client';
103
+ *
104
+ * // Basic initialization
105
+ * const client = new MentaClient({
106
+ * url: 'http://rpcurlhere.com',
107
+ * });
108
+ *
109
+ * // Initialization with a persistent cache
110
+ * const clientWithCache = new MentaClient({
111
+ * url: 'http://rpcurlhere.com',
112
+ * cache: {
113
+ * ttl: 60000, // 1 minute
114
+ * },
115
+ * });
116
+ */
117
+ constructor(protected params: MentaClientConfig) {
118
+ this.blocks = new BlockManager(this);
119
+ this.transactions = new TransactionManager(this);
120
+ this.contracts = new ContractManager(this);
121
+
122
+ if (params.persistenceAdapter) {
123
+ this.persistenceManager = new PersistenceManager(
124
+ this,
125
+ params.persistenceAdapter,
126
+ );
127
+ this.accounts = new AccountManager(this, this.persistenceManager);
128
+ } else {
129
+ this.accounts = new AccountManager(this);
83
130
  }
131
+ }
84
132
 
85
- /**
86
- * Creates an instance of MentaClient.
87
- * @param {MentaClientConfig} params - The configuration parameters for the client.
88
- * @description The constructor initializes the RPC client and the various managers based on the provided configuration.
89
- * It also applies caching and persistence if specified in the configuration.
90
- * @example
91
- * import { MentaClient } from '@mentaproject/client';
92
- *
93
- * // Basic initialization
94
- * const client = new MentaClient({
95
- * url: 'http://rpcurlhere.com',
96
- * });
97
- *
98
- * // Initialization with a persistent cache
99
- * const clientWithCache = new MentaClient({
100
- * url: 'http://rpcurlhere.com',
101
- * cache: {
102
- * ttl: 60000, // 1 minute
103
- * },
104
- * });
105
- */
106
- constructor(params: MentaClientConfig) {
107
- this.rpc = createClient(params) as CoreClient;
108
- if (params.cache) this.rpc = withCache(this.rpc, params.cache);
133
+ async init() {
134
+ let coreClient = createClient(this.params);
109
135
 
110
- this.blocks = new BlockManager(this);
111
- this.transactions = new TransactionManager(this);
112
- this.contracts = new ContractManager(this);
113
- if (params.persistenceAdapter) {
114
- this.persistenceManager = new PersistenceManager(this, params.persistenceAdapter);
115
- this.accounts = new AccountManager(this, this.persistenceManager);
116
- } else {
117
- this.accounts = new AccountManager(this);
118
- }
136
+ if (this.params.cache) {
137
+ coreClient = withCache(coreClient, this.params.cache);
119
138
  }
120
139
 
121
- /**
122
- * Optional manager for persistence-related operations.
123
- * @description This manager is initialized if a persistence adapter is provided in the client configuration,
124
- * allowing for data storage and retrieval.
125
- */
126
- public persistenceManager?: PersistenceManager;
127
- }
140
+ this._rpc = await createMentaAccount(coreClient, {
141
+ signer: this.params.signer,
142
+ bundlerTransport: this.params.bundlerTransport,
143
+ publicTransport: this.params.transport,
144
+ });
145
+ }
146
+
147
+ /**
148
+ * Optional manager for persistence-related operations.
149
+ * @description This manager is initialized if a persistence adapter is provided in the client configuration,
150
+ * allowing for data storage and retrieval.
151
+ */
152
+ public persistenceManager?: PersistenceManager;
153
+ }
@@ -1,7 +1,11 @@
1
1
  /**
2
2
  * @module MentaClientTypes
3
3
  */
4
- import { CoreClientConfig } from "@mentaproject/core/types";
4
+ import {
5
+ CoreClientConfig,
6
+ PasskeySigner,
7
+ Transport,
8
+ } from "@mentaproject/core/types";
5
9
  import { ICache } from "./Cache";
6
10
  import { watchBlockNumber, watchBlocks } from "@mentaproject/core/actions";
7
11
  import { IPersistenceAdapter } from "./PersistenceAdapter";
@@ -11,13 +15,13 @@ import { IPersistenceAdapter } from "./PersistenceAdapter";
11
15
  * @interface CacheConfig
12
16
  */
13
17
  export interface CacheConfig {
14
- /**
15
- * Time-to-live policies for different RPC methods.
16
- * Keys are RPC method names (e.g., "eth_getBlockByNumber"), and values are
17
- * the TTL in milliseconds for caching responses from those methods.
18
- */
19
- ttl_policies: Record<string, number>;
20
- };
18
+ /**
19
+ * Time-to-live policies for different RPC methods.
20
+ * Keys are RPC method names (e.g., "eth_getBlockByNumber"), and values are
21
+ * the TTL in milliseconds for caching responses from those methods.
22
+ */
23
+ ttl_policies: Record<string, number>;
24
+ }
21
25
 
22
26
  /**
23
27
  * Configuration options for the MentaClient.
@@ -25,33 +29,41 @@ export interface CacheConfig {
25
29
  * @interface MentaClientConfig
26
30
  */
27
31
  export interface MentaClientConfig extends CoreClientConfig {
28
- /**
29
- * Optional cache implementation for the client.
30
- * If provided, the client will use this cache for RPC responses.
31
- */
32
- cache?: ICache;
33
- /**
34
- * Optional persistence adapter for local data storage.
35
- * If provided, the client will use this adapter to persist and retrieve data.
36
- */
37
- persistenceAdapter?: IPersistenceAdapter;
38
- };
32
+ /**
33
+ * Optional cache implementation for the client.
34
+ * If provided, the client will use this cache for RPC responses.
35
+ */
36
+ cache?: ICache;
37
+ /**
38
+ * Optional persistence adapter for local data storage.
39
+ * If provided, the client will use this adapter to persist and retrieve data.
40
+ */
41
+ persistenceAdapter?: IPersistenceAdapter;
42
+ /**
43
+ * Bundler transport used for userOperations
44
+ */
45
+ bundlerTransport: Transport;
46
+ /**
47
+ * Passkey compatible signer used for signing user operations
48
+ */
49
+ signer: PasskeySigner;
50
+ }
39
51
 
40
52
  /**
41
53
  * Defines the available client events and their corresponding watch functions.
42
54
  * These functions are used to subscribe to real-time updates from the client.
43
55
  */
44
56
  export const ClientEvents = {
45
- /**
46
- * Event for new blocks.
47
- * Uses the {@link watchBlocks} function from `@mentaproject/core`.
48
- */
49
- block: watchBlocks,
50
- /**
51
- * Event for new block numbers.
52
- * Uses the {@link watchBlockNumber} function from `@mentaproject/core`.
53
- */
54
- blockNumber: watchBlockNumber,
57
+ /**
58
+ * Event for new blocks.
59
+ * Uses the {@link watchBlocks} function from `@mentaproject/core`.
60
+ */
61
+ block: watchBlocks,
62
+ /**
63
+ * Event for new block numbers.
64
+ * Uses the {@link watchBlockNumber} function from `@mentaproject/core`.
65
+ */
66
+ blockNumber: watchBlockNumber,
55
67
  };
56
68
 
57
69
  /**
@@ -60,8 +72,8 @@ export const ClientEvents = {
60
72
  * @template TEvent The name of the event (e.g., 'block' or 'blockNumber') for which to get the listener callback type.
61
73
  */
62
74
  export type GetListenerCallback<TEvent extends keyof typeof ClientEvents> =
63
- Parameters<typeof ClientEvents[TEvent]>[1] extends infer P
64
- ? P extends { [K in `on${Capitalize<TEvent>}`]: infer TCallback }
65
- ? TCallback
66
- : never
67
- : never;
75
+ Parameters<(typeof ClientEvents)[TEvent]>[1] extends infer P
76
+ ? P extends { [K in `on${Capitalize<TEvent>}`]: infer TCallback }
77
+ ? TCallback
78
+ : never
79
+ : never;
@@ -2,7 +2,7 @@
2
2
  * @module withCache
3
3
  */
4
4
  import { watchBlockNumber } from "@mentaproject/core/actions";
5
- import { CoreClient } from "../types";
5
+ import type { CoreClient } from "@mentaproject/core/types";
6
6
  import { ICache } from "../types/Cache";
7
7
  import { Methods } from "../types/JsonRPC";
8
8
 
@@ -15,7 +15,7 @@ import { Methods } from "../types/JsonRPC";
15
15
  * @param cache The cache implementation (ICache) to use for storing and retrieving responses.
16
16
  * @returns The enhanced CoreClient instance with caching enabled.
17
17
  */
18
- export function withCache(client: CoreClient, cache: ICache) {
18
+ export function withCache<T extends CoreClient>(client: T, cache: ICache): T {
19
19
  watchBlockNumber(client, {
20
20
  onBlockNumber: (blockNumber) => {
21
21
  cache.setBlockNumber(blockNumber);
@@ -47,4 +47,4 @@ export function withCache(client: CoreClient, cache: ICache) {
47
47
  }) as any;
48
48
 
49
49
  return client;
50
- };
50
+ }
@@ -8,6 +8,23 @@ import { PersistenceManager } from '../../src/managers/PersistenceManager';
8
8
  import { MentaClientConfig } from '../../src/types/MentaClient';
9
9
  import { http } from '@mentaproject/core';
10
10
  import { mainnet } from 'viem/chains';
11
+ import type { PasskeySigner } from '@mentaproject/core/types';
12
+
13
+ // Mock passkey signer for testing
14
+ const mockSigner = {
15
+ address: '0x0000000000000000000000000000000000000000',
16
+ type: 'local',
17
+ source: 'custom',
18
+ publicKey: '0x00',
19
+ pubX: 0n,
20
+ pubY: 0n,
21
+ authenticatorId: 'mock-authenticator',
22
+ authenticatorIdHash: '0x0000000000000000000000000000000000000000000000000000000000000000',
23
+ rpID: 'localhost',
24
+ signMessage: async () => '0x00',
25
+ signTransaction: async () => '0x00',
26
+ signTypedData: async () => '0x00',
27
+ } as unknown as PasskeySigner;
11
28
 
12
29
  describe('MentaClient', () => {
13
30
  let client: MentaClient;
@@ -15,6 +32,8 @@ describe('MentaClient', () => {
15
32
  transport: http('http://localhost:8545'),
16
33
  chain: mainnet,
17
34
  persistenceAdapter: mockPersistenceAdapter,
35
+ bundlerTransport: http('http://localhost:4337'),
36
+ signer: mockSigner,
18
37
  };
19
38
 
20
39
  beforeEach(() => {
@@ -33,8 +52,10 @@ describe('MentaClient', () => {
33
52
  const clientWithoutPersistence = new MentaClient({
34
53
  transport: http('http://localhost:8545'),
35
54
  chain: mainnet,
55
+ bundlerTransport: http('http://localhost:4337'),
56
+ signer: mockSigner,
36
57
  });
37
58
  expect(clientWithoutPersistence.persistenceManager).toBeUndefined();
38
59
  expect(clientWithoutPersistence.accounts).toBeInstanceOf(AccountManager);
39
60
  });
40
- });
61
+ });