Skip to content

Commit cb52719

Browse files
committed
feat: update Safe multisig transaction workflow to use new environment variable structure and enhance validation
1 parent 739c62c commit cb52719

File tree

5 files changed

+35
-37
lines changed

5 files changed

+35
-37
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,11 @@ jobs:
7070
run: npm run propose
7171
working-directory: ./propose-safe-multisig-tx
7272
env:
73-
PROPOSER_PRIVATE_KEY: ${{ secrets.safe-proposer-private-key }}
74-
SAFE_API_KEY: ${{ secrets.safe-api-key }}
7573
RPC_URL: ${{ inputs.rpc-url }}
7674
SAFE_ADDRESS: ${{ inputs.safe-address }}
7775
TRANSACTION_TO: ${{ inputs.transaction-to }}
7876
TRANSACTION_VALUE: ${{ inputs.transaction-value }}
7977
TRANSACTION_DATA: ${{ inputs.transaction-data }}
78+
SAFE_PROPOSER_PRIVATE_KEY: ${{ secrets.safe-proposer-private-key }}
79+
SAFE_API_KEY: ${{ secrets.safe-api-key }}
8080
id: safe-transaction

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ Provides a standardized workflow for building, testing, and publishing Rust pack
2525
### 🧹 [Stale Issues and PRs](./stale)
2626
Automatically identifies and closes stale issues and pull requests to maintain a clean and focused repository. Helps your team concentrate on active work items and reduces maintenance overhead.
2727

28+
### 🛡️ [Safe Multisig Transaction Proposer](./propose-safe-multisig-tx)
29+
Automates the process of proposing transactions to a Safe multi-signature wallet (Gnosis Safe). Features smart chain detection, comprehensive validation, and secure transaction handling for blockchain operations.
30+
2831
## 🔧 Usage
2932

3033
Each workflow has its own detailed documentation in its respective directory. The comprehensive documentation includes:

propose-safe-multisig-tx/README.md

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ This reusable GitHub Actions workflow automates the process of proposing transac
1010

1111
| **Input** | **Description** | **Required** | **Default** |
1212
| ------------------------ | ------------------------------------------------------------- | ------------ | ----------------------------------- |
13-
| **proposer-private-key** | Private key of the proposer wallet | Yes | - |
1413
| **rpc-url** | RPC URL for the blockchain network | Yes | - |
1514
| **safe-address** | Address of the Safe contract | Yes | - |
1615
| **transaction-to** | Target address for the transaction | Yes | - |
17-
| **safe-api-key** | Safe API key for transaction service | Yes | - |
1816
| **transaction-value** | Value to send in the transaction (in wei) | No | `0` |
1917
| **transaction-data** | Transaction data/calldata | No | `0x` |
18+
| **safe-proposer-private-key** | Private key of the proposer wallet | Yes (Secret) | - |
19+
| **safe-api-key** | Safe API key for transaction service | Yes (Secret) | - |
2020

2121
## Workflow Outputs 📤
2222

@@ -25,13 +25,6 @@ This reusable GitHub Actions workflow automates the process of proposing transac
2525
| **tx-hash** | Hash of the Safe transaction created |
2626
| **tx-details** | Complete transaction details (JSON) |
2727

28-
## Secrets 🔐
29-
30-
| **Secret** | **Description** | **Required** |
31-
| ----------------------------- | -------------------------------------------------- | ------------ |
32-
| **SAFE_PROPOSER_PRIVATE_KEY** | Private key of the proposer wallet | Yes |
33-
| **SAFE_API_KEY** | Safe API key for transaction service | Yes |
34-
3528
## How to Use This Reusable Workflow 🔄
3629

