{"id":49532712,"url":"https://github.com/safe-global/safe-cli-nodejs","last_synced_at":"2026-05-02T08:35:24.893Z","repository":{"id":320592766,"uuid":"1082549702","full_name":"safe-global/safe-cli-nodejs","owner":"safe-global","description":"Safe CLI (Node.js)","archived":false,"fork":false,"pushed_at":"2025-12-01T08:08:51.000Z","size":647,"stargazers_count":2,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-24T14:46:07.198Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/safe-global.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-10-24T12:09:41.000Z","updated_at":"2026-04-02T10:16:59.000Z","dependencies_parsed_at":"2025-10-24T18:25:01.838Z","dependency_job_id":null,"html_url":"https://github.com/safe-global/safe-cli-nodejs","commit_stats":null,"previous_names":["5afe/safe-cli-nodejs","safe-global/safe-cli-nodejs"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/safe-global/safe-cli-nodejs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/safe-global%2Fsafe-cli-nodejs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/safe-global%2Fsafe-cli-nodejs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/safe-global%2Fsafe-cli-nodejs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/safe-global%2Fsafe-cli-nodejs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/safe-global","download_url":"https://codeload.github.com/safe-global/safe-cli-nodejs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/safe-global%2Fsafe-cli-nodejs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32528469,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-02T01:12:54.858Z","status":"online","status_checked_at":"2026-05-02T02:00:05.923Z","response_time":132,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-05-02T08:35:23.409Z","updated_at":"2026-05-02T08:35:24.883Z","avatar_url":"https://github.com/safe-global.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🔐 Safe CLI [![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?logo=typescript\u0026logoColor=white)](https://www.typescriptlang.org/) [![CI](https://github.com/5afe/safe-cli-nodejs/actions/workflows/ci.yml/badge.svg)](https://github.com/5afe/safe-cli-nodejs/actions/workflows/ci.yml) [![npm version](https://img.shields.io/npm/v/@safe-global/safe-cli.svg)](https://www.npmjs.com/package/@safe-global/safe-cli)\n\n\u003e A modern, interactive command-line tool for managing Safe Smart Accounts\n\nBuilt on top of the [Safe Core SDK](https://github.com/safe-global/safe-core-sdk), Safe CLI makes it easy to create, manage, and interact with Safe multi-signature wallets directly from your terminal.\n\n---\n\n## Why Safe CLI?\n\nSafe CLI provides a powerful command-line interface for:\n- **Creating and managing Safe accounts** without using the web interface\n- **Coordinating multi-signature transactions** with your team\n- **Interacting with smart contracts** through an intuitive transaction builder\n- **Automating Safe operations** in scripts and workflows\n- **Managing multiple Safes across different chains** from one place\n- **Hardware wallet support** - Use Ledger devices for maximum security\n\nPerfect for developers, power users, and teams who prefer working in the terminal.\n\n---\n\n## ✨ Features\n\n### Core Functionality\n- 🔐 **Secure wallet management** - Encrypted private key storage with AES-256-GCM + Ledger hardware wallet support\n- ⛓️ **Multi-chain support** - Works with Ethereum, Polygon, Arbitrum, Optimism, Base, and more\n- 🎨 **Beautiful interface** - Modern terminal UI with interactive prompts\n- 📦 **Safe lifecycle** - Create, deploy, and manage Safe accounts\n- 📝 **Transaction handling** - Create, sign, and execute transactions\n\n### Advanced Features\n- 🤖 **Smart contract interaction** - Automatic ABI fetching and interactive function builder\n- 🔌 **Proxy support** - Detects and handles EIP-1967 proxy contracts\n- 👥 **Owner management** - Add/remove owners and change thresholds\n- 🔄 **Multi-sig coordination** - Multiple workflows for collecting signatures\n- 📥 **Transaction import** - Import from Safe web app's Transaction Builder\n\n---\n\n## 🚀 Quick Start\n\n### Installation\n\n```bash\n# Install globally\nnpm install -g @safe-global/safe-cli\n\n# Or run without installing\nnpx @safe-global/safe-cli\n```\n\n### First-Time Setup\n\n**1. Initialize configuration**\n```bash\nsafe config init\n```\nThis sets up your chain configurations and optional API keys.\n\n**2. Set up a wallet**\n```bash\n# Option A: Create a new wallet (generates private key)\nsafe wallet create\n\n# Option B: Import existing private key\nsafe wallet import\n\n# Option C: Import Ledger hardware wallet (recommended for production)\nsafe wallet import-ledger\n```\nPrivate keys are encrypted with a password. Ledger wallets use your hardware device for signing.\n\n**3. Create your first Safe**\n```bash\nsafe account create\n```\nFollow the interactive prompts to configure owners and threshold.\n\n**That's it!** You're ready to manage Safe accounts from your terminal.\n\n---\n\n## 📚 Command Reference\n\n### Configuration\n\n| Command | Description |\n|---------|-------------|\n| `safe config init` | Set up CLI for first use (includes API keys) |\n| `safe config show` | View current configuration |\n| `safe config chains list` | List configured networks |\n| `safe config chains add` | Add a custom network |\n| `safe config chains remove` | Remove a network |\n| `safe config chains edit` | Edit chains in your text editor |\n\n### Wallets\n\n| Command | Description |\n|---------|-------------|\n| `safe wallet create` | Create a new wallet with a generated private key |\n| `safe wallet import` | Import a wallet with your existing private key |\n| `safe wallet import-ledger` | Import a Ledger hardware wallet |\n| `safe wallet list` | View all your wallets (shows wallet types) |\n| `safe wallet use` | Switch to a different wallet |\n| `safe wallet remove` | Delete a wallet |\n\n### Safe Accounts\n\n| Command | Description |\n|---------|-------------|\n| `safe account create` | Create a new Safe |\n| `safe account deploy [address]` | Deploy a predicted Safe to the blockchain |\n| `safe account open [address]` | Add an existing Safe to your workspace |\n| `safe account list` | View all your Safes |\n| `safe account info [address]` | Show Safe details (owners, threshold, balance) |\n| `safe account add-owner [address]` | Add a new owner |\n| `safe account remove-owner [address]` | Remove an owner |\n| `safe account change-threshold [address]` | Change signature threshold |\n\n**💡 Tip:** Most commands support EIP-3770 format (`eth:0x123...`) or will prompt you interactively.\n\n### Transactions\n\n| Command | Description |\n|---------|-------------|\n| `safe tx create` | Create a new transaction |\n| `safe tx sign [txHash]` | Sign a transaction |\n| `safe tx execute [txHash]` | Execute a transaction |\n| `safe tx list` | View transactions |\n| `safe tx status [txHash]` | Check signature progress |\n| `safe tx export [txHash]` | Export as JSON for sharing |\n| `safe tx import [json]` | Import from JSON |\n\n**Multi-sig Coordination:**\n\n| Command | Description |\n|---------|-------------|\n| `safe tx push [txHash]` | Upload to Safe Transaction Service |\n| `safe tx pull` | Download pending transactions |\n| `safe tx sync` | Sync local and remote transactions |\n\n---\n\n## 💡 Common Workflows\n\n### Creating and Deploying a Safe\n\n```bash\n# 1. Create a Safe (gets predicted address)\nsafe account create\n\n# 2. Deploy it to the blockchain\nsafe account deploy eth:0x742d35Cc...\n```\n\n### Sending ETH from a Safe\n\n```bash\n# Create and sign a transaction\nsafe tx create\n# → Select your Safe\n# → Enter recipient address\n# → Enter amount in wei\n# → Sign it\n\n# If you're the only signer needed, execute immediately\nsafe tx execute \u003ctxHash\u003e\n\n# Or, share the transaction with other signers (see Multi-sig section)\n```\n\n### Interacting with a Smart Contract\n\n```bash\nsafe tx create\n# → Select your Safe\n# → Enter contract address\n\n# The CLI automatically:\n# ✓ Detects it's a contract\n# ✓ Fetches the ABI from Etherscan/Sourcify\n# ✓ Shows you all available functions\n# ✓ Helps you fill in parameters with validation\n# ✓ Encodes the transaction\n\n# Then sign and execute as usual\n```\n\n### Multi-sig Coordination\n\n**Option A: Using Safe Transaction Service** (Recommended)\n\n```bash\n# Owner 1: Create and push\nsafe tx create\nsafe tx sign \u003ctxHash\u003e\nsafe tx push \u003ctxHash\u003e\n\n# Owner 2: Pull and sign\nsafe tx pull\nsafe tx sign \u003ctxHash\u003e\nsafe tx push \u003ctxHash\u003e\n\n# Any owner: Execute when threshold is met\nsafe tx execute \u003ctxHash\u003e\n```\n\n**Option B: Offline with JSON Export**\n\n```bash\n# Owner 1: Create and export\nsafe tx create\nsafe tx sign \u003ctxHash\u003e\nsafe tx export \u003ctxHash\u003e\n# → Share the JSON with other owners\n\n# Owner 2: Import and sign\nsafe tx import '{\"safeTxHash\":\"0x...\"...}'\nsafe tx sign \u003ctxHash\u003e\n\n# Check progress\nsafe tx status \u003ctxHash\u003e  # Shows \"2/3 signatures\"\n\n# Execute when ready\nsafe tx execute \u003ctxHash\u003e\n```\n\n---\n\n## 🤖 Non-Interactive Usage \u0026 Automation\n\nSafe CLI supports non-interactive mode for automation, CI/CD pipelines, and scripting workflows.\n\n### Enabling Non-Interactive Mode\n\nUse the `--json` or `--quiet` global flags:\n\n```bash\n# JSON output mode (machine-readable)\nsafe --json [command]\n\n# Quiet mode (suppresses prompts, minimal output)\nsafe --quiet [command]\n```\n\n### Password Handling for Automation\n\nCommands requiring wallet signatures need passwords. Use these methods (in priority order):\n\n**1. Environment Variable** (Recommended for CI/CD)\n```bash\nexport SAFE_WALLET_PASSWORD=\"your-secure-password\"\nsafe --json tx sign 0xabc...\n```\n\n**2. Password File** (Secure for scripts)\n```bash\necho \"your-secure-password\" \u003e ~/.safe-password\nchmod 600 ~/.safe-password\nsafe --password-file ~/.safe-password tx sign 0xabc...\n```\n\n**3. CLI Flag** (⚠️ Insecure - visible in process list)\n```bash\nsafe --password \"your-password\" tx sign 0xabc...\n# Warning: Only use for testing!\n```\n\n### Required Arguments\n\nIn non-interactive mode, commands require all arguments as flags:\n\n#### Creating a Safe\n```bash\nsafe --json account create \\\n  --chain-id 1 \\\n  --owners \"0x123...,0x456...\" \\\n  --threshold 2 \\\n  --name \"my-safe\" \\\n  --no-deploy\n```\n\n#### Deploying a Safe\n```bash\nexport SAFE_WALLET_PASSWORD=\"password\"\nsafe --json account deploy eth:0x742d35Cc...\n```\n\n#### Signing a Transaction\n```bash\nexport SAFE_WALLET_PASSWORD=\"password\"\nsafe --json tx sign 0xabc123...\n```\n\n#### Executing a Transaction\n```bash\nexport SAFE_WALLET_PASSWORD=\"password\"\nsafe --json tx execute 0xabc123...\n```\n\n#### Getting Safe Info\n```bash\nsafe --json account info eth:0x742d35Cc...\n```\n\n#### Listing Transactions\n```bash\nsafe --json tx list eth:0x742d35Cc...\n```\n\n### JSON Output Format\n\nAll commands in `--json` mode return consistent JSON:\n\n**Success:**\n```json\n{\n  \"success\": true,\n  \"message\": \"Operation completed\",\n  \"data\": {\n    \"safeTxHash\": \"0x...\",\n    \"address\": \"0x...\",\n    ...\n  }\n}\n```\n\n**Error:**\n```json\n{\n  \"success\": false,\n  \"error\": \"Error message\",\n  \"exitCode\": 4\n}\n```\n\n**Exit Codes:**\n- `0` - Success\n- `1` - General error\n- `2` - Network error\n- `3` - Authentication failure\n- `4` - Invalid arguments\n- `5` - Configuration error\n- `6` - Safe not found\n- `7` - Wallet error\n\n### Complete CI/CD Example\n\n```bash\n#!/bin/bash\nset -e  # Exit on error\n\n# Set up environment\nexport SAFE_WALLET_PASSWORD=\"${SAFE_PASSWORD}\"  # From CI secrets\nexport SAFE_OUTPUT_FORMAT=\"json\"\n\n# Create a Safe\nRESULT=$(safe --json account create \\\n  --chain-id 11155111 \\\n  --owners \"0x123...,0x456...\" \\\n  --threshold 2 \\\n  --name \"CI-Safe-$(date +%s)\" \\\n  --no-deploy)\n\n# Extract Safe address from JSON\nSAFE_ADDRESS=$(echo $RESULT | jq -r '.data.address')\necho \"Created Safe: $SAFE_ADDRESS\"\n\n# Deploy it\nsafe --json account deploy sepolia:$SAFE_ADDRESS\n\n# Get Safe info and verify deployment\nsafe --json account info sepolia:$SAFE_ADDRESS | jq '.data.deployed'\n```\n\n### GitHub Actions Example\n\n```yaml\nname: Deploy Safe\n\non:\n  push:\n    branches: [main]\n\njobs:\n  deploy:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Install Safe CLI\n        run: npm install -g @safe-global/safe-cli\n\n      - name: Deploy Safe\n        env:\n          SAFE_WALLET_PASSWORD: ${{ secrets.SAFE_PASSWORD }}\n        run: |\n          safe --json account deploy sepolia:0x742d35Cc...\n```\n\n### Best Practices\n\n1. **Never commit passwords** - Use environment variables or CI secrets\n2. **Validate JSON output** - Check `success` field and handle errors\n3. **Use exit codes** - Script can check `$?` for command success\n4. **Parse with jq** - Extract specific fields from JSON output\n5. **Test locally first** - Use `--json` flag to test automation scripts\n6. **Use password files with proper permissions** - `chmod 600` for security\n\n### Automation-Friendly Commands\n\n| Command | Non-Interactive Support | Password Required |\n|---------|------------------------|-------------------|\n| `account create` | ✅ All args required | ❌ |\n| `account deploy` | ✅ Address required | ✅ |\n| `account info` | ✅ Address required | ❌ |\n| `account list` | ✅ No args needed | ❌ |\n| `account add-owner` | ✅ Address/owner required | ❌ (creates tx) |\n| `tx sign` | ✅ Hash required | ✅ |\n| `tx execute` | ✅ Hash required | ✅ |\n| `tx list` | ✅ Optional address | ❌ |\n| `tx status` | ✅ Hash required | ❌ |\n| `tx export` | ✅ Hash required | ❌ |\n| `tx import` | ✅ JSON required | ❌ |\n| `wallet create` | ✅ All args required | ❌ |\n| `wallet import` | ✅ All args required | ❌ |\n| `wallet list` | ✅ No args needed | ❌ |\n\n---\n\n## ⚙️ Configuration\n\n### Storage Location\n\nConfiguration files are stored in:\n- **macOS**: `~/Library/Preferences/safe-cli/`\n- **Linux**: `~/.config/safe-cli/`\n- **Windows**: `%APPDATA%\\safe-cli\\`\n\n### Supported Networks (Default)\n\nPre-configured for 18+ networks including:\n- Ethereum, Sepolia (testnet)\n- Layer 2s: Arbitrum, Optimism, Base, Polygon, zkSync Era, Polygon zkEVM, Scroll, Linea\n- Alternative L1s: BNB Chain, Gnosis Chain, Avalanche, Celo, Aurora\n- Emerging chains: Mantle, World Chain, Sonic, Unichain\n\nAdd custom networks with `safe config chains add`.\n\n### Optional API Keys\n\nThese are optional but recommended for enhanced functionality:\n\n#### Safe Transaction Service API Key\n\n**Get it from:** [Safe Developer Dashboard](https://developer.safe.global)\n\n**Enables:**\n- Multi-sig coordination via Safe Transaction Service\n- Push/pull transactions\n- Integration with Safe web interface\n\n**Without it:** You can still use offline JSON export/import for multi-sig.\n\n#### Etherscan API Key\n\n**Get it from:** [Etherscan](https://etherscan.io/myapikey) (free)\n\n**Enables:**\n- Proxy contract detection (EIP-1967)\n- Better ABI fetching for proxies\n- Automatic ABI merging for proxy + implementation\n\n**Without it:** Uses Sourcify as fallback (still works, but no proxy detection).\n\n**Setup:** Run `safe config init` and follow the prompts, or edit the config file manually.\n\n---\n\n## 🔐 Security\n\n### Private Key Wallets\n- **Key generation**: Uses Node.js crypto.randomBytes() for cryptographically secure random generation\n- **Encryption**: Private keys encrypted with AES-256-GCM\n- **Key derivation**: PBKDF2 with 100,000 iterations\n- **Local storage**: All data stored locally on your machine\n- **No exposure**: Keys never logged or transmitted in plain text\n- **Backup verification**: Confirmation required when creating new wallets\n\n### Hardware Wallets (Ledger)\n- **Maximum security**: Private keys never leave the device\n- **Physical confirmation**: All transactions require on-device approval\n- **Industry standard**: BIP44 derivation paths\n- **Secure Element**: Military-grade chip protection\n\n**Recommendation**: Use Ledger hardware wallets for production Safe accounts with significant funds.\n\n---\n\n## 🛠️ For Developers\n\n### Prerequisites\n\n- Node.js \u003e= 18.0.0\n- npm or yarn\n\n### Development Setup\n\n```bash\n# Clone the repository\ngit clone https://github.com/5afe/safe-cli-nodejs.git\ncd safe-cli-nodejs\n\n# Install dependencies\nnpm install\n\n# Run in development mode\nnpm run dev\n\n# Type checking\nnpm run typecheck\n\n# Run tests\nnpm test\n\n# Build\nnpm run build\n```\n\n### Project Structure\n\n```\nsrc/\n├── commands/           # Command implementations\n│   ├── config/        # Configuration commands\n│   ├── wallet/        # Wallet management (incl. Ledger)\n│   ├── account/       # Safe account operations\n│   └── tx/            # Transaction commands\n├── services/          # Business logic\n│   ├── safe-service.ts\n│   ├── transaction-service.ts\n│   ├── ledger-service.ts      # Ledger hardware wallet integration\n│   ├── abi-service.ts\n│   └── validation-service.ts\n├── storage/           # Persistent storage\n│   ├── config-store.ts\n│   ├── wallet-store.ts\n│   └── transaction-store.ts\n├── ui/                # Terminal UI components (React/Ink)\n├── types/             # TypeScript type definitions\n└── utils/             # Utility functions\n```\n\n### Tech Stack\n\n- **TypeScript** - Type safety\n- **Commander.js** - CLI framework\n- **React + Ink** - Terminal UI\n- **@clack/prompts** - Interactive prompts\n- **Viem** - Ethereum utilities\n- **Safe Core SDK** - Safe protocol integration\n- **LedgerJS** - Hardware wallet integration\n- **Zod** - Runtime validation\n\n---\n\n## 🤝 Contributing\n\nContributions are welcome! Here's how:\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Make your changes\n4. Run tests (`npm test`)\n5. Commit with a clear message\n6. Push and open a Pull Request\n\nPlease ensure:\n- Tests pass (`npm test`)\n- TypeScript compiles (`npm run typecheck`)\n- Code is formatted (`npm run format`)\n\n---\n\n## 📖 Additional Resources\n\n- [Safe Documentation](https://docs.safe.global/)\n- [Safe Core SDK](https://github.com/safe-global/safe-core-sdk)\n- [Safe Website](https://safe.global/)\n- [EIP-3770: Chain-specific addresses](https://eips.ethereum.org/EIPS/eip-3770)\n\n---\n\n## 📄 License\n\nLGPL-3.0\n\n---\n\nMade with ❤️ for the Safe community\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsafe-global%2Fsafe-cli-nodejs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsafe-global%2Fsafe-cli-nodejs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsafe-global%2Fsafe-cli-nodejs/lists"}