ratul-kilosigner
v1.0.1
Published
Drop-in ethers.js replacement for centralized signing. Migrate existing scripts with 1-line import change.
Downloads
119
Maintainers
Readme
KiloSigner
A self-hosted remote signing service built on Convex. Any script, on any machine, on any EVM chain can request a signed transaction without ever holding a private key. Keys live exclusively in Convex environment variables.
How It Works
Script KiloSigner (Convex) Blockchain
│ │ │
│── POST /request-access ────▶│ │
│◀─ { requestId } ────────────│ │
│ │──── Telegram notification ──▶ (you)
│── GET /poll ────────────────▶│ │
│◀─ { status: "pending" } ────│ │
│ │ (admin approves) │
│── GET /poll ────────────────▶│ │
│◀─ { status: "approved", │ │
│ rawKey: "ks_..." } ─────│ │
│ │ │
│── POST /sign ───────────────▶│ │
│ x-api-key: ks_... │── ethers.Wallet(WALLET_1) ──▶│
│ │◀─ txHash ───────────────────│
│◀─ { txHash } ───────────────│ │The raw key is never stored on disk anywhere — only held in the script's memory for the session.
Setup
cd B:\Studio\AIRDROPS\Tools\kilosigner
npm install
npx convex dev # logs in, creates project, starts watcherAfter dev starts and _generated/ is created:
1. Set env vars in Convex Dashboard → Settings → Environment Variables:
| Variable | Value |
|---|---|
| WALLET_1 | private key for wallet 1 |
| WALLET_2 | private key for wallet 2 |
| WALLET_N | ...and so on |
| ADMIN_SECRET | any strong random string |
| TELEGRAM_BOT_TOKEN | from @BotFather (optional) |
| TELEGRAM_ADMIN_CHAT_ID | your Telegram user ID (optional) |
2. Register Telegram webhook (if using Telegram):
https://api.telegram.org/bot<TOKEN>/setWebhook?url=https://<deployment>.convex.site/telegram-webhook3. Deploy:
npx convex deploy4. Open the admin panel:
Open admin/index.html in your browser. Enter your .convex.site URL and ADMIN_SECRET.
Using in a Script
Option A — Keyless (recommended)
Script requests access at startup. Admin approves via Telegram or admin panel.
import { requestAccess, kiloSign } from "../../Tools/kilosigner/lib/client.js";
// .env: KILOSIGNER_URL=https://your-deployment.convex.site
// No KILOSIGNER_API_KEY needed
await requestAccess("my-airdrop-bot"); // waits for approval
const { result: txHash } = await kiloSign({
walletIndex: 1,
requestType: "sendTransaction",
chain: { rpc: "https://bsc-dataseed.binance.org" },
tx: { to: "0x...", data: "0x...", gasLimit: 300_000 },
});Option B — Pre-set key
Approve a request manually once, save the key in .env.
import { kiloSign } from "../../Tools/kilosigner/lib/client.js";
// .env:
// KILOSIGNER_URL=https://your-deployment.convex.site
// KILOSIGNER_API_KEY=ks_your_approved_key
const { address } = await kiloSign({
walletIndex: 2,
requestType: "getAddress",
chain: { rpc: "https://mainnet.base.org" },
});File Structure
kilosigner/
├── convex/
│ ├── schema.js — DB tables: audit_log, api_keys, pending_requests
│ ├── signer.js — "use node" action; ethers signing logic
│ ├── auth.js — API key CRUD (Convex runtime)
│ ├── pending.js — Approval request lifecycle
│ ├── telegram.js — Telegram notifications + callback handling
│ ├── admin.js — Internal queries for admin panel
│ ├── log.js — Audit log writer
│ └── http.js — HTTP router (all endpoints)
├── lib/
│ └── client.js — Drop-in client module for your scripts
├── admin/
│ └── index.html — Admin panel (open in browser)
├── examples/
│ ├── keyless-bootstrap.js — Keyless flow example
│ ├── multi-chain-send.js — Multi-chain operations
│ ├── typed-data-sign.js — EIP-712 permit signing
│ └── API.md — Full API reference
├── test.js
└── package.jsonAdmin Panel
Open admin/index.html directly in your browser (no server needed).
- Access Requests — approve or deny pending script requests. Auto-refreshes every 10s. Telegram inline buttons do the same thing.
- API Keys — view all keys, usage counts, last used time. Revoke individually.
- Audit Logs — last 100 signing operations with wallet, chain, result, success/fail.
Security Model
| What | How |
|---|---|
| Private keys | Only in Convex env vars — never in any file |
| API keys | Stored as SHA-256 hashes — raw key never persisted |
| Admin access | ADMIN_SECRET header on /admin/* endpoints |
| Script access | Explicit per-request approval by admin |
| Audit trail | Every sign request logged with wallet, chain, result |
| Revocation | Any key revokable instantly without affecting others |