3730
1. **Call the Reusable Workflow**
@@ -61,9 +54,9 @@ This reusable GitHub Actions workflow automates the process of proposing transac
6154
safe-api-key: ${{ secrets.SAFE_API_KEY }}
6255
with:
6356
rpc-url: ${{ vars.RPC_URL }}
64-
with:
6557
safe-address: ${{ inputs.safe-address }}
6658
transaction-to: ${{ inputs.transaction-to }}
59+
transaction-value: ${{ inputs.transaction-value }}
6760
transaction-data: ${{ inputs.transaction-data }}
6861
```
6962

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

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,47 +6,49 @@ const privateKeyRegex = /(^|\b)(0x)?[0-9a-fA-F]{64}(\b|$)/;
66
const hexDataRegex = /^0x[0-9a-fA-F]*$/;
77

88
const envSchema = z.object({
9-
// Private key of the proposer wallet
10-
PROPOSER_PRIVATE_KEY: z
11-
.string()
12-
.regex(privateKeyRegex, 'Invalid private key format')
13-
.min(1, 'Proposer private key is required'),
14-
159
// RPC URL for blockchain network connection
1610
RPC_URL: z
1711
.string()
18-
.url('RPC_URL must be a valid URL')
19-
.min(1, 'RPC URL is required'),
12+
.url("RPC_URL must be a valid URL")
13+
.min(1, "RPC URL is required"),
2014

2115
// Safe multisig contract address
2216
SAFE_ADDRESS: z
2317
.string()
24-
.regex(addressRegex, 'Invalid Safe address format')
25-
.min(1, 'Safe address is required'),
18+
.regex(addressRegex, "Invalid Safe address format")
19+
.min(1, "Safe address is required"),
2620

2721
// Target address for the transaction
2822
TRANSACTION_TO: z
2923
.string()
30-
.regex(addressRegex, 'Invalid transaction target address format')
31-
.min(1, 'Transaction target address is required'),
32-
33-
// Safe API key for transaction service
34-
SAFE_API_KEY: z
35-
.string()
36-
.min(1, 'Safe API key is required'),
24+
.regex(addressRegex, "Invalid transaction target address format")
25+
.min(1, "Transaction target address is required"),
3726

3827
// Value to send in the transaction (in wei)
3928
TRANSACTION_VALUE: z
4029
.string()
41-
.default('0')
42-
.pipe(z.coerce.bigint().nonnegative('Transaction value must be a positive amount'))
30+
.default("0")
31+
.pipe(
32+
z.coerce
33+
.bigint()
34+
.nonnegative("Transaction value must be a positive amount")
35+
)
4336
.transform(String),
4437

4538
// Transaction data/calldata
4639
TRANSACTION_DATA: z
4740
.string()
48-
.regex(hexDataRegex, 'Transaction data must be valid hex data')
49-
.default('0x'),
41+
.regex(hexDataRegex, "Transaction data must be valid hex data")
42+
.default("0x"),
43+
44+
// Private key of the proposer wallet
45+
SAFE_PROPOSER_PRIVATE_KEY: z
46+
.string()
47+
.regex(privateKeyRegex, "Invalid private key format")
48+
.min(1, "Safe proposer private key is required"),
49+
50+
// Safe API key for transaction service
51+
SAFE_API_KEY: z.string().min(1, "Safe API key is required"),
5052
});
5153

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

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,21 @@ import { env } from "./env.js";
99
async function run() {
1010
// Environment variables are already validated and parsed
1111
const {
12-
PROPOSER_PRIVATE_KEY: proposerPrivateKey,
1312
RPC_URL: rpcUrl,
1413
SAFE_ADDRESS: safeAddress,
1514
TRANSACTION_TO: transactionTo,
16-
SAFE_API_KEY: safeApiKey,
1715
TRANSACTION_VALUE: transactionValue,
1816
TRANSACTION_DATA: transactionData,
17+
SAFE_PROPOSER_PRIVATE_KEY: safeProposerPrivateKey,
18+
SAFE_API_KEY: safeApiKey,
1919
} = env;
2020

2121
core.info(`🚀 Starting Safe transaction proposal...`);
2222
core.info(`📍 Safe Address: ${safeAddress}`);
2323
core.info(`🎯 Target Address: ${transactionTo}`);
2424

2525
// Initialize wallet
26-
const account = privateKeyToAccount(proposerPrivateKey as `0x${string}`);
26+
const account = privateKeyToAccount(safeProposerPrivateKey as `0x${string}`);
2727
core.info(`🔑 Proposer Address: ${account.address}`);
2828

2929
// Detect chainId from RPC
@@ -43,7 +43,7 @@ async function run() {
4343
// Initialize Protocol Kit
4444
const protocolKit = await Safe.init({
4545
provider: rpcUrl,
46-
signer: proposerPrivateKey,
46+
signer: safeProposerPrivateKey,
4747
safeAddress: safeAddress,
4848
});
4949

0 commit comments

Comments
 (0)