Skip to content

Commit 220279d

Browse files
authored
feat: add dry run mode for transaction validation in multisig proposal (#92)
1 parent bd34b9a commit 220279d

File tree

3 files changed

+56
-19
lines changed

3 files changed

+56
-19
lines changed

.github/workflows/propose-safe-multisig-tx.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ on:
2323
description: 'Transaction data/calldata'
2424
required: true
2525
type: string
26+
dry-run:
27+
description: 'If true, validate and prepare the transaction without proposing it'
28+
required: false
29+
default: false
30+
type: boolean
2631
secrets:
2732
safe-proposer-private-key:
2833
description: 'Private key of the proposer wallet'
@@ -75,4 +80,5 @@ jobs:
7580
TRANSACTION_DATA: ${{ inputs.transaction-data }}
7681
SAFE_PROPOSER_PRIVATE_KEY: ${{ secrets.safe-proposer-private-key }}
7782
SAFE_API_KEY: ${{ secrets.safe-api-key }}
83+
DRY_RUN: ${{ inputs.dry-run }}
7884
id: safe-transaction

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ const envSchema = z.object({
5050

5151
// Safe API key for transaction service
5252
SAFE_API_KEY: z.string().min(1, "Safe API key is required"),
53+
54+
// Dry run mode - validate without proposing
55+
DRY_RUN: z
56+
.string()
57+
.optional()
58+
.default("false")
59+
.transform((val) => val === "true" || val === "1"),
5360
});
5461

5562
export const env = envSchema.parse(process.env);

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

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@ async function run() {
1515
TRANSACTION_DATA: transactionData,
1616
SAFE_PROPOSER_PRIVATE_KEY: safeProposerPrivateKey,
1717
SAFE_API_KEY: safeApiKey,
18+
DRY_RUN: dryRun,
1819
} = env;
1920

20-
core.info(`🚀 Starting Safe transaction proposal...`);
21+
core.info(`🚀 Starting Safe transaction ${dryRun ? 'validation (DRY RUN)' : 'proposal'}...`);
2122
core.info(`📍 Safe Address: ${safeAddress}`);
2223
core.info(`🎯 Target Address: ${transactionTo}`);
2324

@@ -60,24 +61,47 @@ async function run() {
6061

6162
core.info(`🔐 Transaction signed - hash: ${safeTxHash}`);
6263

63-
await apiKit.proposeTransaction({
64-
safeAddress: safeAddress,
65-
safeTransactionData: safeTransaction.data,
66-
safeTxHash: safeTxHash,
67-
senderAddress: account.address,
68-
senderSignature: signature.data,
69-
origin: "GitHub Action - Propose Safe Multisig Transaction",
70-
});
71-
72-
const transaction = await apiKit.getTransaction(safeTxHash);
73-
74-
core.setOutput("tx-hash", safeTxHash);
75-
core.setOutput("tx-details", JSON.stringify(transaction));
76-
77-
core.info(`✅ Transaction proposed successfully!`);
78-
core.info(`🔗 Transaction Hash: ${safeTxHash}`);
79-
core.info(`⏳ Waiting for other owners to sign and execute...`);
80-
core.info(`📋 Transaction Details: ${JSON.stringify(transaction, null, 2)}`);
64+
if (dryRun) {
65+
core.info(`🧪 DRY RUN MODE - Transaction validated but not proposed`);
66+
core.info(`📋 Transaction Preview:`);
67+
core.info(` To: ${safeTransactionData.to}`);
68+
core.info(` Value: ${safeTransactionData.value}`);
69+
core.info(` Data: ${safeTransactionData.data}`);
70+
core.info(` Operation: ${safeTransactionData.operation}`);
71+
72+
core.setOutput("tx-hash", safeTxHash);
73+
core.setOutput("tx-details", JSON.stringify({
74+
to: safeTransactionData.to,
75+
value: safeTransactionData.value,
76+
data: safeTransactionData.data,
77+
operation: safeTransactionData.operation,
78+
safeTxHash: safeTxHash,
79+
senderAddress: account.address,
80+
dryRun: true,
81+
}));
82+
83+
core.info(`✅ Transaction validated successfully (not proposed)`);
84+
core.info(`🔗 Transaction Hash (would be): ${safeTxHash}`);
85+
} else {
86+
await apiKit.proposeTransaction({
87+
safeAddress: safeAddress,
88+
safeTransactionData: safeTransaction.data,
89+
safeTxHash: safeTxHash,
90+
senderAddress: account.address,
91+
senderSignature: signature.data,
92+
origin: "GitHub Action - Propose Safe Multisig Transaction",
93+
});
94+
95+
const transaction = await apiKit.getTransaction(safeTxHash);
96+
97+
core.setOutput("tx-hash", safeTxHash);
98+
core.setOutput("tx-details", JSON.stringify(transaction));
99+
100+
core.info(`✅ Transaction proposed successfully!`);
101+
core.info(`🔗 Transaction Hash: ${safeTxHash}`);
102+
core.info(`⏳ Waiting for other owners to sign and execute...`);
103+
core.info(`📋 Transaction Details: ${JSON.stringify(transaction, null, 2)}`);
104+
}
81105
}
82106

83107
run().catch((error) => {

0 commit comments

Comments
 (0)