Skip to content

Commit 739c62c

Browse files
committed
refactor: streamline transaction proposal logic and enhance error handling
1 parent b5b9a72 commit 739c62c

File tree

1 file changed

+93
-98
lines changed

1 file changed

+93
-98
lines changed

propose-safe-multisig-tx/src/index.ts

Lines changed: 93 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -7,103 +7,98 @@ import { privateKeyToAccount } from "viem/accounts";
77
import { env } from "./env.js";
88

99
async function run() {
10-
try {
11-
// Environment variables are already validated and parsed
12-
const {
13-
PROPOSER_PRIVATE_KEY: proposerPrivateKey,
14-
RPC_URL: rpcUrl,
15-
SAFE_ADDRESS: safeAddress,
16-
TRANSACTION_TO: transactionTo,
17-
SAFE_API_KEY: safeApiKey,
18-
TRANSACTION_VALUE: transactionValue,
19-
TRANSACTION_DATA: transactionData,
20-
} = env;
21-
22-
core.info(`🚀 Starting Safe transaction proposal...`);
23-
core.info(`📍 Safe Address: ${safeAddress}`);
24-
core.info(`🎯 Target Address: ${transactionTo}`);
25-
26-
// Initialize wallet
27-
const account = privateKeyToAccount(proposerPrivateKey as `0x${string}`);
28-
core.info(`🔑 Proposer Address: ${account.address}`);
29-
30-
// Detect chainId from RPC
31-
core.info(`🔍 Detecting chain ID from RPC...`);
32-
const publicClient = createPublicClient({
33-
transport: http(rpcUrl),
34-
});
35-
const chainId = await publicClient.getChainId();
36-
core.info(`🌐 Detected Chain ID: ${chainId.toString()}`);
37-
38-
// Initialize API Kit
39-
const apiKit = new SafeApiKit({
40-
chainId: BigInt(chainId),
41-
apiKey: safeApiKey,
42-
});
43-
44-
// Initialize Protocol Kit
45-
const protocolKit = await Safe.init({
46-
provider: rpcUrl,
47-
signer: proposerPrivateKey,
48-
safeAddress: safeAddress,
49-
});
50-
51-
core.info(`👤 Safe initialized for: ${safeAddress}`);
52-
53-
// Create transaction
54-
const safeTransactionData: MetaTransactionData = {
55-
to: transactionTo,
56-
value: transactionValue,
57-
data: transactionData,
58-
operation: OperationType.Call,
59-
};
60-
61-
core.info("📝 Creating Safe transaction...");
62-
63-
// Create the transaction
64-
const safeTransaction = await protocolKit.createTransaction({
65-
transactions: [safeTransactionData],
66-
});
67-
68-
const safeTxHash = await protocolKit.getTransactionHash(safeTransaction);
69-
const signature = await protocolKit.signHash(safeTxHash);
70-
71-
core.info(`🔐 Transaction signed with hash: ${safeTxHash}`);
72-
73-
// Propose transaction to the service
74-
await apiKit.proposeTransaction({
75-
safeAddress: safeAddress,
76-
safeTransactionData: safeTransaction.data,
77-
safeTxHash: safeTxHash,
78-
senderAddress: account.address,
79-
senderSignature: signature.data,
80-
origin: "GitHub Action - Safe Transaction",
81-
});
82-
83-
core.info("📤 Transaction proposed to Safe service");
84-
85-
// Get transaction details
86-
const transaction = await apiKit.getTransaction(safeTxHash);
87-
88-
// Set outputs
89-
core.setOutput("tx-hash", safeTxHash);
90-
core.setOutput("tx-details", JSON.stringify(transaction));
91-
92-
core.info(`✅ Transaction proposed successfully!`);
93-
core.info(`🔗 Transaction Hash: ${safeTxHash}`);
94-
core.info(`⏳ Waiting for other owners to sign and execute...`);
95-
core.info(
96-
`📋 Transaction Details: ${JSON.stringify(transaction, null, 2)}`
97-
);
98-
} catch (error) {
99-
const errorMessage =
100-
error instanceof Error ? error.message : "Unknown error";
101-
const errorStack = error instanceof Error ? error.stack : undefined;
102-
core.setFailed(`❌ Error proposing Safe transaction: ${errorMessage}`);
103-
if (errorStack) {
104-
core.error(errorStack);
105-
}
106-
}
10+
// Environment variables are already validated and parsed
11+
const {
12+
PROPOSER_PRIVATE_KEY: proposerPrivateKey,
13+
RPC_URL: rpcUrl,
14+
SAFE_ADDRESS: safeAddress,
15+
TRANSACTION_TO: transactionTo,
16+
SAFE_API_KEY: safeApiKey,
17+
TRANSACTION_VALUE: transactionValue,
18+
TRANSACTION_DATA: transactionData,
19+
} = env;
20+
21+
core.info(`🚀 Starting Safe transaction proposal...`);
22+
core.info(`📍 Safe Address: ${safeAddress}`);
23+
core.info(`🎯 Target Address: ${transactionTo}`);
24+
25+
// Initialize wallet
26+
const account = privateKeyToAccount(proposerPrivateKey as `0x${string}`);
27+
core.info(`🔑 Proposer Address: ${account.address}`);
28+
29+
// Detect chainId from RPC
30+
core.info(`🔍 Detecting chain ID from RPC...`);
31+
const publicClient = createPublicClient({
32+
transport: http(rpcUrl),
33+
});
34+
const chainId = await publicClient.getChainId();
35+
core.info(`🌐 Detected Chain ID: ${chainId.toString()}`);
36+
37+
// Initialize API Kit
38+
const apiKit = new SafeApiKit({
39+
chainId: BigInt(chainId),
40+
apiKey: safeApiKey,
41+
});
42+
43+
// Initialize Protocol Kit
44+
const protocolKit = await Safe.init({
45+
provider: rpcUrl,
46+
signer: proposerPrivateKey,
47+
safeAddress: safeAddress,
48+
});
49+
50+
core.info(`👤 Safe initialized for: ${safeAddress}`);
51+
52+
// Create transaction
53+
const safeTransactionData: MetaTransactionData = {
54+
to: transactionTo,
55+
value: transactionValue,
56+
data: transactionData,
57+
operation: OperationType.Call,
58+
};
59+
60+
core.info("📝 Creating Safe transaction...");
61+
62+
// Create the transaction
63+
const safeTransaction = await protocolKit.createTransaction({
64+
transactions: [safeTransactionData],
65+
});
66+
67+
const safeTxHash = await protocolKit.getTransactionHash(safeTransaction);
68+
const signature = await protocolKit.signHash(safeTxHash);
69+
70+
core.info(`🔐 Transaction signed with hash: ${safeTxHash}`);
71+
72+
// Propose transaction to the service
73+
await apiKit.proposeTransaction({
74+
safeAddress: safeAddress,
75+
safeTransactionData: safeTransaction.data,
76+
safeTxHash: safeTxHash,
77+
senderAddress: account.address,
78+
senderSignature: signature.data,
79+
origin: "GitHub Action - Safe Transaction",
80+
});
81+
82+
core.info("📤 Transaction proposed to Safe service");
83+
84+
// Get transaction details
85+
const transaction = await apiKit.getTransaction(safeTxHash);
86+
87+
// Set outputs
88+
core.setOutput("tx-hash", safeTxHash);
89+
core.setOutput("tx-details", JSON.stringify(transaction));
90+
91+
core.info(`✅ Transaction proposed successfully!`);
92+
core.info(`🔗 Transaction Hash: ${safeTxHash}`);
93+
core.info(`⏳ Waiting for other owners to sign and execute...`);
94+
core.info(`📋 Transaction Details: ${JSON.stringify(transaction, null, 2)}`);
10795
}
10896

109-
run();
97+
run().catch((error) => {
98+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
99+
const errorStack = error instanceof Error ? error.stack : undefined;
100+
core.setFailed(`❌ Error proposing Safe transaction: ${errorMessage}`);
101+
if (errorStack) {
102+
core.error(errorStack);
103+
}
104+
});

0 commit comments

Comments
 (0)