@mentaproject/client 0.2.0 → 0.2.2

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.
@@ -2,22 +2,24 @@
2
2
  * @module TransactionManager
3
3
  */
4
4
  import { GetTransactionParameters, Transaction as RawTransaction, SendTransactionParameters } from "@mentaproject/core/types";
5
- import { Transaction as RichTransaction } from "../structures/Transaction";
5
+ import { TransactionRecord } from "../structures/TransactionRecord";
6
6
  import { MulticallTransaction } from "@mentaproject/transactions";
7
7
  import { getTransaction, sendTransaction } from "@mentaproject/core/actions";
8
8
  import { MentaClient } from "../structures";
9
9
  import { JSONTransaction } from "../types";
10
10
  import { parseBingints } from "../utils/bigint";
11
+ import { withGasSupport, WithGas } from "../utils/withGasSupport";
11
12
 
12
13
  /**
13
14
  * Manages blockchain transaction-related operations.
14
15
  *
15
16
  * @example
16
17
  * ```ts
17
- * // Create a multicall transaction
18
+ * // Create a multicall transaction with gas support
18
19
  * const pending = await client.transactions.create()
19
20
  * .addCall(account.sendEth(parseEther("1")))
20
21
  * .addCall(erc20.transfer(to, amount))
22
+ * .withGas("fast")
21
23
  * .execute();
22
24
  *
23
25
  * const receipt = await pending.confirm();
@@ -32,26 +34,28 @@ export class TransactionManager {
32
34
 
33
35
  /**
34
36
  * Creates a new MulticallTransaction for batching multiple calls.
37
+ * Enhanced with withGas() support for easy gas configuration.
35
38
  *
36
- * @returns A MulticallTransaction builder
39
+ * @returns A MulticallTransaction builder with withGas() support
37
40
  *
38
41
  * @example
39
42
  * ```ts
40
43
  * const pending = await client.transactions.create()
41
44
  * .addCall(account.sendEth(parseEther("1")))
42
- * .addCall(erc20.transfer(to, amount))
45
+ * .withGas("fast")
43
46
  * .execute();
44
47
  * ```
45
48
  */
