@nomicfoundation/edr 0.2.0-alpha.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.
Files changed (62) hide show
  1. package/.cargo/config.toml +8 -0
  2. package/.mocharc.json +4 -0
  3. package/Cargo.toml +50 -0
  4. package/LICENSE +1 -0
  5. package/artifacts/bindings-aarch64-apple-darwin/edr.darwin-arm64.node +0 -0
  6. package/artifacts/bindings-aarch64-pc-windows-msvc/edr.win32-arm64-msvc.node +0 -0
  7. package/artifacts/bindings-aarch64-unknown-linux-gnu/edr.linux-arm64-gnu.node +0 -0
  8. package/artifacts/bindings-aarch64-unknown-linux-musl/edr.linux-arm64-musl.node +0 -0
  9. package/artifacts/bindings-i686-pc-windows-msvc/edr.win32-ia32-msvc.node +0 -0
  10. package/artifacts/bindings-x86_64-apple-darwin/edr.darwin-x64.node +0 -0
  11. package/artifacts/bindings-x86_64-pc-windows-msvc/edr.win32-x64-msvc.node +0 -0
  12. package/artifacts/bindings-x86_64-unknown-linux-gnu/edr.linux-x64-gnu.node +0 -0
  13. package/artifacts/bindings-x86_64-unknown-linux-musl/edr.linux-x64-musl.node +0 -0
  14. package/build.rs +3 -0
  15. package/index.d.ts +383 -0
  16. package/index.js +264 -0
  17. package/npm/darwin-arm64/README.md +3 -0
  18. package/npm/darwin-arm64/edr.darwin-arm64.node +0 -0
  19. package/npm/darwin-arm64/package.json +22 -0
  20. package/npm/darwin-x64/README.md +3 -0
  21. package/npm/darwin-x64/edr.darwin-x64.node +0 -0
  22. package/npm/darwin-x64/package.json +22 -0
  23. package/npm/linux-arm64-gnu/README.md +3 -0
  24. package/npm/linux-arm64-gnu/edr.linux-arm64-gnu.node +0 -0
  25. package/npm/linux-arm64-gnu/package.json +25 -0
  26. package/npm/linux-arm64-musl/README.md +3 -0
  27. package/npm/linux-arm64-musl/edr.linux-arm64-musl.node +0 -0
  28. package/npm/linux-arm64-musl/package.json +25 -0
  29. package/npm/linux-x64-gnu/README.md +3 -0
  30. package/npm/linux-x64-gnu/edr.linux-x64-gnu.node +0 -0
  31. package/npm/linux-x64-gnu/package.json +25 -0
  32. package/npm/linux-x64-musl/README.md +3 -0
  33. package/npm/linux-x64-musl/edr.linux-x64-musl.node +0 -0
  34. package/npm/linux-x64-musl/package.json +25 -0
  35. package/npm/win32-arm64-msvc/README.md +3 -0
  36. package/npm/win32-arm64-msvc/edr.win32-arm64-msvc.node +0 -0
  37. package/npm/win32-arm64-msvc/package.json +22 -0
  38. package/npm/win32-ia32-msvc/README.md +3 -0
  39. package/npm/win32-ia32-msvc/edr.win32-ia32-msvc.node +0 -0
  40. package/npm/win32-ia32-msvc/package.json +22 -0
  41. package/npm/win32-x64-msvc/README.md +3 -0
  42. package/npm/win32-x64-msvc/edr.win32-x64-msvc.node +0 -0
  43. package/npm/win32-x64-msvc/package.json +22 -0
  44. package/package.json +61 -0
  45. package/src/account.rs +28 -0
  46. package/src/block.rs +110 -0
  47. package/src/cast.rs +119 -0
  48. package/src/config.rs +70 -0
  49. package/src/context.rs +74 -0
  50. package/src/debug_trace.rs +38 -0
  51. package/src/lib.rs +18 -0
  52. package/src/log.rs +41 -0
  53. package/src/logger.rs +1277 -0
  54. package/src/provider/config.rs +271 -0
  55. package/src/provider.rs +185 -0
  56. package/src/result.rs +254 -0
  57. package/src/subscribe.rs +60 -0
  58. package/src/sync.rs +85 -0
  59. package/src/threadsafe_function.rs +305 -0
  60. package/src/trace.rs +168 -0
  61. package/test/provider.ts +104 -0
  62. package/tsconfig.json +17 -0
