Skip to content

Commit 8f3ea55

Browse files
committed
feat: update simulate tx
1 parent 21efcb1 commit 8f3ea55

File tree

7 files changed

+87
-2
lines changed

7 files changed

+87
-2
lines changed

__tests__/account.test.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,16 @@ describe('deploy and test Wallet', () => {
6565
innerInvokeEstFeeSpy.mockClear();
6666
});
6767

68+
test('simulate transaction', async () => {
69+
const res = await account.simulateTransaction({
70+
contractAddress: erc20Address,
71+
entrypoint: 'transfer',
72+
calldata: [erc20.address, '10', '0'],
73+
});
74+
expect(res).toHaveProperty('fee_estimation');
75+
expect(res).toHaveProperty('trace');
76+
});
77+
6878
test('read balance of wallet', async () => {
6979
const x = await erc20.balanceOf(account.address);
7080

src/account/default.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
InvokeFunctionResponse,
2525
KeyPair,
2626
MultiDeployContractResponse,
27+
Sequencer,
2728
Signature,
2829
UniversalDeployerContractPayload,
2930
} from '../types';
@@ -498,4 +499,36 @@ export class Account extends Provider implements AccountInterface {
498499

499500
return feeEstimate.suggestedMaxFee.toString();
500501
}
502+
503+
public async simulateTransaction(
504+
calls: AllowArray<Call>,
505+
{ nonce: providedNonce, blockIdentifier }: EstimateFeeDetails = {}
506+
): Promise<Sequencer.TransactionSimulationResponse> {
507+
const transactions = Array.isArray(calls) ? calls : [calls];
508+
const nonce = toBN(providedNonce ?? (await this.getNonce()));
509+
const version = toBN(feeTransactionVersion);
510+
const chainId = await this.getChainId();
511+
512+
const signerDetails: InvocationsSignerDetails = {
513+
walletAddress: this.address,
514+
nonce,
515+
maxFee: ZERO,
516+
version,
517+
chainId,
518+
};
519+
520+
const signature = await this.signer.signTransaction(transactions, signerDetails);
521+
522+
const calldata = fromCallsToExecuteCalldata(transactions);
523+
const response: any = await super.getSimulateTransaction(
524+
{ contractAddress: this.address, calldata, signature },
525+
{ version, nonce },
526+
blockIdentifier
527+
);
528+
529+
const suggestedMaxFee = estimatedFeeToMaxFee(response.fee_estimation.overall_fee);
530+
response.fee_estimation.suggestedMaxFee = suggestedMaxFee;
531+
532+
return response;
533+
}
501534
}

src/account/interface.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
InvocationsDetails,
1919
InvokeFunctionResponse,
2020
MultiDeployContractResponse,
21+
Sequencer,
2122
Signature,
2223
UniversalDeployerContractPayload,
2324
} from '../types';
@@ -308,4 +309,19 @@ export abstract class AccountInterface extends ProviderInterface {
308309
estimateFeeAction: EstimateFeeAction,
309310
details: EstimateFeeDetails
310311
): Promise<BigNumberish>;
312+
313+
/**
314+
* Estimate Fee for executing an INVOKE transaction on starknet
315+
*
316+
* @param calls the invocation object containing:
317+
* - contractAddress - the address of the contract
318+
* - entrypoint - the entrypoint of the contract
319+
* - calldata - (defaults to []) the calldata
320+
*
321+
* @returns response from estimate_fee
322+
*/
323+
public abstract simulateTransaction(
324+
calls: AllowArray<Call>,
325+
estimateFeeDetails?: EstimateFeeDetails
326+
): Promise<Sequencer.TransactionSimulationResponse>;
311327
}

src/provider/default.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
Invocation,
1616
InvocationsDetailsWithNonce,
1717
InvokeFunctionResponse,
18+
Sequencer,
1819
Status,
1920
} from '../types';
2021
import { BigNumberish } from '../utils/number';
@@ -184,4 +185,12 @@ export class Provider implements ProviderInterface {
184185
): Promise<GetTransactionReceiptResponse> {
185186
return this.provider.waitForTransaction(txHash, retryInterval, successStates);
186187
}
188+
189+
public async getSimulateTransaction(
190+
invocation: Invocation,
191+
invocationDetails: InvocationsDetailsWithNonce,
192+
blockIdentifier?: BlockIdentifier
193+
): Promise<Sequencer.TransactionSimulationResponse> {
194+
return this.provider.getSimulateTransaction(invocation, invocationDetails, blockIdentifier);
195+
}
187196
}

src/provider/interface.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import type {
1616
Invocation,
1717
InvocationsDetailsWithNonce,
1818
InvokeFunctionResponse,
19+
Sequencer,
1920
Status,
2021
} from '../types';
2122
import type { BigNumberish } from '../utils/number';
@@ -278,4 +279,11 @@ export abstract class ProviderInterface {
278279
retryInterval?: number,
279280
successStates?: Array<Status>
280281
): Promise<GetTransactionReceiptResponse>;
282+
283+
// todo documentation
284+
public abstract getSimulateTransaction(
285+
invocation: Invocation,
286+
invocationDetails: InvocationsDetailsWithNonce,
287+
blockIdentifier?: BlockIdentifier
288+
): Promise<Sequencer.TransactionSimulationResponse>;
281289
}

src/provider/rpc.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
InvocationsDetailsWithNonce,
1515
InvokeFunctionResponse,
1616
RPC,
17+
Sequencer,
1718
} from '../types';
1819
import fetch from '../utils/fetchPonyfill';
1920
import { getSelectorFromName } from '../utils/hash';
@@ -481,4 +482,12 @@ export class RpcProvider implements ProviderInterface {
481482
public async getEvents(eventFilter: RPC.EventFilter): Promise<RPC.GetEventsResponse> {
482483
return this.fetchEndpoint('starknet_getEvents', { filter: eventFilter });
483484
}
485+
486+
public async getSimulateTransaction(
487+
_invocation: Invocation,
488+
_invocationDetails: InvocationsDetailsWithNonce,
489+
_blockIdentifier?: BlockIdentifier
490+
): Promise<Sequencer.TransactionSimulationResponse> {
491+
throw new Error('RPC does not implement simulateTransaction function');
492+
}
484493
}

src/provider/sequencer.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -522,10 +522,10 @@ export class SequencerProvider implements ProviderInterface {
522522
return this.fetchEndpoint('estimate_message_fee', { blockIdentifier }, validCallL1Handler);
523523
}
524524

525-
public async simulateTransaction(
525+
public async getSimulateTransaction(
526526
invocation: Invocation,
527527
invocationDetails: InvocationsDetailsWithNonce,
528-
blockIdentifier: BlockIdentifier = 'pending'
528+
blockIdentifier: BlockIdentifier = this.blockIdentifier
529529
): Promise<Sequencer.TransactionSimulationResponse> {
530530
return this.fetchEndpoint(
531531
'simulate_transaction',

0 commit comments

Comments
 (0)