46
- create(): MulticallTransaction {
47
- return new MulticallTransaction(this.client.rpc);
49
+ create(): WithGas<MulticallTransaction> {
50
+ const tx = new MulticallTransaction(this.client.rpc);
51
+ return withGasSupport(tx, this.client.gas);
48
52
  }
49
53
 
50
54
  /**
51
- * Retrieves a rich transaction by its hash.
55
+ * Retrieves a transaction record by its hash.
52
56
  *
53
57
  * @param hash - The transaction hash
54
- * @returns A rich Transaction with receipt, block, etc.
58
+ * @returns A TransactionRecord with receipt, block, etc.
55
59
  *
56
60
  * @example
57
61
  * ```ts
@@ -59,22 +63,22 @@ export class TransactionManager {
59
63
  * console.log(tx.from, tx.to, tx.value);
60
64
  * ```
61
65
  */
62
- async fromHash(hash: `0x${string}`): Promise<RichTransaction> {
66
+ async fromHash(hash: `0x${string}`): Promise<TransactionRecord> {
63
67
  return this.get({ hash });
64
68
  }
65
69
 
66
70
  /**
67
71
  * Retrieves a transaction by its hash or block number and index.
68
72
  */
69
- async get(params: GetTransactionParameters): Promise<RichTransaction> {
73
+ async get(params: GetTransactionParameters): Promise<TransactionRecord> {
70
74
  const data = await getTransaction(this.client.rpc, params);
71
- return new RichTransaction(this.client, data);
75
+ return new TransactionRecord(this.client, data);
72
76
  }
73
77
 
74
78
  /**
75
79
  * Parse a transaction object from a JSON converted transaction data object.
76
80
  */
77
- parse<J extends JSONTransaction<0>>(data: J): RichTransaction {
81
+ parse<J extends JSONTransaction<0>>(data: J): TransactionRecord {
78
82
  const parsed = parseBingints(data);
79
83
 
80
84
  const rawData = {
@@ -83,14 +87,14 @@ export class TransactionManager {
83
87
  to: parsed.to ? parsed.to.address : null,
84
88
  };
85
89
 
86
- return new RichTransaction(this.client, rawData as RawTransaction);
90
+ return new TransactionRecord(this.client, rawData as RawTransaction);
87
91
  }
88
92
 
89
93
  /**
90
94
  * Sends a transaction to the blockchain network.
91
95
  * @deprecated Use client.transactions.create() for new transactions
92
96
  */
93
- async send(params: SendTransactionParameters): Promise<RichTransaction> {
97
+ async send(params: SendTransactionParameters): Promise<TransactionRecord> {
94
98
  const hash = await sendTransaction(this.client.rpc, params);
95
99
  return await this.get({ hash });
96
100
  }
@@ -1,4 +1,5 @@
1
1
  export * from './AccountManager';
2
2
  export * from './BlockManager';
3
3
  export * from './ContractManager';
4
- export * from './TransactionManager';
4
+ export * from './GasManager';
5
+ export * from './TransactionManager';
@@ -11,7 +11,7 @@ import type {
11
11
  Hash,
12
12
  onBlockRangeCallback,
13
13
  } from "@mentaproject/core/types";
14
- import { Transaction as RichTransaction } from "./Transaction";
14
+ import { TransactionRecord } from "./TransactionRecord";
15
15
  import { Transaction } from "@mentaproject/transactions";
16
16
  import { toHex } from "@mentaproject/core/utils";
17
17
  import {
@@ -24,6 +24,7 @@ import { getContractType } from "@mentaproject/contracts";
24
24
  import { toJSON } from "../utils/toJSON";
25
25
  import { PersistenceManager } from "../managers/PersistenceManager";
26
26
  import { MentaClient } from "./MentaClient";
27
+ import { withGasSupport, WithGas } from "../utils/withGasSupport";
27
28
 
28
29
  /**
29
30
  * Represents a blockchain account with functionalities to interact with the Menta blockchain.
@@ -55,25 +56,29 @@ export class Account implements AccountData {
55
56
 
56
57
  /**
57
58
  * Creates a Transaction to send ETH to this account.
59
+ * Enhanced with withGas() support for easy gas configuration.
58
60
  *
59
61
  * @param amount The amount of ETH to send, in wei.
60
- * @returns A Transaction with .call(), .simulate(), and .execute() methods.
62
+ * @returns A Transaction with withGas(), .call(), .simulate(), and .execute() methods.
61
63
  *
62
64
  * @example
63
65
  * ```ts
64
- * // Direct execution
65
- * const pending = await account.sendEth(parseEther("1")).execute();
66
+ * // With gas config
67
+ * const pending = await account.sendEth(parseEther("1"))
68
+ * .withGas("fast")
69
+ * .execute();
66
70
  * const receipt = await pending.confirm();
67
71
  *
68
72
  * // Batch with MulticallTransaction
69
73
  * multicall.addCall(account.sendEth(parseEther("1")));
70
74
  * ```
71
75
  */
72
- sendEth(amount: bigint): Transaction {
73
- return new Transaction(this.client.rpc, {
76
+ sendEth(amount: bigint): WithGas<Transaction> {
77
+ const tx = new Transaction(this.client.rpc, {
74
78
  to: this.address,
75
79
  value: amount,
76
80
  });
81
+ return withGasSupport(tx, this.client.gas);
77
82
  }
78
83
 
79
84
  async ETHBalance(): Promise<bigint> {
@@ -87,7 +92,7 @@ export class Account implements AccountData {
87
92
  async transactions(
88
93
  params: GetTransactionsParams,
89
94
  forceFetch = false,
90
- ): Promise<RichTransaction[]> {
95
+ ): Promise<TransactionRecord[]> {
91
96
  if (!this.persistenceManager || forceFetch) {
92
97
  const hashes = await this._fetchTransactions(params);
93
98
  const transactions = await Promise.all(
@@ -1,7 +1,7 @@
1
1
  import { Block as RawBlock, Hash, Hex, Withdrawal } from "@mentaproject/core";
2
2
 
3
3
  import { Account } from "./Account";
4
- import { Transaction } from "./Transaction";
4
+ import { TransactionRecord } from "./TransactionRecord";
5
5
  import { JSONBlock } from "../types/Block";
6
6
  import { toJSON } from "../utils/toJSON";
7
7
  import { MentaClient } from "./MentaClient";
@@ -119,7 +119,7 @@ export class Block implements Omit<RawBlock, "miner" | "transactions"> {
119
119
  /**
120
120
  * @description The transactions included in the block, represented as an array of Transaction instances.
121
121
  */
122
- transactions?: Transaction[] | Hash[]
122
+ transactions?: TransactionRecord[] | Hash[]
123
123
 
124
124
  /**
125
125
  * @description Creates an instance of Block.
@@ -157,12 +157,12 @@ export class Block implements Omit<RawBlock, "miner" | "transactions"> {
157
157
  this.miner = new Account(this.client, { address: data.miner});
158
158
 
159
159
  if (!data.transactions || data.transactions.length === 0) {
160
- const parsed = data.transactions.map((data) => typeof data === "string" ? data : new Transaction(this.client, data))
161
- this.transactions = parsed as Transaction[] | Hash[];
160
+ const parsed = data.transactions.map((data) => typeof data === "string" ? data : new TransactionRecord(this.client, data))
161
+ this.transactions = parsed as TransactionRecord[] | Hash[];
162
162
  }
163
163
  };
164
164
 
165
- protected includeTransactions(): this is this & { transactions: Transaction[] } {
165
+ protected includeTransactions(): this is this & { transactions: TransactionRecord[] } {
166
166
  if (!this.transactions || this.transactions.length === 0) return false;
167
167
  return true
168
168
  }
@@ -10,6 +10,7 @@ import { TransactionManager } from "../managers/TransactionManager";
10
10
  import { ContractManager } from "../managers/ContractManager";
11
11
  import { AccountManager } from "../managers/AccountManager";
12
12
  import { PersistenceManager } from "../managers/PersistenceManager";
13
+ import { GasManager, GasStrategy } from "../managers/GasManager";
13
14
  import {
14
15
  ClientEvents,
15
16
  GetListenerCallback,
@@ -20,18 +21,29 @@ import { Account } from "./Account";
20
21
 
21
22
  /**
22
23
  * The main client for interacting with the Menta API.
23
- * It provides managers for blocks, transactions, contracts, and accounts.
24
+ * It provides managers for blocks, transactions, contracts, accounts, and gas.
24
25
  *
25
- * @description This class serves as the primary entry point for interacting with the Menta blockchain.
26
- * It encapsulates the core RPC client and provides specialized managers for various blockchain entities,
27
- * simplifying common operations.
26
+ * @example
27
+ * ```ts
28
+ * const client = new MentaClient({
29
+ * url: 'http://rpcurlhere.com',
30
+ * gas: { strategy: 'fast' }, // Default gas strategy
31
+ * });
32
+ *
33
+ * await client.init();
34
+ *
35
+ * // Use gas manager
36
+ * const prices = await client.gas.getPrices();
37
+ * const fastConfig = await client.gas.estimate('fast');
38
+ * ```
28
39
  */
29
40
  export class MentaClient {
30
41
  protected _rpc?: MentaAccountClient;
31
42
  protected _account?: Account;
43
+ protected _gas?: GasManager;
44
+
32
45
  /**
33
46
  * The underlying RPC client used for blockchain interactions.
34
- * @description This client is responsible for low-level communication with the RPC node.
35
47
  */
36
48
  public get rpc(): MentaAccountClient {
37
49
  if (!this._rpc) {
@@ -42,7 +54,6 @@ export class MentaClient {
42
54
 
43
55
  /**
44
56
  * The account associated with the client.
45
- * @description This account is used for signing transactions and interacting with the blockchain.
46
57
  */
47
58
  public get account(): Account {
48
59
  if (!this._account) {
@@ -51,46 +62,44 @@ export class MentaClient {
51
62
  return this._account;
52
63
  }
53
64
 
65
+ /**
66
+ * Manager for gas estimation and configuration.
67
+ */
68
+ public get gas(): GasManager {
69
+ if (!this._gas) {
70
+ throw new Error("Gas manager not initialized");
71
+ }
72
+ return this._gas;
73
+ }
74
+
75
+ /**
76
+ * Default gas strategy for transactions.
77
+ */
78
+ public defaultGasStrategy?: GasStrategy;
79
+
54
80
  /**
55
81
  * Manager for block-related operations.
56
- * @description Provides methods to query and interact with blockchain blocks.
57
82
  */
58
83
  public blocks!: BlockManager;
59
84
  /**
60
85
  * Manager for transaction-related operations.
61
- * @description Provides methods to send, query, and manage blockchain transactions.
62
86
  */
63
87
  public transactions!: TransactionManager;
64
88
  /**
65
89
  * Manager for contract-related operations.
66
- * @description Provides methods to deploy, interact with, and query smart contracts.
67
90
  */
68
91
  public contracts!: ContractManager;
69
92
  /**
70
93
  * Manager for account-related operations.
71
- * @description Provides methods to manage and interact with blockchain accounts.
72
94
  */
73
95
  public accounts!: AccountManager;
96
+ /**
97
+ * Optional manager for persistence-related operations.
98
+ */
99
+ public persistenceManager?: PersistenceManager;
74
100
 
75
101
  /**
76
102
  * Subscribes to a specific client event.
77
- * @template TEvent The type of the event to listen for.
78
- * @param {TEvent} event - The event to listen for (e.g., 'block', 'transaction').
79
- * @param {GetListenerCallback<TEvent>} callback - The callback function to execute when the event is triggered.
80
- * @returns {() => void} An unsubscribe function to stop listening to the event.
81
- * @description This method allows the client to listen for real-time events from the blockchain, such as new blocks or transactions.
82
- * @example
83
- * import { MentaClient } from '@mentaproject/client';
84
- *
85
- * const client = new MentaClient({ url: 'http://rpcurlhere.com' });
86
- *
87
- * // Subscribe to new blocks
88
- * const unsubscribe = client.on('block', (block) => {
89
- * console.log('New block received:', block);
90
- * });
91
- *
92
- * // To stop listening
93
- * // unsubscribe();
94
103
  */
95
104
  on<TEvent extends keyof typeof ClientEvents>(
96
105
  event: TEvent,
@@ -108,30 +117,16 @@ export class MentaClient {
108
117
 
109
118
  /**
110
119
  * Creates an instance of MentaClient.
111
- * @param {MentaClientConfig} params - The configuration parameters for the client.
112
- * @description The constructor initializes the RPC client and the various managers based on the provided configuration.
113
- * It also applies caching and persistence if specified in the configuration.
114
- * @example
115
- * import { MentaClient } from '@mentaproject/client';
116
- *
117
- * // Basic initialization
118
- * const client = new MentaClient({
119
- * url: 'http://rpcurlhere.com',
120
- * });
121
- *
122
- * // Initialization with a persistent cache
123
- * const clientWithCache = new MentaClient({
124
- * url: 'http://rpcurlhere.com',
125
- * cache: {
126
- * ttl: 60000, // 1 minute
127
- * },
128
- * });
129
120
  */
130
121
  constructor(protected params: MentaClientConfig) {
131
122
  this.blocks = new BlockManager(this);
132
123
  this.transactions = new TransactionManager(this);
133
124
  this.contracts = new ContractManager(this);
134
125
 
126
+ if (params.gas?.strategy) {
127
+ this.defaultGasStrategy = params.gas.strategy;
128
+ }
129
+
135
130
  if (params.persistenceAdapter) {
136
131
  this.persistenceManager = new PersistenceManager(
137
132
  this,
@@ -158,12 +153,6 @@ export class MentaClient {
158
153
  });
159
154
 
160
155
  this._account = this.accounts.get(this.rpc.account.address);
156
+ this._gas = new GasManager(this.rpc);
161
157
  }
162
-
163
- /**
164
- * Optional manager for persistence-related operations.
165
- * @description This manager is initialized if a persistence adapter is provided in the client configuration,
166
- * allowing for data storage and retrieval.
167
- */
168
- public persistenceManager?: PersistenceManager;
169
158
  }
@@ -17,7 +17,7 @@ import { JSONTransaction, TransactionCall } from '../types';
17
17
  * providing methods to interact with the blockchain to retrieve transaction-related information such as
18
18
  * internal calls, receipts, and the block it belongs to.
19
19
  */
20
- export class Transaction implements Omit<RawTransaction, "from" | "to"> {
20
+ export class TransactionRecord implements Omit<RawTransaction, "from" | "to"> {
21
21
  /**
22
22
  * @description The access list for the transaction.
23
23
  */
@@ -1,5 +1,5 @@
1
1
  export * from "./Account";
2
2
  export * from "./Block";
3
3
  export * from "./MentaClient";
4
- export * from "./Transaction";
4
+ export * from "./TransactionRecord";
5
5
  export * from "./Cache";
@@ -6,6 +6,7 @@ import { ICache } from "./Cache";
6
6
  import { watchBlockNumber, watchBlocks } from "@mentaproject/core/actions";
7
7
  import { IPersistenceAdapter } from "./PersistenceAdapter";
8
8
  import { WebAuthnAccount } from "@mentaproject/core/account-abstraction";
9
+ import { GasStrategy } from "../managers/GasManager";
9
10
 
10
11
  /**
11
12
  * Configuration for the client's cache.
@@ -20,6 +21,17 @@ export interface CacheConfig {
20
21
  ttl_policies: Record<string, number>;
21
22
  }
22
23
 
24
+ /**
25
+ * Gas configuration for the client.
26
+ */
27
+ export interface GasConfig {
28
+ /**
29
+ * Default gas strategy for all transactions.
30
+ * Can be overridden per transaction with withGas() or withGasConfig().
31
+ */
32
+ strategy: GasStrategy;
33
+ }
34
+
23
35
  /**
24
36
  * Configuration options for the MentaClient.
25
37
  * Extends {@link CoreClientConfig} from `@mentaproject/core`.
@@ -48,6 +60,11 @@ export interface MentaClientConfig extends CoreClientConfig {
48
60
  * Validator address used for userOperations
49
61
  */
50
62
  validatorAddress: Address;
63
+ /**
64
+ * Optional gas configuration.
65
+ * If provided, sets the default gas strategy for all transactions.
66
+ */
67
+ gas?: GasConfig;
51
68
  }
52
69
 
53
70
  /**
@@ -1,6 +1,6 @@
1
1
  import { Address } from '@mentaproject/core/types';
2
2
 
3
- import { Transaction } from '../structures/Transaction';
3
+ import { TransactionRecord } from '../structures/TransactionRecord';
4
4
  import { GetTransactionsParams } from './Account';
5
5
  import { JSONTransaction } from './Transaction';
6
6
 
@@ -12,16 +12,16 @@ export interface IPersistenceAdapter {
12
12
  /**
13
13
  * @method upsertTransactions
14
14
  * @description Inserts or updates a list of transactions. The operation must be atomic.
15
- * @param {Transaction[]} transactions - An array of transaction data, including associated account addresses and timestamps.
15
+ * @param {TransactionRecord[]} transactions - An array of transaction data, including associated account addresses and timestamps.
16
16
  * @returns {Promise<void>} A Promise that resolves when the transactions have been successfully inserted or updated.
17
17
  */
18
- upsertTransactions(transactions: Transaction[]): Promise<void>;
18
+ upsertTransactions(transactions: TransactionRecord[]): Promise<void>;
19
19
 
20
20
  /**
21
21
  * @method getTransactions
22
22
  * @description Retrieves a paginated list of transactions for a specific account based on provided filters.
23
23
  * @param {GetTransactionsFilters} filters - An object containing filters for retrieving transactions, such as account address, block range, pagination, and sort order.
24
- * @returns {Promise<JSONTransaction[]>} A Promise that resolves with transactions objects.
24
+ * @returns {Promise<JSONTransactionRecord[]>} A Promise that resolves with transactions objects.
25
25
  */
26
26
  getTransactions(address: Address, params: GetTransactionsParams): Promise<JSONTransaction<0>[]>;
27
27
 
@@ -0,0 +1,50 @@
1
+ import { BaseTransaction } from "@mentaproject/transactions";
2
+ import { GasManager, GasStrategy } from "../managers/GasManager";
3
+
4
+ /**
5
+ * Transaction enhanced with withGas() support.
6
+ */
7
+ export type WithGas<T extends BaseTransaction> = T & {
8
+ /**
9
+ * Sets gas configuration using a strategy (easy mode).
10
+ * Uses the client's GasManager for estimation.
11
+ *
12
+ * @param strategy - "slow", "medium", or "fast"
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * await tx.withGas("fast").execute();
17
+ * ```
18
+ */
19
+ withGas(strategy: GasStrategy): Promise<T>;
20
+ };
21
+
22
+ /**
23
+ * Enhances a transaction with withGas() support.
24
+ * This injects the client's GasManager for gas estimation.
25
+ *
26
+ * @param tx - The transaction to enhance
27
+ * @param gasManager - The client's GasManager
28
+ * @returns The enhanced transaction with withGas() method
29
+ *
30
+ * @example
31
+ * ```ts
32
+ * const tx = new Transaction(client.rpc, call);
33
+ * const enhanced = withGasSupport(tx, client.gas);
34
+ * await enhanced.withGas("fast").execute();
35
+ * ```
36
+ */
37
+ export function withGasSupport<T extends BaseTransaction>(
38
+ tx: T,
39
+ gasManager: GasManager,
40
+ ): WithGas<T> {
41
+ const enhanced = tx as WithGas<T>;
42
+
43
+ enhanced.withGas = async (strategy: GasStrategy): Promise<T> => {
44
+ const config = await gasManager.estimate(strategy);
45
+ tx.withGasConfig(config);
46
+ return tx;
47
+ };
48
+
49
+ return enhanced;
50
+ }