package/src/trace.rs ADDED
@@ -0,0 +1,168 @@
1
+ use std::{mem, sync::Arc};
2
+
3
+ use edr_evm::{trace::BeforeMessage, OPCODE_JUMPMAP};
4
+ use napi::{
5
+ bindgen_prelude::{BigInt, Buffer, Either3},
6
+ Env, JsBuffer, JsBufferValue,
7
+ };
8
+ use napi_derive::napi;
9
+
10
+ use crate::result::ExecutionResult;
11
+
12
+ #[napi(object)]
13
+ pub struct TracingMessage {
14
+ /// Sender address
15
+ #[napi(readonly)]
16
+ pub caller: Buffer,
17
+
18
+ /// Recipient address. None if it is a Create message.
19
+ #[napi(readonly)]
20
+ pub to: Option<Buffer>,
21
+
22
+ /// Transaction gas limit
23
+ #[napi(readonly)]
24
+ pub gas_limit: BigInt,
25
+
26
+ /// Depth of the message
27
+ #[napi(readonly)]
28
+ pub depth: u8,
29
+
30
+ /// Input data of the message
31
+ #[napi(readonly)]
32
+ pub data: JsBuffer,
33
+
34
+ /// Value sent in the message
35
+ #[napi(readonly)]
36
+ pub value: BigInt,
37
+
38
+ /// Address of the code that is being executed. Can be different from `to`
39
+ /// if a delegate call is being done.
40
+ #[napi(readonly)]
41
+ pub code_address: Option<Buffer>,
42
+
43
+ /// Code of the contract that is being executed.
44
+ #[napi(readonly)]
45
+ pub code: Option<JsBuffer>,
46
+ }
47
+
48
+ impl TracingMessage {
49
+ pub fn new(env: &Env, message: &BeforeMessage) -> napi::Result<Self> {
50
+ let data = message.data.clone();
51
+ let data = unsafe {
52
+ env.create_buffer_with_borrowed_data(
53
+ data.as_ptr(),
54
+ data.len(),
55
+ data,
56
+ |data: edr_eth::Bytes, _env| {
57
+ mem::drop(data);
58
+ },
59
+ )
60
+ }
61
+ .map(JsBufferValue::into_raw)?;
62
+
63
+ let code = message.code.as_ref().map_or(Ok(None), |code| {
64
+ let code = code.original_bytes();
65
+
66
+ unsafe {
67
+ env.create_buffer_with_borrowed_data(
68
+ code.as_ptr(),
69
+ code.len(),
70
+ code,
71
+ |code: edr_eth::Bytes, _env| {
72
+ mem::drop(code);
73
+ },
74
+ )
75
+ }
76
+ .map(JsBufferValue::into_raw)
77
+ .map(Some)
78
+ })?;
79
+
80
+ Ok(TracingMessage {
81
+ caller: Buffer::from(message.caller.as_slice()),
82
+ to: message.to.map(|to| Buffer::from(to.as_slice())),
83
+ gas_limit: BigInt::from(message.gas_limit),
84
+ depth: message.depth as u8,
85
+ data,
86
+ value: BigInt {
87
+ sign_bit: false,
88
+ words: message.value.into_limbs().to_vec(),
89
+ },
90
+ code_address: message
91
+ .code_address
92
+ .map(|address| Buffer::from(address.to_vec())),
93
+ code,
94
+ })
95
+ }
96
+ }
97
+
98
+ #[napi(object)]
99
+ pub struct TracingStep {
100
+ /// Call depth
101
+ #[napi(readonly)]
102
+ pub depth: u8,
103
+ /// The program counter
104
+ #[napi(readonly)]
105
+ pub pc: BigInt,
106
+ /// The executed op code
107
+ #[napi(readonly)]
108
+ pub opcode: String,
109
+ /// The top entry on the stack. None if the stack is empty.
110
+ #[napi(readonly)]
111
+ pub stack_top: Option<BigInt>,
112
+ }
113
+
114
+ impl TracingStep {
115
+ pub fn new(step: &edr_evm::trace::Step) -> Self {
116
+ Self {
117
+ depth: step.depth as u8,
118
+ pc: BigInt::from(step.pc),
119
+ opcode: OPCODE_JUMPMAP[usize::from(step.opcode)]
120
+ .unwrap_or("")
121
+ .to_string(),
122
+ stack_top: step.stack_top.map(|v| BigInt {
123
+ sign_bit: false,
124
+ words: v.into_limbs().to_vec(),
125
+ }),
126
+ }
127
+ }
128
+ }
129
+
130
+ #[napi(object)]
131
+ pub struct TracingMessageResult {
132
+ /// Execution result
133
+ #[napi(readonly)]
134
+ pub execution_result: ExecutionResult,
135
+ }
136
+
137
+ #[napi]
138
+ pub struct RawTrace {
139
+ inner: Arc<edr_evm::trace::Trace>,
140
+ }
141
+
142
+ impl RawTrace {
143
+ pub fn new(inner: Arc<edr_evm::trace::Trace>) -> Self {
144
+ Self { inner }
145
+ }
146
+ }
147
+
148
+ #[napi]
149
+ impl RawTrace {
150
+ #[napi]
151
+ pub fn trace(
152
+ &self,
153
+ env: Env,
154
+ ) -> napi::Result<Vec<Either3<TracingMessage, TracingStep, TracingMessageResult>>> {
155
+ self.inner
156
+ .messages
157
+ .iter()
158
+ .map(|message| match message {
159
+ edr_evm::trace::TraceMessage::Before(message) => {
160
+ TracingMessage::new(&env, message).map(Either3::A)
161
+ }
162
+ edr_evm::trace::TraceMessage::Step(step) => Ok(Either3::B(TracingStep::new(step))),
163
+ edr_evm::trace::TraceMessage::After(result) => ExecutionResult::new(&env, result)
164
+ .map(|execution_result| Either3::C(TracingMessageResult { execution_result })),
165
+ })
166
+ .collect::<napi::Result<_>>()
167
+ }
168
+ }
@@ -0,0 +1,104 @@
1
+ import chai, { assert } from "chai";
2
+ import chaiAsPromised from "chai-as-promised";
3
+ import {
4
+ ContractAndFunctionName,
5
+ EdrContext,
6
+ MineOrdering,
7
+ Provider,
8
+ SpecId,
9
+ SubscriptionEvent,
10
+ } from "..";
11
+
12
+ chai.use(chaiAsPromised);
13
+
14
+ function getEnv(key: string): string | undefined {
15
+ const variable = process.env[key];
16
+ if (variable === undefined || variable === "") {
17
+ return undefined;
18
+ }
19
+
20
+ const trimmed = variable.trim();
21
+
22
+ return trimmed.length === 0 ? undefined : trimmed;
23
+ }
24
+
25
+ const ALCHEMY_URL = getEnv("ALCHEMY_URL");
26
+
27
+ describe("Provider", () => {
28
+ const context = new EdrContext();
29
+ const providerConfig = {
30
+ allowBlocksWithSameTimestamp: false,
31
+ allowUnlimitedContractSize: true,
32
+ bailOnCallFailure: false,
33
+ bailOnTransactionFailure: false,
34
+ blockGasLimit: 300_000_000n,
35
+ chainId: 123n,
36
+ chains: [],
37
+ coinbase: Buffer.from("0000000000000000000000000000000000000000", "hex"),
38
+ genesisAccounts: [],
39
+ hardfork: SpecId.Latest,
40
+ initialBlobGas: {
41
+ gasUsed: 0n,
42
+ excessGas: 0n,
43
+ },
44
+ initialParentBeaconBlockRoot: Buffer.from(
45
+ "0000000000000000000000000000000000000000000000000000000000000000",
46
+ "hex"
47
+ ),
48
+ minGasPrice: 0n,
49
+ mining: {
50
+ autoMine: true,
51
+ memPool: {
52
+ order: MineOrdering.Priority,
53
+ },
54
+ },
55
+ networkId: 123n,
56
+ };
57
+
58
+ const loggerConfig = {
59
+ enable: false,
60
+ decodeConsoleLogInputsCallback: (inputs: Buffer[]): string[] => {
61
+ return [];
62
+ },
63
+ getContractAndFunctionNameCallback: (
64
+ _code: Buffer,
65
+ _calldata?: Buffer
66
+ ): ContractAndFunctionName => {
67
+ return {
68
+ contractName: "",
69
+ };
70
+ },
71
+ printLineCallback: (message: string, replace: boolean) => {},
72
+ };
73
+
74
+ it("initialize local", async function () {
75
+ const provider = Provider.withConfig(
76
+ context,
77
+ providerConfig,
78
+ loggerConfig,
79
+ (_event: SubscriptionEvent) => {}
80
+ );
81
+
82
+ await assert.isFulfilled(provider);
83
+ });
84
+
85
+ it("initialize remote", async function () {
86
+ if (ALCHEMY_URL === undefined) {
87
+ this.skip();
88
+ }
89
+
90
+ const provider = Provider.withConfig(
91
+ context,
92
+ {
93
+ fork: {
94
+ jsonRpcUrl: ALCHEMY_URL,
95
+ },
96
+ ...providerConfig,
97
+ },
98
+ loggerConfig,
99
+ (_event: SubscriptionEvent) => {}
100
+ );
101
+
102
+ await assert.isFulfilled(provider);
103
+ });
104
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "extends": "../../config/typescript/tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "./build-test",
5
+ "rootDirs": [
6
+ "./test"
7
+ ],
8
+ "composite": true
9
+ },
10
+ "include": [
11
+ "./*.ts",
12
+ "./test/**/*.ts"
13
+ ],
14
+ "exclude": [
15
+ "./node_modules"
16
+ ]
17
+ }