-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Expand file tree
/
Copy pathgenerateFunctionSignatureHashesFromABIs.cjs
More file actions
96 lines (86 loc) · 3.02 KB
/
Copy pathgenerateFunctionSignatureHashesFromABIs.cjs
File metadata and controls
96 lines (86 loc) · 3.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
const { readdir, writeFile, mkdir, stat } = require('fs/promises')
const fs = require('fs')
const path = require('path')
const { keccak256 } = require('@ethersproject/keccak256')
async function createFileIfNotExists(filePath, content = '') {
try {
const dir = path.dirname(filePath)
await mkdir(dir, { recursive: true })
await stat(filePath)
} catch (error) {
if (error.code === 'ENOENT') {
await writeFile(filePath, content)
} else {
console.error(error)
}
}
}
function getFunctionSelectors(abi) {
const selectors = {}
abi.forEach((item) => {
if (item.type === 'function') {
const signature = `${item.name}(${item.inputs.map((input) => input.type).join(',')})`
const funcSignatureBuffer = Buffer.from(signature)
const hash = keccak256(new Uint8Array(funcSignatureBuffer))
const selector = hash.substring(2, 10) // First 4 bytes (after '0x')
selectors[signature] = selector
}
})
return selectors
}
async function processABIFiles(directory) {
if (!fs.existsSync(directory)) {
console.warn(`Directory not found: ${directory}`)
return
}
let results = {}
const directories = await readdir(directory, { withFileTypes: true })
const promises = directories.map(async (dirent) => {
const fullPath = path.join(directory, dirent.name)
if (dirent.isDirectory()) {
const subResults = await processABIFiles(fullPath) // Recursively process subdirectories
Object.assign(results, subResults)
} else if (dirent.isFile() && dirent.name.endsWith('.json')) {
const abi = require(fullPath).abi
if (abi) {
const relativePath = fullPath.split(`${path.sep}node_modules${path.sep}`)[1]
results[relativePath] = getFunctionSelectors(abi)
}
}
})
await Promise.all(promises)
return results
}
const packages = [
'@uniswap/v3-periphery/artifacts',
'@uniswap/v3-core/artifacts',
'@uniswap/v2-core/build',
'@uniswap/universal-router/artifacts',
'@uniswap/swap-router-contracts/artifacts',
]
function mapHashesToSignatures(data) {
const hashToSignatureMap = {}
for (const file in data) {
const functionMappings = data[file]
for (const signature in functionMappings) {
const hash = functionMappings[signature]
hashToSignatureMap[hash] = signature
}
}
return hashToSignatureMap
}
async function main() {
createFileIfNotExists('scripts/dist/file-to-signature-to-hash.json')
createFileIfNotExists('scripts/dist/hash-to-signature.json')
const calls = packages.map((packageName) => {
const packagePath = path.join(process.cwd(), 'node_modules', packageName)
return processABIFiles(packagePath)
})
const data = await Promise.all(calls)
const results = data.reduce((acc, cur) => ({ ...acc, ...cur }), {})
await writeFile('scripts/dist/file-to-signature-to-hash.json', JSON.stringify(results, null, 2))
await writeFile('scripts/dist/hash-to-signature.json', JSON.stringify(mapHashesToSignatures(results), null, 2))
}
main()
.then(() => console.log('done'))
.catch(console.error)