Skip to content

Commit b5b9a72

Browse files
committed
feat: add environment variable validation and update dependencies
1 parent d9fdd7d commit b5b9a72

File tree

4 files changed

+126
-60
lines changed

4 files changed

+126
-60
lines changed

propose-safe-multisig-tx/package-lock.json

Lines changed: 57 additions & 38 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

propose-safe-multisig-tx/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@
1212
"@safe-global/api-kit": "^4.0.0",
1313
"@safe-global/protocol-kit": "^6.1.1",
1414
"@safe-global/types-kit": "^3.0.0",
15-
"viem": "^2.21.0"
15+
"dotenv": "^16.3.1",
16+
"viem": "^2.21.0",
17+
"zod": "^3.22.4"
1618
},
1719
"devDependencies": {
20+
"@types/node": "^24.7.0",
1821
"typescript": "^5.0.0"
1922
}
2023
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import 'dotenv/config';
2+
import { z } from 'zod';
3+
4+
const addressRegex = /(^|\b)(0x)?[0-9a-fA-F]{40}(\b|$)/;
5+
const privateKeyRegex = /(^|\b)(0x)?[0-9a-fA-F]{64}(\b|$)/;
6+
const hexDataRegex = /^0x[0-9a-fA-F]*$/;
7+
8+
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+
15+
// RPC URL for blockchain network connection
16+
RPC_URL: z
17+
.string()
18+
.url('RPC_URL must be a valid URL')
19+
.min(1, 'RPC URL is required'),
20+
21+
// Safe multisig contract address
22+
SAFE_ADDRESS: z
23+
.string()
24+
.regex(addressRegex, 'Invalid Safe address format')
25+
.min(1, 'Safe address is required'),
26+
27+
// Target address for the transaction
28+
TRANSACTION_TO: z
29+
.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'),
37+
38+
// Value to send in the transaction (in wei)
39+
TRANSACTION_VALUE: z
40+
.string()
41+
.default('0')
42+
.pipe(z.coerce.bigint().nonnegative('Transaction value must be a positive amount'))
43+
.transform(String),
44+
45+
// Transaction data/calldata
46+
TRANSACTION_DATA: z
47+
.string()
48+
.regex(hexDataRegex, 'Transaction data must be valid hex data')
49+
.default('0x'),
50+
});
51+
52+
export const env = envSchema.parse(process.env);

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

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,20 @@ import Safe from "@safe-global/protocol-kit";
44
import { OperationType, MetaTransactionData } from "@safe-global/types-kit";
55
import { createPublicClient, http } from "viem";
66
import { privateKeyToAccount } from "viem/accounts";
7+
import { env } from "./env.js";
78

89
async function run() {
910
try {
10-
// Get inputs from environment variables
11-
const proposerPrivateKey = process.env.INPUT_PROPOSER_PRIVATE_KEY;
12-
const rpcUrl = process.env.INPUT_RPC_URL;
13-
const safeAddress = process.env.INPUT_SAFE_ADDRESS;
14-
const transactionTo = process.env.INPUT_TRANSACTION_TO;
15-
const safeApiKey = process.env.INPUT_SAFE_API_KEY;
16-
const transactionValue = process.env.INPUT_TRANSACTION_VALUE || "0";
17-
const transactionData = process.env.INPUT_TRANSACTION_DATA || "0x";
18-
19-
// Validate required inputs
20-
if (
21-
!proposerPrivateKey ||
22-
!rpcUrl ||
23-
!safeAddress ||
24-
!transactionTo ||
25-
!safeApiKey
26-
) {
27-
throw new Error("Missing required environment variables");
28-
}
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;
2921

3022
core.info(`🚀 Starting Safe transaction proposal...`);
3123
core.info(`📍 Safe Address: ${safeAddress}`);
@@ -94,8 +86,8 @@ async function run() {
9486
const transaction = await apiKit.getTransaction(safeTxHash);
9587

9688
// Set outputs
97-
core.setOutput("safe-tx-hash", safeTxHash);
98-
core.setOutput("transaction", JSON.stringify(transaction));
89+
core.setOutput("tx-hash", safeTxHash);
90+
core.setOutput("tx-details", JSON.stringify(transaction));
9991

10092
core.info(`✅ Transaction proposed successfully!`);
10193
core.info(`🔗 Transaction Hash: ${safeTxHash}`);

0 commit comments

Comments
 (0)