Skip to content

Commit d6eafe7

Browse files
committed
feat: add function to compute safe tx hash
1 parent bfde791 commit d6eafe7

File tree

3 files changed

+68
-1
lines changed

3 files changed

+68
-1
lines changed

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,12 @@
6363
"dependencies": {
6464
"@ledgerhq/hw-transport": "6.31.3",
6565
"@ledgerhq/logs": "6.12.0",
66+
"@safe-global/protocol-kit": "^5.0.4",
6667
"bip32-path": "^0.4.2",
6768
"bitcoinjs-lib": "^5.2.0",
6869
"bs58": "^4.0.1",
6970
"bs58check": "^2.1.2",
71+
"ethers": "^6.13.4",
7072
"invariant": "^2.2.4",
7173
"ripemd160": "2",
7274
"semver": "^7.3.5",

tsconfig.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"module": "commonjs",
2121
"lib": ["DOM", "ES2017"],
2222
"isolatedModules": false,
23-
"target": "ES6"
23+
"target": "ES2020"
2424
},
2525
"include": ["src/**/*"]
2626
}

utils/compute_hash_safe_tx.ts

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#!/usr/bin/env bun
2+
3+
const { calculateSafeTransactionHash } = require("@safe-global/protocol-kit/dist/src/utils")
4+
const { ethers } = require("ethers")
5+
6+
const network: "mainnet" | "testnet" = "mainnet"
7+
8+
function decodeTxData(data: string) {
9+
const [bitcoinRedeemer, amount, extrData] = new ethers.Interface([
10+
"function approveAndCall(address spender, uint256 value, bytes extraData) returns (bool)",
11+
]).decodeFunctionData("approveAndCall", data)
12+
13+
const [
14+
verifyingContract, // Safe Address
15+
walletPublicKeyHash,
16+
mainUtxoTransactionHash,
17+
mainUtxoOutputIndex,
18+
mainUtxoValue,
19+
redeemerOutputScript,
20+
] = ethers.AbiCoder.defaultAbiCoder().decode(
21+
["address", "bytes20", "bytes32", "uint32", "uint64", "bytes"],
22+
extrData,
23+
)
24+
25+
return {
26+
bitcoinRedeemer,
27+
amount,
28+
extrData: {
29+
verifyingContract,
30+
walletPublicKeyHash,
31+
mainUtxoTransactionHash,
32+
mainUtxoOutputIndex,
33+
mainUtxoValue,
34+
redeemerOutputScript,
35+
},
36+
}
37+
}
38+
39+
// TRANSACTION DATA
40+
const safeTx = {
41+
to: "0xdf217efd8f3ecb5e837aedf203c28c1f06854017",
42+
value: "0x0",
43+
data: "0xcae9ca510000000000000000000000007e184b0cc12572d12db6da248322a0e3618fc7560000000000000000000000000000000000000000000000000031b85e8795cc0000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000100000000000000000000000000dcbc417bc341d1974d88b78ac460e4e9306b9ee088d63b7585feb6fcd186277dedafec05ce3b3f24000000000000000000000000bf5be15c2cbfdca7619685291fb03f70090172a6d12dcb4024ba2c85be8ba6a200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000116b4558700000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000017160014e30b33e50bc704a4c620ef180f4c8fbdaa8f6927000000000000000000",
44+
operation: "0",
45+
safeTxGas: "0x0",
46+
baseGas: "0x0",
47+
gasPrice: "0x0",
48+
gasToken: "0x0000000000000000000000000000000000000000",
49+
refundReceiver: "0x0000000000000000000000000000000000000000",
50+
nonce: "0",
51+
}
52+
53+
const decodedTxData = decodeTxData(safeTx.data)
54+
console.log("Decoded Tx Data:", decodedTxData)
55+
56+
console.log("Network", network)
57+
58+
const safeTxHash = calculateSafeTransactionHash(
59+
decodedTxData.extrData.verifyingContract,
60+
safeTx,
61+
"1.4.1",
62+
network === "mainnet" ? 1n : 1115511n,
63+
)
64+
65+
console.log("Safe Tx Hash:", safeTxHash)

0 commit comments

Comments
 (0)