Skip to content

Commit 32f0086

Browse files
authored
[GW-644]: Add simulate tx node extension (#2)
* feat: add simulate tx node extension * refactor: add jest and node types * refactor: handle simulate send tx * feat: add simulate test * feat: add env examples
1 parent a4f892b commit 32f0086

File tree

12 files changed

+7671
-179
lines changed

12 files changed

+7671
-179
lines changed

.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
TENDERLY_WEB3_GATEWAY_ACCESS_TOKEN=

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,10 @@ Node Extensions is a game-changing enhancement to our existing production node.
77
## How to use
88

99
TBD
10+
11+
## Node Extension Examples
12+
13+
Here are examples of Node Extensions that you can use in your projects:
14+
15+
- [chainlink-price-feed](./chainlink-price-feed) - A Node Extension that allows you to query Chainlink Price Feeds
16+
- [simulate-send-transaction](./simulate-send-transaction) - A Node Extension that allows you to simulate a transaction before sending on-chain
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
TENDERLY_WEB3_GATEWAY_ACCESS_TOKEN=
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
TENDERLY_WEB3_GATEWAY_ACCESS_TOKEN=

simulate-send-transaction/actions/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ node_modules/
33

44
# Ignore tsc output
55
out/**/*
6+
7+
.env
Lines changed: 44 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,46 @@
1-
import {ActionFn, Context, Event, Network} from '@tenderly/actions';
2-
3-
import {ethers} from 'ethers';
1+
import { ActionFn, Context, Event, Network, WebhookEvent } from '@tenderly/actions';
2+
import { ethers } from 'ethers';
43

54
export const sendSimulateRawTransaction: ActionFn = async (context: Context, event: Event) => {
6-
// Setting a variable that will store the Web3 Gateway RPC URL and secret key
7-
const defaultGatewayURL = context.gateways.getGateway(Network.MAINNET);
8-
9-
// Using the Ethere.js provider class to call the RPC URL
10-
const provider = new ethers.JsonRpcProvider(defaultGatewayURL);
11-
12-
// Decode raw transaction
13-
const tx = ethers.Transaction.from(event)
14-
15-
// Simulate transaction to get execution results
16-
const simResponse = await provider.send("tenderly_simulateTransaction", [{
17-
"from": tx.from,
18-
"to": tx.to,
19-
"gas": tx.gasLimit,
20-
"gasPrice": tx.gasPrice,
21-
"value": tx.value,
22-
"data": tx.data,
23-
}])
24-
25-
// If simulation fails, return error
26-
if (simResponse.status == false) {
27-
return null
28-
}
29-
30-
// Send transaction to the network
31-
return provider.send('eth_sendRawTransaction', event)
32-
}
5+
// Casting the event to a WebhookEvent
6+
const webhookEvent: WebhookEvent = event as WebhookEvent;
7+
8+
// Setting a variable that will store the Web3 Gateway RPC URL and secret key
9+
const defaultGatewayURL = context.gateways.getGateway(Network.MAINNET);
10+
11+
// Using the Ethers.js provider class to call the RPC URL
12+
const provider = new ethers.providers.JsonRpcProvider(defaultGatewayURL);
13+
14+
// Getting the raw transaction payload from the webhook event
15+
const txPayload = webhookEvent.payload.data;
16+
17+
// Parsing the transaction payload
18+
const tx = ethers.utils.parseTransaction(txPayload);
19+
20+
// Creating a new transaction object with the parsed transaction
21+
// in order to support the tenderly_simulateTransaction RPC call
22+
const parsedTransaction = {
23+
from: tx.from,
24+
to: tx.to,
25+
gas: tx.gasLimit?._hex,
26+
gasPrice: tx.gasPrice?._hex,
27+
value: tx.value?._hex,
28+
data: tx.data,
29+
};
30+
31+
// Simulate transaction to get execution results
32+
const simulationResponse = await provider.send('tenderly_simulateTransaction', [parsedTransaction, 'latest']);
33+
34+
// If simulation fails, return error
35+
if (simulationResponse.status === false) {
36+
console.log('Simulate transaction failed');
37+
return Promise.reject({
38+
error: 'Simulation failed',
39+
simulationResponse,
40+
});
41+
}
42+
43+
// If simulation succeeds, send the transaction
44+
console.log('Simulate transaction success');
45+
return provider.send('eth_sendRawTransaction', [txPayload]);
46+
};
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"preset": "ts-jest",
3+
"testEnvironment": "node"
4+
}

0 commit comments

Comments
 (0)