@gzeoneth/gov-tracker 0.1.0 → 0.1.1-1
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/README.md +75 -119
- package/dist/calldata/address-utils.d.ts +22 -0
- package/dist/calldata/address-utils.d.ts.map +1 -0
- package/dist/calldata/address-utils.js +84 -0
- package/dist/calldata/address-utils.js.map +1 -0
- package/dist/calldata/decoder.d.ts +27 -0
- package/dist/calldata/decoder.d.ts.map +1 -0
- package/dist/calldata/decoder.js +245 -0
- package/dist/calldata/decoder.js.map +1 -0
- package/dist/calldata/index.d.ts +13 -0
- package/dist/calldata/index.d.ts.map +1 -0
- package/dist/calldata/index.js +46 -0
- package/dist/calldata/index.js.map +1 -0
- package/dist/calldata/parameter-decoder.d.ts +44 -0
- package/dist/calldata/parameter-decoder.d.ts.map +1 -0
- package/dist/calldata/parameter-decoder.js +164 -0
- package/dist/calldata/parameter-decoder.js.map +1 -0
- package/dist/calldata/retryable-ticket.d.ts +55 -0
- package/dist/calldata/retryable-ticket.d.ts.map +1 -0
- package/dist/calldata/retryable-ticket.js +104 -0
- package/dist/calldata/retryable-ticket.js.map +1 -0
- package/dist/calldata/signature-lookup.d.ts +46 -0
- package/dist/calldata/signature-lookup.d.ts.map +1 -0
- package/dist/calldata/signature-lookup.js +160 -0
- package/dist/calldata/signature-lookup.js.map +1 -0
- package/dist/cli/lib/cli.d.ts +74 -6
- package/dist/cli/lib/cli.d.ts.map +1 -1
- package/dist/cli/lib/cli.js +240 -69
- package/dist/cli/lib/cli.js.map +1 -1
- package/dist/cli/monitor.js +258 -111
- package/dist/cli/monitor.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +48 -3
- package/dist/index.js.map +1 -1
- package/dist/simulation/address-alias.d.ts +35 -0
- package/dist/simulation/address-alias.d.ts.map +1 -0
- package/dist/simulation/address-alias.js +46 -0
- package/dist/simulation/address-alias.js.map +1 -0
- package/dist/simulation/index.d.ts +9 -0
- package/dist/simulation/index.d.ts.map +1 -0
- package/dist/simulation/index.js +26 -0
- package/dist/simulation/index.js.map +1 -0
- package/dist/simulation/simulation-data.d.ts +77 -0
- package/dist/simulation/simulation-data.d.ts.map +1 -0
- package/dist/simulation/simulation-data.js +327 -0
- package/dist/simulation/simulation-data.js.map +1 -0
- package/dist/stages/l2-to-l1-message.d.ts +2 -2
- package/dist/stages/l2-to-l1-message.d.ts.map +1 -1
- package/dist/stages/l2-to-l1-message.js +5 -3
- package/dist/stages/l2-to-l1-message.js.map +1 -1
- package/dist/stages/retryables.d.ts +2 -2
- package/dist/stages/retryables.d.ts.map +1 -1
- package/dist/stages/retryables.js +5 -3
- package/dist/stages/retryables.js.map +1 -1
- package/dist/stages/timelock.d.ts.map +1 -1
- package/dist/stages/timelock.js +5 -3
- package/dist/stages/timelock.js.map +1 -1
- package/dist/stages/voting.d.ts.map +1 -1
- package/dist/stages/voting.js +15 -4
- package/dist/stages/voting.js.map +1 -1
- package/dist/tracker/execute.d.ts.map +1 -1
- package/dist/tracker/execute.js +34 -22
- package/dist/tracker/execute.js.map +1 -1
- package/dist/tracker.d.ts.map +1 -1
- package/dist/tracker.js +6 -2
- package/dist/tracker.js.map +1 -1
- package/dist/types/calldata.d.ts +95 -0
- package/dist/types/calldata.d.ts.map +1 -0
- package/dist/types/calldata.js +9 -0
- package/dist/types/calldata.js.map +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/simulation.d.ts +101 -0
- package/dist/types/simulation.d.ts.map +1 -0
- package/dist/types/simulation.js +9 -0
- package/dist/types/simulation.js.map +1 -0
- package/dist/types/stages.d.ts +4 -0
- package/dist/types/stages.d.ts.map +1 -1
- package/dist/types/stages.js.map +1 -1
- package/dist/types/tracking.d.ts +2 -1
- package/dist/types/tracking.d.ts.map +1 -1
- package/dist/utils/error-classification.d.ts +13 -0
- package/dist/utils/error-classification.d.ts.map +1 -0
- package/dist/utils/error-classification.js +28 -0
- package/dist/utils/error-classification.js.map +1 -0
- package/dist/utils/stage-helpers.d.ts +1 -1
- package/dist/utils/stage-helpers.d.ts.map +1 -1
- package/dist/utils/stage-helpers.js +1 -1
- package/dist/utils/stage-helpers.js.map +1 -1
- package/dist/utils/urls.d.ts +24 -1
- package/dist/utils/urls.d.ts.map +1 -1
- package/dist/utils/urls.js +50 -0
- package/dist/utils/urls.js.map +1 -1
- package/package.json +6 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/calldata/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAGhE,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAGrE,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGvF,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Calldata Decoding Module
|
|
4
|
+
*
|
|
5
|
+
* Exports for recursive calldata decoding, signature lookup,
|
|
6
|
+
* and address utilities.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.retryableChainToContext = exports.getRetryableChainName = exports.decodeRetryableTicket = exports.detectChainFromInbox = exports.isRetryableTicketMagic = exports.NOVA_DELAYED_INBOX = exports.ARB1_DELAYED_INBOX = exports.RETRYABLE_TICKET_MAGIC = exports.getChainLabel = exports.getTxExplorerUrl = exports.getAddressExplorerUrl = exports.getKnownAddresses = exports.getAddressLabel = exports.decodeParameters = exports.formatDecodedValue = exports.isLikelyCalldata = exports.parseParamTypes = exports.clearSignatureCache = exports.extractFunctionName = exports.lookup4byteDirectory = exports.lookupLocalSignature = exports.lookupSignature = exports.decodeCalldataArray = exports.decodeCalldata = void 0;
|
|
10
|
+
// Main decoder
|
|
11
|
+
var decoder_1 = require("./decoder");
|
|
12
|
+
Object.defineProperty(exports, "decodeCalldata", { enumerable: true, get: function () { return decoder_1.decodeCalldata; } });
|
|
13
|
+
Object.defineProperty(exports, "decodeCalldataArray", { enumerable: true, get: function () { return decoder_1.decodeCalldataArray; } });
|
|
14
|
+
// Signature lookup
|
|
15
|
+
var signature_lookup_1 = require("./signature-lookup");
|
|
16
|
+
Object.defineProperty(exports, "lookupSignature", { enumerable: true, get: function () { return signature_lookup_1.lookupSignature; } });
|
|
17
|
+
Object.defineProperty(exports, "lookupLocalSignature", { enumerable: true, get: function () { return signature_lookup_1.lookupLocalSignature; } });
|
|
18
|
+
Object.defineProperty(exports, "lookup4byteDirectory", { enumerable: true, get: function () { return signature_lookup_1.lookup4byteDirectory; } });
|
|
19
|
+
Object.defineProperty(exports, "extractFunctionName", { enumerable: true, get: function () { return signature_lookup_1.extractFunctionName; } });
|
|
20
|
+
Object.defineProperty(exports, "clearSignatureCache", { enumerable: true, get: function () { return signature_lookup_1.clearSignatureCache; } });
|
|
21
|
+
// Parameter decoder
|
|
22
|
+
var parameter_decoder_1 = require("./parameter-decoder");
|
|
23
|
+
Object.defineProperty(exports, "parseParamTypes", { enumerable: true, get: function () { return parameter_decoder_1.parseParamTypes; } });
|
|
24
|
+
Object.defineProperty(exports, "isLikelyCalldata", { enumerable: true, get: function () { return parameter_decoder_1.isLikelyCalldata; } });
|
|
25
|
+
Object.defineProperty(exports, "formatDecodedValue", { enumerable: true, get: function () { return parameter_decoder_1.formatDecodedValue; } });
|
|
26
|
+
Object.defineProperty(exports, "decodeParameters", { enumerable: true, get: function () { return parameter_decoder_1.decodeParameters; } });
|
|
27
|
+
// Address utilities
|
|
28
|
+
var address_utils_1 = require("./address-utils");
|
|
29
|
+
Object.defineProperty(exports, "getAddressLabel", { enumerable: true, get: function () { return address_utils_1.getAddressLabel; } });
|
|
30
|
+
Object.defineProperty(exports, "getKnownAddresses", { enumerable: true, get: function () { return address_utils_1.getKnownAddresses; } });
|
|
31
|
+
// URL utilities
|
|
32
|
+
var urls_1 = require("../utils/urls");
|
|
33
|
+
Object.defineProperty(exports, "getAddressExplorerUrl", { enumerable: true, get: function () { return urls_1.getAddressExplorerUrl; } });
|
|
34
|
+
Object.defineProperty(exports, "getTxExplorerUrl", { enumerable: true, get: function () { return urls_1.getTxExplorerUrl; } });
|
|
35
|
+
Object.defineProperty(exports, "getChainLabel", { enumerable: true, get: function () { return urls_1.getChainLabel; } });
|
|
36
|
+
// Retryable ticket
|
|
37
|
+
var retryable_ticket_1 = require("./retryable-ticket");
|
|
38
|
+
Object.defineProperty(exports, "RETRYABLE_TICKET_MAGIC", { enumerable: true, get: function () { return retryable_ticket_1.RETRYABLE_TICKET_MAGIC; } });
|
|
39
|
+
Object.defineProperty(exports, "ARB1_DELAYED_INBOX", { enumerable: true, get: function () { return retryable_ticket_1.ARB1_DELAYED_INBOX; } });
|
|
40
|
+
Object.defineProperty(exports, "NOVA_DELAYED_INBOX", { enumerable: true, get: function () { return retryable_ticket_1.NOVA_DELAYED_INBOX; } });
|
|
41
|
+
Object.defineProperty(exports, "isRetryableTicketMagic", { enumerable: true, get: function () { return retryable_ticket_1.isRetryableTicketMagic; } });
|
|
42
|
+
Object.defineProperty(exports, "detectChainFromInbox", { enumerable: true, get: function () { return retryable_ticket_1.detectChainFromInbox; } });
|
|
43
|
+
Object.defineProperty(exports, "decodeRetryableTicket", { enumerable: true, get: function () { return retryable_ticket_1.decodeRetryableTicket; } });
|
|
44
|
+
Object.defineProperty(exports, "getRetryableChainName", { enumerable: true, get: function () { return retryable_ticket_1.getRetryableChainName; } });
|
|
45
|
+
Object.defineProperty(exports, "retryableChainToContext", { enumerable: true, get: function () { return retryable_ticket_1.retryableChainToContext; } });
|
|
46
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/calldata/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,eAAe;AACf,qCAAgE;AAAvD,yGAAA,cAAc,OAAA;AAAE,8GAAA,mBAAmB,OAAA;AAE5C,mBAAmB;AACnB,uDAM4B;AAL1B,mHAAA,eAAe,OAAA;AACf,wHAAA,oBAAoB,OAAA;AACpB,wHAAA,oBAAoB,OAAA;AACpB,uHAAA,mBAAmB,OAAA;AACnB,uHAAA,mBAAmB,OAAA;AAGrB,oBAAoB;AACpB,yDAK6B;AAJ3B,oHAAA,eAAe,OAAA;AACf,qHAAA,gBAAgB,OAAA;AAChB,uHAAA,kBAAkB,OAAA;AAClB,qHAAA,gBAAgB,OAAA;AAGlB,oBAAoB;AACpB,iDAAqE;AAA5D,gHAAA,eAAe,OAAA;AAAE,kHAAA,iBAAiB,OAAA;AAE3C,gBAAgB;AAChB,sCAAuF;AAA9E,6GAAA,qBAAqB,OAAA;AAAE,wGAAA,gBAAgB,OAAA;AAAE,qGAAA,aAAa,OAAA;AAE/D,mBAAmB;AACnB,uDAS4B;AAR1B,0HAAA,sBAAsB,OAAA;AACtB,sHAAA,kBAAkB,OAAA;AAClB,sHAAA,kBAAkB,OAAA;AAClB,0HAAA,sBAAsB,OAAA;AACtB,wHAAA,oBAAoB,OAAA;AACpB,yHAAA,qBAAqB,OAAA;AACrB,yHAAA,qBAAqB,OAAA;AACrB,2HAAA,uBAAuB,OAAA"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parameter Decoder
|
|
3
|
+
*
|
|
4
|
+
* Decodes ABI-encoded parameters from calldata into typed values.
|
|
5
|
+
* Handles complex types like tuples, arrays, and provides formatting.
|
|
6
|
+
*/
|
|
7
|
+
import { ethers } from "ethers";
|
|
8
|
+
import type { ChainContext, DecodedParameter } from "../types/calldata";
|
|
9
|
+
/**
|
|
10
|
+
* Parse parameter types from function signature
|
|
11
|
+
* Handles nested types like tuples and arrays
|
|
12
|
+
*
|
|
13
|
+
* @param typesStr - Parameter types string (e.g., "address,uint256,bytes")
|
|
14
|
+
* @returns Array of individual type strings
|
|
15
|
+
*/
|
|
16
|
+
export declare function parseParamTypes(typesStr: string): string[];
|
|
17
|
+
/**
|
|
18
|
+
* Check if a value looks like calldata (for nested decoding)
|
|
19
|
+
*
|
|
20
|
+
* @param value - Hex string to check
|
|
21
|
+
* @returns True if it looks like valid calldata
|
|
22
|
+
*/
|
|
23
|
+
export declare function isLikelyCalldata(value: string): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Format a decoded value for display
|
|
26
|
+
*
|
|
27
|
+
* @param value - The raw decoded value
|
|
28
|
+
* @param type - Solidity type string
|
|
29
|
+
* @returns Formatted string representation
|
|
30
|
+
*/
|
|
31
|
+
export declare function formatDecodedValue(value: unknown, type: string): string;
|
|
32
|
+
/**
|
|
33
|
+
* Decode parameters from calldata using signature
|
|
34
|
+
*
|
|
35
|
+
* @param calldata - Full calldata hex string (with selector)
|
|
36
|
+
* @param signature - Function signature (e.g., "transfer(address,uint256)")
|
|
37
|
+
* @param chainContext - Chain for address resolution
|
|
38
|
+
* @returns Array of decoded parameters, or null if decoding fails
|
|
39
|
+
*/
|
|
40
|
+
export declare function decodeParameters(calldata: string, signature: string, chainContext: ChainContext): {
|
|
41
|
+
params: DecodedParameter[];
|
|
42
|
+
decoded: ethers.utils.Result;
|
|
43
|
+
} | null;
|
|
44
|
+
//# sourceMappingURL=parameter-decoder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parameter-decoder.d.ts","sourceRoot":"","sources":["../../src/calldata/parameter-decoder.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAGxE;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAmB1D;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAUvD;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAuCvE;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,YAAY,GACzB;IAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAA;CAAE,GAAG,IAAI,CAwDrE"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Parameter Decoder
|
|
4
|
+
*
|
|
5
|
+
* Decodes ABI-encoded parameters from calldata into typed values.
|
|
6
|
+
* Handles complex types like tuples, arrays, and provides formatting.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.parseParamTypes = parseParamTypes;
|
|
10
|
+
exports.isLikelyCalldata = isLikelyCalldata;
|
|
11
|
+
exports.formatDecodedValue = formatDecodedValue;
|
|
12
|
+
exports.decodeParameters = decodeParameters;
|
|
13
|
+
const ethers_1 = require("ethers");
|
|
14
|
+
const address_utils_1 = require("./address-utils");
|
|
15
|
+
/**
|
|
16
|
+
* Parse parameter types from function signature
|
|
17
|
+
* Handles nested types like tuples and arrays
|
|
18
|
+
*
|
|
19
|
+
* @param typesStr - Parameter types string (e.g., "address,uint256,bytes")
|
|
20
|
+
* @returns Array of individual type strings
|
|
21
|
+
*/
|
|
22
|
+
function parseParamTypes(typesStr) {
|
|
23
|
+
const types = [];
|
|
24
|
+
let depth = 0;
|
|
25
|
+
let current = "";
|
|
26
|
+
for (const char of typesStr) {
|
|
27
|
+
if (char === "(" || char === "[")
|
|
28
|
+
depth++;
|
|
29
|
+
if (char === ")" || char === "]")
|
|
30
|
+
depth--;
|
|
31
|
+
if (char === "," && depth === 0) {
|
|
32
|
+
if (current.trim())
|
|
33
|
+
types.push(current.trim());
|
|
34
|
+
current = "";
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
current += char;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
if (current.trim())
|
|
41
|
+
types.push(current.trim());
|
|
42
|
+
return types;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Check if a value looks like calldata (for nested decoding)
|
|
46
|
+
*
|
|
47
|
+
* @param value - Hex string to check
|
|
48
|
+
* @returns True if it looks like valid calldata
|
|
49
|
+
*/
|
|
50
|
+
function isLikelyCalldata(value) {
|
|
51
|
+
if (!value || typeof value !== "string")
|
|
52
|
+
return false;
|
|
53
|
+
if (!value.startsWith("0x"))
|
|
54
|
+
return false;
|
|
55
|
+
// Must have at least selector (4 bytes = 8 hex chars + 0x)
|
|
56
|
+
if (value.length < 10)
|
|
57
|
+
return false;
|
|
58
|
+
// Check if it's all hex
|
|
59
|
+
const hexPattern = /^0x[0-9a-fA-F]+$/;
|
|
60
|
+
return hexPattern.test(value);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Format a decoded value for display
|
|
64
|
+
*
|
|
65
|
+
* @param value - The raw decoded value
|
|
66
|
+
* @param type - Solidity type string
|
|
67
|
+
* @returns Formatted string representation
|
|
68
|
+
*/
|
|
69
|
+
function formatDecodedValue(value, type) {
|
|
70
|
+
// Handle BigNumber
|
|
71
|
+
if (ethers_1.ethers.BigNumber.isBigNumber(value)) {
|
|
72
|
+
const bn = value;
|
|
73
|
+
const strValue = bn.toString();
|
|
74
|
+
// For uint256 that might be ETH amounts, show conversion
|
|
75
|
+
if (type.includes("uint256") && bn.gt(0)) {
|
|
76
|
+
try {
|
|
77
|
+
const ethValue = ethers_1.ethers.utils.formatEther(bn);
|
|
78
|
+
const ethNum = parseFloat(ethValue);
|
|
79
|
+
// Only show ETH conversion for values >= 0.001 ETH
|
|
80
|
+
if (ethNum >= 0.001) {
|
|
81
|
+
return `${strValue} (${ethValue} ETH)`;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
// Ignore formatting errors
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return strValue;
|
|
89
|
+
}
|
|
90
|
+
// Handle arrays
|
|
91
|
+
if (Array.isArray(value)) {
|
|
92
|
+
const elementType = type.endsWith("[]") ? type.slice(0, -2) : type;
|
|
93
|
+
const formatted = value.map((v) => formatDecodedValue(v, elementType));
|
|
94
|
+
return `[${formatted.join(", ")}]`;
|
|
95
|
+
}
|
|
96
|
+
// Handle bytes - truncate middle for readability
|
|
97
|
+
if (typeof value === "string" && value.startsWith("0x") && value.length > 34) {
|
|
98
|
+
const prefix = value.slice(0, 18);
|
|
99
|
+
const suffix = value.slice(-16);
|
|
100
|
+
return `${prefix}...${suffix}`;
|
|
101
|
+
}
|
|
102
|
+
// Default: convert to string
|
|
103
|
+
return String(value);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Decode parameters from calldata using signature
|
|
107
|
+
*
|
|
108
|
+
* @param calldata - Full calldata hex string (with selector)
|
|
109
|
+
* @param signature - Function signature (e.g., "transfer(address,uint256)")
|
|
110
|
+
* @param chainContext - Chain for address resolution
|
|
111
|
+
* @returns Array of decoded parameters, or null if decoding fails
|
|
112
|
+
*/
|
|
113
|
+
function decodeParameters(calldata, signature, chainContext) {
|
|
114
|
+
try {
|
|
115
|
+
// Extract parameter types from signature
|
|
116
|
+
const match = signature.match(/\((.+)\)$/);
|
|
117
|
+
if (!match)
|
|
118
|
+
return null;
|
|
119
|
+
const typesStr = match[1];
|
|
120
|
+
const paramTypes = parseParamTypes(typesStr);
|
|
121
|
+
// Remove selector (first 4 bytes = 10 chars including 0x)
|
|
122
|
+
const encodedParams = "0x" + calldata.slice(10);
|
|
123
|
+
// Decode using ethers
|
|
124
|
+
const abiCoder = new ethers_1.ethers.utils.AbiCoder();
|
|
125
|
+
const decoded = abiCoder.decode(paramTypes, encodedParams);
|
|
126
|
+
// Format into DecodedParameter array
|
|
127
|
+
const params = paramTypes.map((type, index) => {
|
|
128
|
+
const rawValue = decoded[index];
|
|
129
|
+
const param = {
|
|
130
|
+
name: `arg${index}`,
|
|
131
|
+
type,
|
|
132
|
+
value: formatDecodedValue(rawValue, type),
|
|
133
|
+
rawValue: rawValue,
|
|
134
|
+
isNested: false,
|
|
135
|
+
};
|
|
136
|
+
// Handle address type - add label
|
|
137
|
+
if (type === "address") {
|
|
138
|
+
const addr = String(rawValue);
|
|
139
|
+
const label = (0, address_utils_1.getAddressLabel)(addr, chainContext);
|
|
140
|
+
if (label)
|
|
141
|
+
param.addressLabel = label;
|
|
142
|
+
}
|
|
143
|
+
// Handle bytes type - check if nested calldata
|
|
144
|
+
if (type === "bytes") {
|
|
145
|
+
const bytesValue = String(rawValue);
|
|
146
|
+
if (isLikelyCalldata(bytesValue)) {
|
|
147
|
+
param.isNested = true;
|
|
148
|
+
}
|
|
149
|
+
param.value = bytesValue;
|
|
150
|
+
}
|
|
151
|
+
// Handle bytes[] - store raw array for nested processing
|
|
152
|
+
if (type === "bytes[]" && Array.isArray(rawValue)) {
|
|
153
|
+
param._rawBytesArray = rawValue.map((b) => String(b));
|
|
154
|
+
param.isNested = true;
|
|
155
|
+
}
|
|
156
|
+
return param;
|
|
157
|
+
});
|
|
158
|
+
return { params, decoded };
|
|
159
|
+
}
|
|
160
|
+
catch (_error) {
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=parameter-decoder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parameter-decoder.js","sourceRoot":"","sources":["../../src/calldata/parameter-decoder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retryable Ticket Decoder
|
|
3
|
+
*
|
|
4
|
+
* Extracts and parses Arbitrum L1→L2 retryable ticket data from calldata.
|
|
5
|
+
*/
|
|
6
|
+
import type { RetryableTicketData, ChainContext } from "../types/calldata";
|
|
7
|
+
/**
|
|
8
|
+
* Magic address that indicates a retryable ticket in timelock operations
|
|
9
|
+
* When a timelock target is this address, the calldata contains a retryable tuple
|
|
10
|
+
*/
|
|
11
|
+
export declare const RETRYABLE_TICKET_MAGIC = "0xa723c008e76e379c55599d2e4d93879beafda79c";
|
|
12
|
+
/**
|
|
13
|
+
* Delayed inbox addresses for chain detection
|
|
14
|
+
*/
|
|
15
|
+
export declare const ARB1_DELAYED_INBOX = "0x4dbd4fc535ac27206064b68ffcf827b0a60bab3f";
|
|
16
|
+
export declare const NOVA_DELAYED_INBOX = "0xc4448b71118c9071bcb9734a0eac55d18a153949";
|
|
17
|
+
/**
|
|
18
|
+
* Check if an address is the retryable ticket magic address
|
|
19
|
+
*
|
|
20
|
+
* @param target - Target address to check
|
|
21
|
+
* @returns True if this is the retryable ticket magic address
|
|
22
|
+
*/
|
|
23
|
+
export declare function isRetryableTicketMagic(target: string): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Detect L2 chain from inbox address
|
|
26
|
+
*
|
|
27
|
+
* @param inboxAddress - Delayed inbox address on L1
|
|
28
|
+
* @returns Target L2 chain
|
|
29
|
+
*/
|
|
30
|
+
export declare function detectChainFromInbox(inboxAddress: string): "arb1" | "nova" | "unknown";
|
|
31
|
+
/**
|
|
32
|
+
* Get human-readable chain name for display
|
|
33
|
+
*
|
|
34
|
+
* @param chain - Chain identifier
|
|
35
|
+
* @returns Human-readable chain name
|
|
36
|
+
*/
|
|
37
|
+
export declare function getRetryableChainName(chain: "arb1" | "nova" | "unknown"): string;
|
|
38
|
+
/**
|
|
39
|
+
* Decode retryable ticket data from ABI-encoded bytes
|
|
40
|
+
*
|
|
41
|
+
* Retryable tickets are encoded as tuples (NOT calldata) with this structure:
|
|
42
|
+
* (address inbox, address l2Target, uint256 l2Value, uint256 gasLimit, uint256 maxFeePerGas, bytes l2Calldata)
|
|
43
|
+
*
|
|
44
|
+
* @param bytes - ABI-encoded retryable ticket bytes
|
|
45
|
+
* @returns Decoded retryable ticket data, or null if decoding fails
|
|
46
|
+
*/
|
|
47
|
+
export declare function decodeRetryableTicket(bytes: string): RetryableTicketData | null;
|
|
48
|
+
/**
|
|
49
|
+
* Get ChainContext from retryable chain
|
|
50
|
+
*
|
|
51
|
+
* @param chain - Retryable chain identifier
|
|
52
|
+
* @returns ChainContext for address resolution
|
|
53
|
+
*/
|
|
54
|
+
export declare function retryableChainToContext(chain: "arb1" | "nova" | "unknown"): ChainContext;
|
|
55
|
+
//# sourceMappingURL=retryable-ticket.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retryable-ticket.d.ts","sourceRoot":"","sources":["../../src/calldata/retryable-ticket.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE3E;;;GAGG;AACH,eAAO,MAAM,sBAAsB,+CAA+C,CAAC;AAEnF;;GAEG;AACH,eAAO,MAAM,kBAAkB,+CAA+C,CAAC;AAC/E,eAAO,MAAM,kBAAkB,+CAA+C,CAAC;AAE/E;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAMtF;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,CAShF;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CAsB/E;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,YAAY,CAIxF"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Retryable Ticket Decoder
|
|
4
|
+
*
|
|
5
|
+
* Extracts and parses Arbitrum L1→L2 retryable ticket data from calldata.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.NOVA_DELAYED_INBOX = exports.ARB1_DELAYED_INBOX = exports.RETRYABLE_TICKET_MAGIC = void 0;
|
|
9
|
+
exports.isRetryableTicketMagic = isRetryableTicketMagic;
|
|
10
|
+
exports.detectChainFromInbox = detectChainFromInbox;
|
|
11
|
+
exports.getRetryableChainName = getRetryableChainName;
|
|
12
|
+
exports.decodeRetryableTicket = decodeRetryableTicket;
|
|
13
|
+
exports.retryableChainToContext = retryableChainToContext;
|
|
14
|
+
const ethers_1 = require("ethers");
|
|
15
|
+
/**
|
|
16
|
+
* Magic address that indicates a retryable ticket in timelock operations
|
|
17
|
+
* When a timelock target is this address, the calldata contains a retryable tuple
|
|
18
|
+
*/
|
|
19
|
+
exports.RETRYABLE_TICKET_MAGIC = "0xa723c008e76e379c55599d2e4d93879beafda79c";
|
|
20
|
+
/**
|
|
21
|
+
* Delayed inbox addresses for chain detection
|
|
22
|
+
*/
|
|
23
|
+
exports.ARB1_DELAYED_INBOX = "0x4dbd4fc535ac27206064b68ffcf827b0a60bab3f";
|
|
24
|
+
exports.NOVA_DELAYED_INBOX = "0xc4448b71118c9071bcb9734a0eac55d18a153949";
|
|
25
|
+
/**
|
|
26
|
+
* Check if an address is the retryable ticket magic address
|
|
27
|
+
*
|
|
28
|
+
* @param target - Target address to check
|
|
29
|
+
* @returns True if this is the retryable ticket magic address
|
|
30
|
+
*/
|
|
31
|
+
function isRetryableTicketMagic(target) {
|
|
32
|
+
return target.toLowerCase() === exports.RETRYABLE_TICKET_MAGIC;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Detect L2 chain from inbox address
|
|
36
|
+
*
|
|
37
|
+
* @param inboxAddress - Delayed inbox address on L1
|
|
38
|
+
* @returns Target L2 chain
|
|
39
|
+
*/
|
|
40
|
+
function detectChainFromInbox(inboxAddress) {
|
|
41
|
+
const lowerInbox = inboxAddress.toLowerCase();
|
|
42
|
+
if (lowerInbox === exports.ARB1_DELAYED_INBOX)
|
|
43
|
+
return "arb1";
|
|
44
|
+
if (lowerInbox === exports.NOVA_DELAYED_INBOX)
|
|
45
|
+
return "nova";
|
|
46
|
+
return "unknown";
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Get human-readable chain name for display
|
|
50
|
+
*
|
|
51
|
+
* @param chain - Chain identifier
|
|
52
|
+
* @returns Human-readable chain name
|
|
53
|
+
*/
|
|
54
|
+
function getRetryableChainName(chain) {
|
|
55
|
+
switch (chain) {
|
|
56
|
+
case "arb1":
|
|
57
|
+
return "Arbitrum One";
|
|
58
|
+
case "nova":
|
|
59
|
+
return "Nova";
|
|
60
|
+
default:
|
|
61
|
+
return "Unknown L2";
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Decode retryable ticket data from ABI-encoded bytes
|
|
66
|
+
*
|
|
67
|
+
* Retryable tickets are encoded as tuples (NOT calldata) with this structure:
|
|
68
|
+
* (address inbox, address l2Target, uint256 l2Value, uint256 gasLimit, uint256 maxFeePerGas, bytes l2Calldata)
|
|
69
|
+
*
|
|
70
|
+
* @param bytes - ABI-encoded retryable ticket bytes
|
|
71
|
+
* @returns Decoded retryable ticket data, or null if decoding fails
|
|
72
|
+
*/
|
|
73
|
+
function decodeRetryableTicket(bytes) {
|
|
74
|
+
try {
|
|
75
|
+
const abiCoder = new ethers_1.ethers.utils.AbiCoder();
|
|
76
|
+
const decoded = abiCoder.decode(["address", "address", "uint256", "uint256", "uint256", "bytes"], bytes);
|
|
77
|
+
const chain = detectChainFromInbox(decoded[0]);
|
|
78
|
+
return {
|
|
79
|
+
targetInbox: decoded[0],
|
|
80
|
+
l2Target: decoded[1],
|
|
81
|
+
l2Value: decoded[2].toString(),
|
|
82
|
+
gasLimit: decoded[3].toString(),
|
|
83
|
+
maxFeePerGas: decoded[4].toString(),
|
|
84
|
+
l2Calldata: decoded[5],
|
|
85
|
+
chain,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
catch (_error) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Get ChainContext from retryable chain
|
|
94
|
+
*
|
|
95
|
+
* @param chain - Retryable chain identifier
|
|
96
|
+
* @returns ChainContext for address resolution
|
|
97
|
+
*/
|
|
98
|
+
function retryableChainToContext(chain) {
|
|
99
|
+
if (chain === "nova")
|
|
100
|
+
return "nova";
|
|
101
|
+
// Default to arb1 for unknown
|
|
102
|
+
return "arb1";
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=retryable-ticket.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retryable-ticket.js","sourceRoot":"","sources":["../../src/calldata/retryable-ticket.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAuBH,wDAEC;AAQD,oDAMC;AAQD,sDASC;AAWD,sDAsBC;AAQD,0DAIC;AAnGD,mCAAgC;AAGhC;;;GAGG;AACU,QAAA,sBAAsB,GAAG,4CAA4C,CAAC;AAEnF;;GAEG;AACU,QAAA,kBAAkB,GAAG,4CAA4C,CAAC;AAClE,QAAA,kBAAkB,GAAG,4CAA4C,CAAC;AAE/E;;;;;GAKG;AACH,SAAgB,sBAAsB,CAAC,MAAc;IACnD,OAAO,MAAM,CAAC,WAAW,EAAE,KAAK,8BAAsB,CAAC;AACzD,CAAC;AAED;;;;;GAKG;AACH,SAAgB,oBAAoB,CAAC,YAAoB;IACvD,MAAM,UAAU,GAAG,YAAY,CAAC,WAAW,EAAE,CAAC;IAE9C,IAAI,UAAU,KAAK,0BAAkB;QAAE,OAAO,MAAM,CAAC;IACrD,IAAI,UAAU,KAAK,0BAAkB;QAAE,OAAO,MAAM,CAAC;IACrD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;GAKG;AACH,SAAgB,qBAAqB,CAAC,KAAkC;IACtE,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,MAAM;YACT,OAAO,cAAc,CAAC;QACxB,KAAK,MAAM;YACT,OAAO,MAAM,CAAC;QAChB;YACE,OAAO,YAAY,CAAC;IACxB,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,qBAAqB,CAAC,KAAa;IACjD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,eAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC7C,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAC7B,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,EAChE,KAAK,CACN,CAAC;QAEF,MAAM,KAAK,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAW,CAAC,CAAC;QAEzD,OAAO;YACL,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;YACvB,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;YACpB,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;YAC9B,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;YAC/B,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;YACnC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;YACtB,KAAK;SACN,CAAC;IACJ,CAAC;IAAC,OAAO,MAAM,EAAE,CAAC;QAChB,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAgB,uBAAuB,CAAC,KAAkC;IACxE,IAAI,KAAK,KAAK,MAAM;QAAE,OAAO,MAAM,CAAC;IACpC,8BAA8B;IAC9B,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Function Signature Lookup
|
|
3
|
+
*
|
|
4
|
+
* Resolves 4-byte function selectors to full function signatures.
|
|
5
|
+
* Uses local registry first, then falls back to 4byte.directory API.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Look up function signature in local registry
|
|
9
|
+
*
|
|
10
|
+
* @param selector - The 4-byte function selector (e.g., "0x8f2a0bb0")
|
|
11
|
+
* @returns The function signature if found, null otherwise
|
|
12
|
+
*/
|
|
13
|
+
export declare function lookupLocalSignature(selector: string): string | null;
|
|
14
|
+
/**
|
|
15
|
+
* Query 4byte.directory API with caching
|
|
16
|
+
*
|
|
17
|
+
* @param selector - The 4-byte function selector
|
|
18
|
+
* @returns The function signature if found, null otherwise
|
|
19
|
+
*/
|
|
20
|
+
export declare function lookup4byteDirectory(selector: string): Promise<string | null>;
|
|
21
|
+
/**
|
|
22
|
+
* Look up function signature from all sources
|
|
23
|
+
*
|
|
24
|
+
* Priority:
|
|
25
|
+
* 1. Local registry (instant)
|
|
26
|
+
* 2. 4byte.directory API (with caching)
|
|
27
|
+
*
|
|
28
|
+
* @param selector - The 4-byte function selector (e.g., "0x8f2a0bb0")
|
|
29
|
+
* @returns Object with signature and source, or null signature if not found
|
|
30
|
+
*/
|
|
31
|
+
export declare function lookupSignature(selector: string): Promise<{
|
|
32
|
+
signature: string | null;
|
|
33
|
+
source: "local" | "api" | "failed";
|
|
34
|
+
}>;
|
|
35
|
+
/**
|
|
36
|
+
* Extract function name from signature
|
|
37
|
+
*
|
|
38
|
+
* @param signature - Full function signature (e.g., "transfer(address,uint256)")
|
|
39
|
+
* @returns Function name (e.g., "transfer")
|
|
40
|
+
*/
|
|
41
|
+
export declare function extractFunctionName(signature: string): string;
|
|
42
|
+
/**
|
|
43
|
+
* Clear the signature cache (useful for testing)
|
|
44
|
+
*/
|
|
45
|
+
export declare function clearSignatureCache(): void;
|
|
46
|
+
//# sourceMappingURL=signature-lookup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signature-lookup.d.ts","sourceRoot":"","sources":["../../src/calldata/signature-lookup.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAoEH;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGpE;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAyCnF;AAED;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,OAAO,GAAG,KAAK,GAAG,QAAQ,CAAA;CAAE,CAAC,CAc3E;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAG7D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Function Signature Lookup
|
|
4
|
+
*
|
|
5
|
+
* Resolves 4-byte function selectors to full function signatures.
|
|
6
|
+
* Uses local registry first, then falls back to 4byte.directory API.
|
|
7
|
+
*/
|
|
8
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.lookupLocalSignature = lookupLocalSignature;
|
|
13
|
+
exports.lookup4byteDirectory = lookup4byteDirectory;
|
|
14
|
+
exports.lookupSignature = lookupSignature;
|
|
15
|
+
exports.extractFunctionName = extractFunctionName;
|
|
16
|
+
exports.clearSignatureCache = clearSignatureCache;
|
|
17
|
+
const debug_1 = __importDefault(require("debug"));
|
|
18
|
+
const debug = (0, debug_1.default)("gov-tracker:calldata");
|
|
19
|
+
/**
|
|
20
|
+
* Local registry of common governance function signatures
|
|
21
|
+
* Priority 1: Checked before API lookup
|
|
22
|
+
*/
|
|
23
|
+
const LOCAL_SIGNATURES = {
|
|
24
|
+
// Timelock operations
|
|
25
|
+
"0x01d5062a": "schedule(address,uint256,bytes,bytes32,bytes32,uint256)",
|
|
26
|
+
"0x8f2a0bb0": "scheduleBatch(address[],uint256[],bytes[],bytes32,bytes32,uint256)",
|
|
27
|
+
"0x134008d3": "execute(address,uint256,bytes,bytes32,bytes32)",
|
|
28
|
+
"0xe38335e5": "executeBatch(address[],uint256[],bytes[],bytes32,bytes32)",
|
|
29
|
+
"0xc4d252f5": "cancel(bytes32)",
|
|
30
|
+
"0xd45c4435": "hashOperation(address,uint256,bytes,bytes32,bytes32)",
|
|
31
|
+
"0xb1c5f427": "hashOperationBatch(address[],uint256[],bytes[],bytes32,bytes32)",
|
|
32
|
+
// Cross-chain messaging
|
|
33
|
+
"0x928c169a": "sendTxToL1(address,bytes)",
|
|
34
|
+
// UpgradeExecutor
|
|
35
|
+
"0x1cff79cd": "execute(address,bytes)",
|
|
36
|
+
"0x61461954": "executeCall(address,bytes)",
|
|
37
|
+
// ERC20
|
|
38
|
+
"0xa9059cbb": "transfer(address,uint256)",
|
|
39
|
+
"0x095ea7b3": "approve(address,uint256)",
|
|
40
|
+
"0x23b872dd": "transferFrom(address,address,uint256)",
|
|
41
|
+
"0x70a08231": "balanceOf(address)",
|
|
42
|
+
"0xdd62ed3e": "allowance(address,address)",
|
|
43
|
+
// Proxy upgrades
|
|
44
|
+
"0x3659cfe6": "upgradeTo(address)",
|
|
45
|
+
"0x4f1ef286": "upgradeToAndCall(address,bytes)",
|
|
46
|
+
"0x0900f010": "upgrade(address)",
|
|
47
|
+
"0x99a88ec4": "upgrade(address,address)",
|
|
48
|
+
// Ownership
|
|
49
|
+
"0x13af4035": "setOwner(address)",
|
|
50
|
+
"0xf2fde38b": "transferOwnership(address)",
|
|
51
|
+
"0x715018a6": "renounceOwnership()",
|
|
52
|
+
"0x8da5cb5b": "owner()",
|
|
53
|
+
// Governor
|
|
54
|
+
"0x7d5e81e2": "propose(address[],uint256[],bytes[],string)",
|
|
55
|
+
"0xfe0d94c1": "execute(uint256)",
|
|
56
|
+
"0xddf0b009": "queue(uint256)",
|
|
57
|
+
"0x56781388": "castVote(uint256,uint8)",
|
|
58
|
+
"0x3bccf4fd": "castVoteWithReason(uint256,uint8,string)",
|
|
59
|
+
// Security Council
|
|
60
|
+
"0xbf396750": "replaceCohort(address[],address[])",
|
|
61
|
+
"0xb147f40c": "perform()",
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* In-memory cache for API lookups (session cache)
|
|
65
|
+
*/
|
|
66
|
+
const signatureCache = new Map();
|
|
67
|
+
/**
|
|
68
|
+
* API timeout in milliseconds
|
|
69
|
+
*/
|
|
70
|
+
const API_TIMEOUT_MS = 5000;
|
|
71
|
+
/**
|
|
72
|
+
* Look up function signature in local registry
|
|
73
|
+
*
|
|
74
|
+
* @param selector - The 4-byte function selector (e.g., "0x8f2a0bb0")
|
|
75
|
+
* @returns The function signature if found, null otherwise
|
|
76
|
+
*/
|
|
77
|
+
function lookupLocalSignature(selector) {
|
|
78
|
+
const normalizedSelector = selector.toLowerCase();
|
|
79
|
+
return LOCAL_SIGNATURES[normalizedSelector] ?? null;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Query 4byte.directory API with caching
|
|
83
|
+
*
|
|
84
|
+
* @param selector - The 4-byte function selector
|
|
85
|
+
* @returns The function signature if found, null otherwise
|
|
86
|
+
*/
|
|
87
|
+
async function lookup4byteDirectory(selector) {
|
|
88
|
+
const normalizedSelector = selector.toLowerCase();
|
|
89
|
+
// Check session cache
|
|
90
|
+
if (signatureCache.has(normalizedSelector)) {
|
|
91
|
+
return signatureCache.get(normalizedSelector) ?? null;
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
const controller = new AbortController();
|
|
95
|
+
const timeoutId = setTimeout(() => controller.abort(), API_TIMEOUT_MS);
|
|
96
|
+
const url = `https://www.4byte.directory/api/v1/signatures/?hex_signature=${normalizedSelector}`;
|
|
97
|
+
const response = await fetch(url, { signal: controller.signal });
|
|
98
|
+
clearTimeout(timeoutId);
|
|
99
|
+
if (!response.ok) {
|
|
100
|
+
debug("4byte.directory API error: %d", response.status);
|
|
101
|
+
signatureCache.set(normalizedSelector, null);
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
const data = (await response.json());
|
|
105
|
+
if (data.results && data.results.length > 0) {
|
|
106
|
+
// Return the first (most common) signature
|
|
107
|
+
const signature = data.results[0].text_signature;
|
|
108
|
+
signatureCache.set(normalizedSelector, signature);
|
|
109
|
+
debug("4byte.directory found: %s -> %s", normalizedSelector, signature);
|
|
110
|
+
return signature;
|
|
111
|
+
}
|
|
112
|
+
signatureCache.set(normalizedSelector, null);
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
debug("4byte.directory lookup failed: %O", error);
|
|
117
|
+
signatureCache.set(normalizedSelector, null);
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Look up function signature from all sources
|
|
123
|
+
*
|
|
124
|
+
* Priority:
|
|
125
|
+
* 1. Local registry (instant)
|
|
126
|
+
* 2. 4byte.directory API (with caching)
|
|
127
|
+
*
|
|
128
|
+
* @param selector - The 4-byte function selector (e.g., "0x8f2a0bb0")
|
|
129
|
+
* @returns Object with signature and source, or null signature if not found
|
|
130
|
+
*/
|
|
131
|
+
async function lookupSignature(selector) {
|
|
132
|
+
// Try local registry first
|
|
133
|
+
const localResult = lookupLocalSignature(selector);
|
|
134
|
+
if (localResult) {
|
|
135
|
+
return { signature: localResult, source: "local" };
|
|
136
|
+
}
|
|
137
|
+
// Fall back to 4byte.directory API
|
|
138
|
+
const apiResult = await lookup4byteDirectory(selector);
|
|
139
|
+
if (apiResult) {
|
|
140
|
+
return { signature: apiResult, source: "api" };
|
|
141
|
+
}
|
|
142
|
+
return { signature: null, source: "failed" };
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Extract function name from signature
|
|
146
|
+
*
|
|
147
|
+
* @param signature - Full function signature (e.g., "transfer(address,uint256)")
|
|
148
|
+
* @returns Function name (e.g., "transfer")
|
|
149
|
+
*/
|
|
150
|
+
function extractFunctionName(signature) {
|
|
151
|
+
const parenIndex = signature.indexOf("(");
|
|
152
|
+
return parenIndex > 0 ? signature.slice(0, parenIndex) : signature;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Clear the signature cache (useful for testing)
|
|
156
|
+
*/
|
|
157
|
+
function clearSignatureCache() {
|
|
158
|
+
signatureCache.clear();
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=signature-lookup.js.map
|