@bgd-labs/toolbox 0.0.25 → 0.0.27

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.
package/dist/node.mjs CHANGED
@@ -13845,6 +13845,113 @@ import {
13845
13845
  createWalletClient,
13846
13846
  http
13847
13847
  } from "viem";
13848
+
13849
+ // src/ecosystem/chainIds.ts
13850
+ import {
13851
+ arbitrum,
13852
+ arbitrumSepolia,
13853
+ avalanche,
13854
+ avalancheFuji,
13855
+ base,
13856
+ baseSepolia,
13857
+ bsc,
13858
+ celo,
13859
+ fantom,
13860
+ fantomTestnet,
13861
+ gnosis,
13862
+ harmonyOne,
13863
+ linea,
13864
+ mainnet,
13865
+ mantle,
13866
+ metis,
13867
+ optimism,
13868
+ optimismSepolia,
13869
+ polygon,
13870
+ polygonAmoy,
13871
+ polygonZkEvm,
13872
+ scroll,
13873
+ scrollSepolia,
13874
+ sepolia,
13875
+ sonic,
13876
+ zksync,
13877
+ ink,
13878
+ soneium,
13879
+ bob
13880
+ } from "viem/chains";
13881
+ var ChainId = {
13882
+ celo: celo.id,
13883
+ mainnet: mainnet.id,
13884
+ polygon: polygon.id,
13885
+ polygon_amoy: polygonAmoy.id,
13886
+ avalanche: avalanche.id,
13887
+ avalanche_fuji: avalancheFuji.id,
13888
+ arbitrum: arbitrum.id,
13889
+ arbitrum_sepolia: arbitrumSepolia.id,
13890
+ fantom: fantom.id,
13891
+ fantom_testnet: fantomTestnet.id,
13892
+ optimism: optimism.id,
13893
+ optimism_sepolia: optimismSepolia.id,
13894
+ harmony: harmonyOne.id,
13895
+ sepolia: sepolia.id,
13896
+ scroll: scroll.id,
13897
+ scroll_sepolia: scrollSepolia.id,
13898
+ sonic: sonic.id,
13899
+ mantle: mantle.id,
13900
+ metis: metis.id,
13901
+ base: base.id,
13902
+ base_sepolia: baseSepolia.id,
13903
+ bnb: bsc.id,
13904
+ gnosis: gnosis.id,
13905
+ zkEVM: polygonZkEvm.id,
13906
+ zksync: zksync.id,
13907
+ linea: linea.id,
13908
+ ink: ink.id,
13909
+ soneium: soneium.id,
13910
+ bob: bob.id
13911
+ };
13912
+ var ChainList = {
13913
+ [ChainId.mainnet]: mainnet,
13914
+ [ChainId.polygon]: polygon,
13915
+ [ChainId.polygon_amoy]: polygonAmoy,
13916
+ [ChainId.avalanche]: {
13917
+ ...avalanche,
13918
+ blockExplorers: {
13919
+ default: { url: "https://snowscan.xyz", name: "Snowscan" }
13920
+ }
13921
+ },
13922
+ [ChainId.avalanche_fuji]: {
13923
+ ...avalancheFuji,
13924
+ blockExplorers: {
13925
+ default: { url: "https://testnet.snowscan.xyz", name: "Snowscan Fuji" }
13926
+ }
13927
+ },
13928
+ [ChainId.arbitrum]: arbitrum,
13929
+ [ChainId.arbitrum_sepolia]: arbitrumSepolia,
13930
+ [ChainId.fantom]: fantom,
13931
+ [ChainId.fantom_testnet]: fantomTestnet,
13932
+ [ChainId.optimism]: optimism,
13933
+ [ChainId.optimism_sepolia]: optimismSepolia,
13934
+ [ChainId.harmony]: harmonyOne,
13935
+ [ChainId.sepolia]: sepolia,
13936
+ [ChainId.scroll]: scroll,
13937
+ [ChainId.scroll_sepolia]: scrollSepolia,
13938
+ [ChainId.sonic]: sonic,
13939
+ [ChainId.mantle]: mantle,
13940
+ [ChainId.metis]: metis,
13941
+ [ChainId.base]: base,
13942
+ [ChainId.base_sepolia]: baseSepolia,
13943
+ [ChainId.bnb]: bsc,
13944
+ [ChainId.gnosis]: gnosis,
13945
+ [ChainId.zkEVM]: polygonZkEvm,
13946
+ [ChainId.celo]: celo,
13947
+ [ChainId.zksync]: zksync,
13948
+ [ChainId.linea]: linea,
13949
+ [ChainId.ink]: ink,
13950
+ [ChainId.soneium]: soneium,
13951
+ [ChainId.bob]: bob
13952
+ };
13953
+
13954
+ // src/ecosystem/tenderly.ts
13848
13955
  var TENDERLY_BASE_URL = "https://api.tenderly.co/api/v1";
