-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
35 lines (29 loc) · 1.23 KB
/
index.ts
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
import type { Address, Hex } from 'viem'
import { encodePacked, getAddress, keccak256, toBytes } from 'viem'
// Adapted from https://github.com/LuKks/predict-deterministic-address/
// moved from using '@noble/hashes/sha3' for cryptography to viem
const PROXY_START = '0x3d602d80600a3d3981f3363d3d373d3d3d363d73'
const PROXY_END = '5af43d82803e903d91602b57fd5bf3'
export function predictDeterministicAddress(
implementation: Address,
salt: Hex,
deployer: Address,
virtualMachine?: string,
) {
const creationCode = PROXY_START + removeHexStart(implementation).toLowerCase() + PROXY_END
const bytecode = keccak256(toBytes(creationCode))
const vm = getVM(virtualMachine)
const concatenatedHex = `0x${[vm, deployer, salt, bytecode].map(removeHexStart).join('')}`
const hash = keccak256(toBytes(concatenatedHex))
return getAddress(`0x${hash.slice(-40)}`)
}
function getVM(vm?: string) {
if (!vm || vm === 'EVM') return 'ff' // Ethereum
// Note: Disabled for now, checksum address needs to be compatible with Tron
// if (vm === 'TVM') return '41' // Tron
throw new Error('Invalid virtual machine code')
}
function removeHexStart(value: Hex | string): string {
if (value.startsWith('0x')) return value.slice(2)
return value
}