13849
13956
  async function tenderly_deleteVnet(vnetId, { accountSlug, projectSlug, accessToken }) {
13850
13957
  return fetch(
@@ -13953,11 +14060,18 @@ async function tenderly_createVnet({
13953
14060
  return {
13954
14061
  vnet: response,
13955
14062
  testClient: createTestClient({
14063
+ chain: {
14064
+ ...ChainList[baseChainId],
14065
+ id: forkChainId
14066
+ },
13956
14067
  mode: "tenderly",
13957
14068
  transport: http(rpc.url)
13958
14069
  }),
13959
14070
  walletClient: createWalletClient({
13960
- chain: { id: forkChainId },
14071
+ chain: {
14072
+ ...ChainList[baseChainId],
14073
+ id: forkChainId
14074
+ },
13961
14075
  account: "0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9",
13962
14076
  transport: http(rpc.url)
13963
14077
  }),
@@ -14009,115 +14123,76 @@ async function tenderly_sim({ accountSlug, projectSlug, accessToken }, body) {
14009
14123
  );
14010
14124
  return response.json();
14011
14125
  }
14126
+ function unwrapComponents(input) {
14127
+ return input.map((input2) => {
14128
+ if (input2.type === "tuple") {
14129
+ return {
14130
+ name: input2.name,
14131
+ type: input2.type,
14132
+ internalType: input2.type,
14133
+ indexed: input2.indexed,
14134
+ components: unwrapComponents(input2.components)
14135
+ };
14136
+ }
14137
+ return {
14138
+ name: input2.name,
14139
+ type: input2.type,
14140
+ internalType: input2.type,
14141
+ indexed: input2.indexed
14142
+ };
14143
+ });
14144
+ }
14145
+ function unwrapLogInputs(inputs) {
14146
+ return inputs.map((input) => {
14147
+ if (input.soltype?.type === "tuple") {
14148
+ return {
14149
+ name: input.soltype?.name,
14150
+ type: input.soltype?.type,
14151
+ indexed: input.soltype?.indexed,
14152
+ internalType: input.soltype?.type,
14153
+ components: unwrapComponents(input.soltype?.components)
14154
+ };
14155
+ }
14156
+ return {
14157
+ name: input.soltype?.name,
14158
+ type: input.soltype?.type,
14159
+ indexed: input.soltype?.indexed,
14160
+ internalType: input.soltype?.type
14161
+ };
14162
+ });
14163
+ }
14164
+ function tenderly_logsToAbiLogs(logs) {
14165
+ return logs.map((log) => {
14166
+ return {
14167
+ type: "event",
14168
+ name: log.name,
14169
+ ...log.inputs ? { inputs: unwrapLogInputs(log.inputs) } : {}
14170
+ };
14171
+ });
14172
+ }
14173
+
14174
+ // src/ecosystem/tenderly.types.ts
14175
+ var SoltypeType = /* @__PURE__ */ ((SoltypeType2) => {
14176
+ SoltypeType2["Address"] = "address";
14177
+ SoltypeType2["Bool"] = "bool";
14178
+ SoltypeType2["Bytes32"] = "bytes32";
14179
+ SoltypeType2["MappingAddressUint256"] = "mapping (address => uint256)";
14180
+ SoltypeType2["MappingUint256Uint256"] = "mapping (uint256 => uint256)";
14181
+ SoltypeType2["String"] = "string";
14182
+ SoltypeType2["Tuple"] = "tuple";
14183
+ SoltypeType2["TypeAddress"] = "address[]";
14184
+ SoltypeType2["TypeTuple"] = "tuple[]";
14185
+ SoltypeType2["Uint16"] = "uint16";
14186
+ SoltypeType2["Uint256"] = "uint256";
14187
+ SoltypeType2["Uint48"] = "uint48";
14188
+ SoltypeType2["Uint56"] = "uint56";
14189
+ SoltypeType2["Uint8"] = "uint8";
14190
+ return SoltypeType2;
14191
+ })(SoltypeType || {});
14012
14192
 
14013
14193
  // src/ecosystem/event-db.ts
14014
14194
  var EVENT_DB = [];
14015
14195
 
14016
- // src/ecosystem/chainIds.ts
14017
- import {
14018
- arbitrum,
14019
- arbitrumSepolia,
14020
- avalanche,
14021
- avalancheFuji,
14022
- base,
14023
- baseSepolia,
14024
- bsc,
14025
- celo,
14026
- fantom,
14027
- fantomTestnet,
14028
- gnosis,
14029
- harmonyOne,
14030
- linea,
14031
- mainnet,
14032
- mantle,
14033
- metis,
14034
- optimism,
14035
- optimismSepolia,
14036
- polygon,
14037
- polygonAmoy,
14038
- polygonZkEvm,
14039
- scroll,
14040
- scrollSepolia,
14041
- sepolia,
14042
- sonic,
14043
- zksync,
14044
- ink,
14045
- soneium,
14046
- bob
14047
- } from "viem/chains";
14048
- var ChainId = {
14049
- celo: celo.id,
14050
- mainnet: mainnet.id,
14051
- polygon: polygon.id,
14052
- polygon_amoy: polygonAmoy.id,
14053
- avalanche: avalanche.id,
14054
- avalanche_fuji: avalancheFuji.id,
14055
- arbitrum: arbitrum.id,
14056
- arbitrum_sepolia: arbitrumSepolia.id,
14057
- fantom: fantom.id,
14058
- fantom_testnet: fantomTestnet.id,
14059
- optimism: optimism.id,
14060
- optimism_sepolia: optimismSepolia.id,
14061
- harmony: harmonyOne.id,
14062
- sepolia: sepolia.id,
14063
- scroll: scroll.id,
14064
- scroll_sepolia: scrollSepolia.id,
14065
- sonic: sonic.id,
14066
- mantle: mantle.id,
14067
- metis: metis.id,
14068
- base: base.id,
14069
- base_sepolia: baseSepolia.id,
14070
- bnb: bsc.id,
14071
- gnosis: gnosis.id,
14072
- zkEVM: polygonZkEvm.id,
14073
- zksync: zksync.id,
14074
- linea: linea.id,
14075
- ink: ink.id,
14076
- soneium: soneium.id,
14077
- bob: bob.id
14078
- };
14079
- var ChainList = {
14080
- [ChainId.mainnet]: mainnet,
14081
- [ChainId.polygon]: polygon,
14082
- [ChainId.polygon_amoy]: polygonAmoy,
14083
- [ChainId.avalanche]: {
14084
- ...avalanche,
14085
- blockExplorers: {
14086
- default: { url: "https://snowscan.xyz", name: "Snowscan" }
14087
- }
14088
- },
14089
- [ChainId.avalanche_fuji]: {
14090
- ...avalancheFuji,
14091
- blockExplorers: {
14092
- default: { url: "https://testnet.snowscan.xyz", name: "Snowscan Fuji" }
14093
- }
14094
- },
14095
- [ChainId.arbitrum]: arbitrum,
14096
- [ChainId.arbitrum_sepolia]: arbitrumSepolia,
14097
- [ChainId.fantom]: fantom,
14098
- [ChainId.fantom_testnet]: fantomTestnet,
14099
- [ChainId.optimism]: optimism,
14100
- [ChainId.optimism_sepolia]: optimismSepolia,
14101
- [ChainId.harmony]: harmonyOne,
14102
- [ChainId.sepolia]: sepolia,
14103
- [ChainId.scroll]: scroll,
14104
- [ChainId.scroll_sepolia]: scrollSepolia,
14105
- [ChainId.sonic]: sonic,
14106
- [ChainId.mantle]: mantle,
14107
- [ChainId.metis]: metis,
14108
- [ChainId.base]: base,
14109
- [ChainId.base_sepolia]: baseSepolia,
14110
- [ChainId.bnb]: bsc,
14111
- [ChainId.gnosis]: gnosis,
14112
- [ChainId.zkEVM]: polygonZkEvm,
14113
- [ChainId.celo]: celo,
14114
- [ChainId.zksync]: zksync,
14115
- [ChainId.linea]: linea,
14116
- [ChainId.ink]: ink,
14117
- [ChainId.soneium]: soneium,
14118
- [ChainId.bob]: bob
14119
- };
14120
-
14121
14196
  // src/ecosystem/rpcs.ts
14122
14197
  import {
14123
14198
  http as http2,
@@ -28629,15 +28704,33 @@ var SELFDESTRUCT = 255;
28629
28704
  var DELEGATECALL = 244;
28630
28705
  var isHalting = (opcode) => [STOP, RETURN, REVERT, INVALID, SELFDESTRUCT].includes(opcode);
28631
28706
  var isPUSH = (opcode) => opcode >= PUSH1 && opcode <= PUSH32;
28632
- var SelfdestuctCheckState = /* @__PURE__ */ ((SelfdestuctCheckState2) => {
28633
- SelfdestuctCheckState2[SelfdestuctCheckState2["TRUSTED"] = 0] = "TRUSTED";
28634
- SelfdestuctCheckState2[SelfdestuctCheckState2["EOA"] = 1] = "EOA";
28635
- SelfdestuctCheckState2[SelfdestuctCheckState2["EMPTY"] = 2] = "EMPTY";
28636
- SelfdestuctCheckState2[SelfdestuctCheckState2["DELEGATECALL"] = 3] = "DELEGATECALL";
28637
- SelfdestuctCheckState2[SelfdestuctCheckState2["SAFE"] = 4] = "SAFE";
28638
- SelfdestuctCheckState2[SelfdestuctCheckState2["SELF_DESTRUCT"] = 5] = "SELF_DESTRUCT";
28639
- return SelfdestuctCheckState2;
28640
- })(SelfdestuctCheckState || {});
28707
+ var SelfdestructCheckState = /* @__PURE__ */ ((SelfdestructCheckState2) => {
28708
+ SelfdestructCheckState2[SelfdestructCheckState2["TRUSTED"] = 0] = "TRUSTED";
28709
+ SelfdestructCheckState2[SelfdestructCheckState2["EOA"] = 1] = "EOA";
28710
+ SelfdestructCheckState2[SelfdestructCheckState2["EMPTY"] = 2] = "EMPTY";
28711
+ SelfdestructCheckState2[SelfdestructCheckState2["DELEGATECALL"] = 3] = "DELEGATECALL";
28712
+ SelfdestructCheckState2[SelfdestructCheckState2["SAFE"] = 4] = "SAFE";
28713
+ SelfdestructCheckState2[SelfdestructCheckState2["SELF_DESTRUCT"] = 5] = "SELF_DESTRUCT";
28714
+ return SelfdestructCheckState2;
28715
+ })(SelfdestructCheckState || {});
28716
+ function selfDestructStatusToString(state) {
28717
+ switch (state) {
28718
+ case 0 /* TRUSTED */:
28719
+ return "Trusted";
28720
+ case 1 /* EOA */:
28721
+ return "EOA";
28722
+ case 2 /* EMPTY */:
28723
+ return "Empty";
28724
+ case 3 /* DELEGATECALL */:
28725
+ return "DelegateCall";
28726
+ case 4 /* SAFE */:
28727
+ return "Safe";
28728
+ case 5 /* SELF_DESTRUCT */:
28729
+ return "SelfDestruct";
28730
+ default:
28731
+ return "Unknown";
28732
+ }
28733
+ }
28641
28734
  async function checkForSelfdestruct(client, addresses, trustedAddresses) {
28642
28735
  const result = [];
28643
28736
  for (const address of addresses) {
@@ -28648,7 +28741,8 @@ async function checkForSelfdestruct(client, addresses, trustedAddresses) {
28648
28741
  const code = await getBytecode2(client, { address });
28649
28742
  if (!code) {
28650
28743
  const nonce = await getTransactionCount(client, { address });
28651
- if (nonce > 0) result.push({ address, state: 1 /* EOA */ });
28744
+ if (nonce > 0)
28745
+ result.push({ address, state: 1 /* EOA */ });
28652
28746
  else result.push({ address, state: 2 /* EMPTY */ });
28653
28747
  continue;
28654
28748
  }
@@ -28687,6 +28781,22 @@ function checkCode(bytecode) {
28687
28781
 
28688
28782
  // src/seatbelt/verified.ts
28689
28783
  import { getCode } from "viem/actions";
28784
+ var VerificationStatus = /* @__PURE__ */ ((VerificationStatus2) => {
28785
+ VerificationStatus2[VerificationStatus2["EOA"] = 0] = "EOA";
28786
+ VerificationStatus2[VerificationStatus2["CONTRACT"] = 1] = "CONTRACT";
28787
+ VerificationStatus2[VerificationStatus2["ERROR"] = 2] = "ERROR";
28788
+ return VerificationStatus2;
28789
+ })(VerificationStatus || {});
28790
+ function verificationStatusToString(status) {
28791
+ switch (status) {
28792
+ case 0 /* EOA */:
28793
+ return "EOA";
28794
+ case 1 /* CONTRACT */:
28795
+ return "Contract";
28796
+ case 2 /* ERROR */:
28797
+ return "Error";
28798
+ }
28799
+ }
28690
28800
  async function getVerificationStatus({
28691
28801
  client,
28692
28802
  addresses,
@@ -28735,73 +28845,6 @@ async function getVerificationStatus({
28735
28845
  return results;
28736
28846
  }
28737
28847
 
28738
- // src/seatbelt/tenderly-report.ts
28739
- async function renderTenderlyReport({
28740
- client,
28741
- sim,
28742
- payloadId,
28743
- payload,
28744
- onchainLogs: { createdLog, queuedLog, executedLog }
28745
- }) {
28746
- const logs = parseLogs({
28747
- logs: (sim.transaction.transaction_info.logs || []).map((l) => l.raw),
28748
- eventDb: EVENT_DB
28749
- });
28750
- const selfDestruct = checkForSelfdestruct(
28751
- client,
28752
- sim.transaction.addresses,
28753
- []
28754
- // trusted addresses
28755
- );
28756
- const verified = getVerificationStatus({
28757
- client,
28758
- addresses: sim.transaction.addresses,
28759
- contractDb: {}
28760
- });
28761
- let report = `## Payload ${payloadId} on ${client.chain.name}
28762
-
28763
- - creator: ${payload.creator}
28764
- - maximumAccessLevelRequired: ${payload.maximumAccessLevelRequired}
28765
- - state: ${payload.state}(${HUMAN_READABLE_PAYLOAD_STATE[payload.state]})
28766
- - actions:
28767
- ${payload.actions.map((a) => ` - [${a.target}](${toTxLink(a.target, client)}), accessLevel: ${a.accessLevel}, withDelegateCall: ${a.withDelegateCall}, value: ${a.value}, signature: ${a.signature}, callData: ${a.callData}`).join("\n")}
28768
- - createdAt: [${renderUnixTime(payload.createdAt)}](${toTxLink(createdLog.transactionHash, client)})
28769
- `;
28770
- if (queuedLog) {
28771
- report += `- queuedAt: [${renderUnixTime(payload.queuedAt)}](${toTxLink(
28772
- queuedLog.transactionHash,
28773
- client
28774
- )})
28775
- `;
28776
- if (executedLog) {
28777
- report += `- executedAt: [${renderUnixTime(payload.executedAt)}, block: ${executedLog.blockNumber}](${toTxLink(
28778
- executedLog.transactionHash,
28779
- client
28780
- )})
28781
- `;
28782
- } else {
28783
- report += `- earliest execution at: [${renderUnixTime(
28784
- payload.queuedAt + payload.delay
28785
- )}](https://www.epochconverter.com/countdown?q=${payload.queuedAt + payload.delay})
28786
- `;
28787
- const timestamp = Math.floor(
28788
- new Date(sim.transaction.timestamp).getTime() / 1e3
28789
- );
28790
- report += `- simulatedExecutionAt: ${renderUnixTime(
28791
- timestamp
28792
- )}, timestamp: ${timestamp}, block: ${sim.transaction.block_number}`;
28793
- }
28794
- }
28795
- report += "\n";
28796
- return report;
28797
- }
28798
- function renderUnixTime(time) {
28799
- return new Date(time * 1e3).toLocaleString("en-GB", { timeZone: "UTC" });
28800
- }
28801
- function toTxLink(txn, client) {
28802
- return `${client.chain?.blockExplorers?.default.url}/tx/${txn}`;
28803
- }
28804
-
28805
28848
  // src/seatbelt/state.ts
28806
28849
  import { getAddress as getAddress2 } from "viem";
28807
28850
  function transformTenderlyStateDiff(stateDiff) {
@@ -28826,7 +28869,8 @@ function transformTenderlyStateDiff(stateDiff) {
28826
28869
  changes.push({
28827
28870
  before: oldVal,
28828
28871
  after: newVal,
28829
- name: `Slot \`${w.key}\``
28872
+ type: "raw",
28873
+ name: w.key
28830
28874
  });
28831
28875
  }
28832
28876
  } else if (diff.soltype.simple_type) {
@@ -28846,23 +28890,25 @@ function transformTenderlyStateDiff(stateDiff) {
28846
28890
  const original = diff.original || {};
28847
28891
  const dirty = diff.dirty || {};
28848
28892
  for (const k of keys) {
28849
- if (original[k] || dirty[k])
28893
+ if (original[k] || dirty[k]) {
28894
+ const objDiff = getObjectDiff(original[k], dirty[k]);
28850
28895
  changes.push({
28851
- before: original[k],
28852
- after: dirty[k],
28853
- name: k,
28854
- type: diff.soltype?.name
28896
+ before: objDiff.before,
28897
+ after: objDiff.after,
28898
+ name: diff.soltype?.name,
28899
+ type: diff.soltype?.type,
28900
+ key: k
28855
28901
  });
28902
+ }
28856
28903
  }
28857
28904
  } else {
28858
28905
  for (const w of diff.raw) {
28859
- const oldVal = JSON.stringify(w.original);
28860
- const newVal = JSON.stringify(w.dirty);
28906
+ const diff2 = getObjectDiff(w.original, w.dirty);
28861
28907
  changes.push({
28862
- before: oldVal,
28863
- after: newVal,
28908
+ before: diff2.before,
28909
+ after: diff2.after,
28864
28910
  name: w.key,
28865
- type: "slot"
28911
+ type: "raw"
28866
28912
  });
28867
28913
  }
28868
28914
  }
@@ -28871,6 +28917,213 @@ function transformTenderlyStateDiff(stateDiff) {
28871
28917
  }
28872
28918
  return allChanges;
28873
28919
  }
28920
+ function getObjectDiff(obj1, obj2) {
28921
+ const diff = { before: {}, after: {} };
28922
+ const allKeys = /* @__PURE__ */ new Set([...Object.keys(obj1), ...Object.keys(obj2)]);
28923
+ for (const key of allKeys) {
28924
+ const val1 = obj1[key];
28925
+ const val2 = obj2[key];
28926
+ if (JSON.stringify(val1) !== JSON.stringify(val2)) {
28927
+ diff.before[key] = val1;
28928
+ diff.after[key] = val2;
28929
+ }
28930
+ }
28931
+ return diff;
28932
+ }
28933
+ function renderMarkdownStateDiffReport(changes, getContractName = (address) => `${address}`) {
28934
+ let report = "";
28935
+ for (const contract of Object.keys(changes)) {
28936
+ report += `## ${getContractName(contract)}
28937
+
28938
+ `;
28939
+ for (const change of changes[contract]) {
28940
+ if (typeof change.before !== "object" || typeof change.after !== "object") {
28941
+ report += `@@ \`${change.name}\` ${change.type} ${change.key ? `key \`${change.key}\`` : ""} @@
28942
+ `;
28943
+ report += `- ${change.before}
28944
+ `;
28945
+ report += `+ ${change.after}
28946
+
28947
+ `;
28948
+ } else {
28949
+ report += deepDiff(change);
28950
+ }
28951
+ }
28952
+ }
28953
+ return report;
28954
+ }
28955
+ function deepDiff({
28956
+ name,
28957
+ type: type2,
28958
+ before,
28959
+ after,
28960
+ key,
28961
+ path
28962
+ }) {
28963
+ let diff = "";
28964
+ const allKeys = /* @__PURE__ */ new Set([...Object.keys(before), ...Object.keys(after)]);
28965
+ for (const pathKey of allKeys) {
28966
+ if (typeof before[pathKey] !== "object" || typeof after[pathKey] !== "object") {
28967
+ diff += `@@ \`${name}\` ${type2} ${key ? `key \`${key}\`` : ""}.${path ?? ""}${pathKey} @@
28968
+ `;
28969
+ diff += `- ${JSON.stringify(before[pathKey])}
28970
+ `;
28971
+ diff += `+ ${JSON.stringify(after[pathKey])}
28972
+
28973
+ `;
28974
+ } else {
28975
+ return deepDiff({
28976
+ name,
28977
+ type: type2,
28978
+ before: before[pathKey],
28979
+ after: after[pathKey],
28980
+ key,
28981
+ path: path ? `${path}.${pathKey}` : `${pathKey}.`
28982
+ });
28983
+ }
28984
+ }
28985
+ return diff;
28986
+ }
28987
+
28988
+ // src/seatbelt/tenderly-report.ts
28989
+ async function renderTenderlyReport({
28990
+ client,
28991
+ sim,
28992
+ payloadId,
28993
+ payload,
28994
+ onchainLogs: { createdLog, queuedLog, executedLog },
28995
+ eventCache = [],
28996
+ config
28997
+ }) {
28998
+ const events = sim.transaction.transaction_info?.logs ? tenderly_logsToAbiLogs(sim.transaction.transaction_info?.logs) : [];
28999
+ events.map((e) => {
29000
+ if (!eventCache.find((eC) => JSON.stringify(eC) === JSON.stringify(e))) {
29001
+ eventCache.push(e);
29002
+ }
29003
+ });
29004
+ const logs = parseLogs({
29005
+ logs: (sim.transaction.transaction_info.logs || []).map((l) => l.raw),
29006
+ eventDb: eventCache
29007
+ });
29008
+ const selfDestruct = await checkForSelfdestruct(
29009
+ client,
29010
+ sim.transaction.addresses,
29011
+ []
29012
+ // trusted addresses
29013
+ );
29014
+ const verified = await getVerificationStatus({
29015
+ client,
29016
+ addresses: sim.transaction.addresses,
29017
+ // In the future we might want to maintain our own db, so we do not need to rely on tenderly so much for contract name lookup.
29018
+ contractDb: sim.contracts.reduce(
29019
+ (acc, val) => {
29020
+ acc[val.address] = val.contract_name;
29021
+ return acc;
29022
+ },
29023
+ {}
29024
+ ),
29025
+ apiKey: config.etherscanApiKey
29026
+ });
29027
+ const stateDiff = transformTenderlyStateDiff(
29028
+ sim.transaction.transaction_info.state_diff
29029
+ );
29030
+ let report = `## Payload ${payloadId} on ${client.chain.name}
29031
+
29032
+ - creator: ${payload.creator}
29033
+ - maximumAccessLevelRequired: ${payload.maximumAccessLevelRequired}
29034
+ - state: ${payload.state}(${HUMAN_READABLE_PAYLOAD_STATE[payload.state]})
29035
+ - actions:
29036
+ ${payload.actions.map(
29037
+ (a) => ` - [${a.target}](${toTxLink(a.target, client)}), accessLevel: ${a.accessLevel}, withDelegateCall: ${a.withDelegateCall}, value: ${a.value}, signature: ${a.signature}, callData: ${a.callData}`
29038
+ ).join("\n")}
29039
+ `;
29040
+ if (createdLog) {
29041
+ report += `- createdAt: [${renderUnixTime(payload.createdAt)}](${toTxLink(
29042
+ createdLog.transactionHash,
29043
+ client
29044
+ )})
29045
+ `;
29046
+ if (queuedLog) {
29047
+ report += `- queuedAt: [${renderUnixTime(payload.queuedAt)}](${toTxLink(
29048
+ queuedLog.transactionHash,
29049
+ client
29050
+ )})
29051
+ `;
29052
+ if (executedLog) {
29053
+ report += `- executedAt: [${renderUnixTime(payload.executedAt)}, block: ${executedLog.blockNumber}](${toTxLink(executedLog.transactionHash, client)})
29054
+ `;
29055
+ } else {
29056
+ report += `- earliest execution at: [${renderUnixTime(
29057
+ payload.queuedAt + payload.delay
29058
+ )}](https://www.epochconverter.com/countdown?q=${payload.queuedAt + payload.delay})
29059
+ `;
29060
+ const timestamp = Math.floor(
29061
+ new Date(sim.transaction.timestamp).getTime() / 1e3
29062
+ );
29063
+ report += `- simulatedExecutionAt: ${renderUnixTime(
29064
+ timestamp
29065
+ )}, timestamp: ${timestamp}, block: ${sim.transaction.block_number}`;
29066
+ }
29067
+ }
29068
+ }
29069
+ report += "\n";
29070
+ if (verified.find((contract) => contract.status === 2 /* ERROR */)) {
29071
+ report += `:sos: Found unverified contracts!
29072
+
29073
+ `;
29074
+ }
29075
+ if (selfDestruct.find(
29076
+ (contract) => contract.state === 5 /* SELF_DESTRUCT */
29077
+ )) {
29078
+ report += `:sos: Found selfDestruct!
29079
+
29080
+ `;
29081
+ }
29082
+ report += renderMarkdownStateDiffReport(stateDiff);
29083
+ if (verified.length) {
29084
+ report += "### Verification status for contracts touched in the proposal\n\n";
29085
+ report += "| Contract | Status |\n";
29086
+ report += "|---------|------------|\n";
29087
+ verified.map((contract) => {
29088
+ report += `| ${contract.address}(${contract.name}) | ${verificationStatusToString(contract.status)} |
29089
+ `;
29090
+ });
29091
+ report += "\n";
29092
+ }
29093
+ if (selfDestruct.length) {
29094
+ report += `### Selfdestruct analysis
29095
+
29096
+ `;
29097
+ report += "| Address | Result |\n";
29098
+ report += "|---------|------------|\n";
29099
+ selfDestruct.map((selfDestruct2) => {
29100
+ report += `| ${selfDestruct2.address} | ${selfDestructStatusToString(
29101
+ selfDestruct2.state
29102
+ )} |
29103
+ `;
29104
+ });
29105
+ report += "\n";
29106
+ }
29107
+ if (logs.length) {
29108
+ report += "### Events emitted from the proposal\n\n";
29109
+ report += "| Address | Event Name | Arguments |\n";
29110
+ report += "|---------|------------|-----------|\n";
29111
+ logs.map((log) => {
29112
+ report += `| ${log.address} | ${log.eventName || log.topics} | ${log.args ? JSON.stringify(
29113
+ log.args,
29114
+ (_, v) => typeof v === "bigint" ? v.toString() : v
29115
+ ) : log.data} |
29116
+ `;
29117
+ });
29118
+ }
29119
+ return { report, eventCache };
29120
+ }
29121
+ function renderUnixTime(time) {
29122
+ return new Date(time * 1e3).toLocaleString("en-GB", { timeZone: "UTC" });
29123
+ }
29124
+ function toTxLink(txn, client) {
29125
+ return `${client.chain?.blockExplorers?.default.url}/tx/${txn}`;
29126
+ }
28874
29127
 
28875
29128
  // src/ecosystem/foundry.ts
28876
29129
  import { execSync } from "node:child_process";
@@ -28960,7 +29213,9 @@ export {
28960
29213
  ProposalState,
28961
29214
  RAY,
28962
29215
  SECONDS_PER_YEAR,
28963
- SelfdestuctCheckState,
29216
+ SelfdestructCheckState,
29217
+ SoltypeType,
29218
+ VerificationStatus,
28964
29219
  WAD,
28965
29220
  WAD_RAY_RATIO,
28966
29221
  aaveAddressesProvider_IncentivesControllerSlot,
@@ -29011,6 +29266,7 @@ export {
29011
29266
  getNonFinalizedProposals,
29012
29267
  getNormalizedDebt,
29013
29268
  getNormalizedIncome,
29269
+ getObjectDiff,
29014
29270
  getPayloadStorageOverrides,
29015
29271
  getPayloadsController,
29016
29272
  getPublicRpc,
@@ -29035,17 +29291,21 @@ export {
29035
29291
  rayDiv,
29036
29292
  rayMul,
29037
29293
  rayToWad,
29294
+ renderMarkdownStateDiffReport,
29038
29295
  renderTenderlyReport,
29039
29296
  routescanExplorers,
29297
+ selfDestructStatusToString,
29040
29298
  setBits,
29041
29299
  tenderly_createVnet,
29042
29300
  tenderly_deleteVnet,
29043
29301
  tenderly_getVnet,
29302
+ tenderly_logsToAbiLogs,
29044
29303
  tenderly_sim,
29045
29304
  tenderly_simVnet,
29046
29305
  toTxLink,
29047
29306
  transformTenderlyStateDiff,
29048
29307
  validateAip,
29308
+ verificationStatusToString,
29049
29309
  wadDiv,
29050
29310
  wadToRay
29051
29311
  };