fund-distribution — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited fund-distribution (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Manage the complete lifecycle of funding agent wallets across 8 EVM chains with 5 stablecoins + native gas tokens. Use when the user says "distribute funds", "fund agents", "rebalance", "bridge tokens", "fan out", "check balances", "inventory", "sweep funds", or similar.
# Load master wallet key from AWS SM without displaying it
node -e "
const { execSync } = require('child_process');
const raw = execSync('aws secretsmanager get-secret-value --secret-id YOUR_SECRET_PATH/x402 --query SecretString --output text --region us-east-2', {encoding:'utf8'});
const pk = JSON.parse(raw).PRIVATE_KEY;
execSync('npx tsx kk/<script>.ts <args>', {
stdio: 'inherit',
env: { ...process.env, WALLET_PRIVATE_KEY: pk, PRIVATE_KEY: pk }
});
"| Wallet | Address | Key Source |
|---|---|---|
| Master/Platform | YOUR_PLATFORM_WALLET | AWS SM YOUR_SECRET_PATH/x402:PRIVATE_KEY |
| Dev | YOUR_DEV_WALLET | .env.local:WALLET_PRIVATE_KEY |
| Test Worker | YOUR_TEST_WORKER_WALLET | AWS SM YOUR_SECRET_PATH/test-worker:private_key |
| KK Agent Wallets | 24 HD-derived wallets | AWS SM YOUR_SECRET_PATH/swarm-seed (mnemonic) |
cd scripts && npm install<YOUR_AWS_ACCOUNT_ID>, region us-east-2scripts/kk/config/wallets.json (generated by generate-wallets.ts)scripts/kk/config/allocation.json (generated by generate-allocation.ts)All scripts live in scripts/kk/. Run from scripts/ directory.
| Script | Purpose |
|---|---|
check-full-inventory.ts | Check ALL stablecoin + native balances on ALL chains |
check-all-balances.ts | Quick check: native + USDC only |
bridge-from-source.ts | Bridge USDC between chains via deBridge/Squid |
bridge-gas.ts | Bridge USDC → native gas tokens via deBridge |
distribute-funds.ts | Fan out tokens + gas to N wallets (Disperse or sequential) |
generate-allocation.ts | Generate randomized per-agent allocation plan |
sweep-funds.ts | Recover ALL tokens from agent wallets back to master |
generate-wallets.ts | Generate HD wallets from mnemonic |
This matrix defines which tokens the Ultravioleta Facilitator accepts for payments on each chain. Source: https://facilitator.ultravioletadao.xyz
| Chain | USDC | EURC | AUSD | PYUSD | USDT | Bridge | Disperse |
|---|---|---|---|---|---|---|---|
| Base | Y | Y | - | - | - | deBridge | Y |
| Ethereum | Y | Y | Y | Y | - | deBridge | Y |
| Polygon | Y | - | Y | - | - | deBridge | Y |
| Arbitrum | Y | - | Y | - | Y | deBridge | Y |
| Avalanche | Y | Y | Y | - | - | deBridge | Y |
| Optimism | Y | - | - | - | Y | deBridge | Y |
| Celo | Y | - | - | - | Y | Squid* | No |
| Monad | Y | - | Y | - | Y | deBridge | No |
*Squid requires SQUID_INTEGRATOR_ID env var (apply at squidrouter.typeform.com/integrator-id).
Token config source of truth: scripts/kk/lib/chains.ts — must match Facilitator.
ALWAYS start here. Check what you have before doing anything.
cd scripts
# Uses master wallet from AWS SM:
node -e "
const { execSync } = require('child_process');
const raw = execSync('aws secretsmanager get-secret-value --secret-id YOUR_SECRET_PATH/x402 --query SecretString --output text --region us-east-2', {encoding:'utf8'});
const pk = JSON.parse(raw).PRIVATE_KEY;
execSync('npx tsx kk/check-full-inventory.ts', {
stdio: 'inherit',
env: { ...process.env, WALLET_PRIVATE_KEY: pk, PRIVATE_KEY: pk }
});
"Output: Per-chain breakdown of all stablecoin balances + native gas, plus totals per token and Facilitator support matrix.
If distributing per a budget plan:
cd scripts
npx tsx kk/generate-allocation.ts --budget 200 --output config/allocation.jsonThis creates a randomized allocation of the budget across agents and chains, respecting token availability per chain.
Bridge USDC from a source chain (typically Avalanche) to all destination chains.
# Dry run first (ALWAYS)
npx tsx kk/bridge-from-source.ts --source avalanche --allocation config/allocation.json --dry-run
# Execute
npx tsx kk/bridge-from-source.ts --source avalanche --allocation config/allocation.json# Bridge $20 USDC to specific chains
npx tsx kk/bridge-from-source.ts --source avalanche --chains base,polygon --amount 20 --dry-run
npx tsx kk/bridge-from-source.ts --source avalanche --chains base,polygon --amount 20bridge-router.ts auto-selects the best provider.100000030 (not 143)Bridge USDC from Avalanche to native gas tokens (ETH, POL, CELO, MON) on destination chains.
# Dry run — shows quotes only
npx tsx kk/bridge-gas.ts --dry-run
# Execute all chains that need gas
npx tsx kk/bridge-gas.ts
# Specific chains only
npx tsx kk/bridge-gas.ts --chains base,monad| Chain | Gas/Agent | Total Need | ~USD Cost | Notes |
|---|---|---|---|---|
| Base | 0.0002 ETH | 0.005 ETH | ~$12 | Very cheap L2 |
| Ethereum | 0.00015 ETH | 0.004 ETH | ~$10 | L1, more expensive per TX |
| Polygon | 0.1 POL | 3.0 POL | ~$1.50 | Extremely cheap |
| Arbitrum | 0.0002 ETH | 0.005 ETH | ~$12 | Cheap L2 |
| Avalanche | 0.005 AVAX | 0.12 AVAX | ~$3 | Source chain, already has AVAX |
| Optimism | 0.0002 ETH | 0.005 ETH | ~$12 | Cheap L2 |
| Celo | 0.01 CELO | 0.30 CELO | ~$0.15 | No deBridge — needs Squid |
| Monad | 0.01 MON | 0.30 MON | ~$0.50 | Cheap L2 |
Note: Gas amounts in bridge-gas.ts:GAS_TARGETS include master wallet buffer. Adjust if budget is tight.
# Dry run first
npx tsx kk/distribute-funds.ts --chain base --tokens USDC --amount 0.20 --gas 0.0002 --dry-run
# Execute — all tokens on one chain
npx tsx kk/distribute-funds.ts --chain base --tokens USDC,EURC --amount 0.10 --gas 0.0002
# Gas only (no tokens)
npx tsx kk/distribute-funds.ts --chain ethereum --tokens USDC --amount 0 --gas 0.00015npx tsx kk/distribute-funds.ts --chain base --allocation config/allocation.json --dry-run
npx tsx kk/distribute-funds.ts --chain base --allocation config/allocation.jsonExecute per chain, all tokens + gas in one command:
# Base: USDC + EURC + gas
npx tsx kk/distribute-funds.ts --chain base --tokens USDC,EURC --amount 0.10 --gas 0.0002
# Ethereum: USDC + EURC + AUSD + PYUSD + gas (expensive! small amounts)
npx tsx kk/distribute-funds.ts --chain ethereum --tokens USDC,EURC,AUSD,PYUSD --amount 0.10 --gas 0.00015
# Polygon: USDC + AUSD + gas
npx tsx kk/distribute-funds.ts --chain polygon --tokens USDC,AUSD --amount 0.05 --gas 0.1
# Arbitrum: USDC + USDT + AUSD + gas
npx tsx kk/distribute-funds.ts --chain arbitrum --tokens USDC,USDT,AUSD --amount 0.10 --gas 0.0002
# Avalanche: USDC + EURC + AUSD + gas
npx tsx kk/distribute-funds.ts --chain avalanche --tokens USDC,EURC,AUSD --amount 0.10 --gas 0.005
# Optimism: USDC + USDT + gas
npx tsx kk/distribute-funds.ts --chain optimism --tokens USDC,USDT --amount 0.10 --gas 0.0002
# Celo: USDC + USDT + gas (sequential — slow, ~2min)
npx tsx kk/distribute-funds.ts --chain celo --tokens USDC,USDT --amount 0.02 --gas 0.01
# Monad: USDC + AUSD + gas (sequential — slow, ~2min)
npx tsx kk/distribute-funds.ts --chain monad --tokens USDC,AUSD --amount 0.10 --gas 0.01When funds are unevenly distributed or need redistribution:
# Dry run — see what would be recovered
npx tsx kk/sweep-funds.ts --target YOUR_PLATFORM_WALLET --dry-run
# Sweep specific chains
npx tsx kk/sweep-funds.ts --target 0xD386... --chains monad,polygon
# Tokens only (keep gas in wallets)
npx tsx kk/sweep-funds.ts --target 0xD386... --tokens-onlyIf one chain has excess and another needs more:
# Bridge $10 USDC from Avalanche to Arbitrum
npx tsx kk/bridge-from-source.ts --source avalanche --chains arbitrum --amount 10Run Phase 4 again with adjusted amounts.
After any operation, re-run the full inventory:
npx tsx kk/check-full-inventory.tsCompare with the allocation plan. All agents should have:
Master wallet doesn't have enough gas for the Disperse TX itself. Either:
--gas amount per agentMaster wallet doesn't have enough of that stablecoin. Either:
--amount.env.local (e.g., AVALANCHE_RPC_URL).env.local must be loaded BEFORE importing chains.ts (import order matters in scripts)SQUID_INTEGRATOR_ID env var is setdeBridge execution fee varies between quote and TX. Scripts add 2% buffer on approve. If still failing, increase buffer in bridge-from-source.ts or bridge-gas.ts.
These chains don't have Disperse.app deployed. Each transfer is 1 TX. 24 agents × 2-3 tokens = 48-72 TXs. Expect ~2-5 minutes per chain.
If echo, export, or other bash commands fail, use the Node.js wrapper pattern:
node -e "
const { execSync } = require('child_process');
execSync('npx tsx kk/<script>.ts <args>', {
stdio: 'inherit',
env: { ...process.env, WALLET_PRIVATE_KEY: '<loaded-from-aws>' }
});
"1. Inventory → check-full-inventory.ts
2. Plan → generate-allocation.ts (optional)
3. Bridge USDC → bridge-from-source.ts
4. Bridge Gas → bridge-gas.ts
5. Fan Out → distribute-funds.ts (per chain, per token)
6. Verify → check-full-inventory.ts
7. Rebalance → sweep-funds.ts + bridge + redistribute| File | Purpose |
|---|---|
scripts/kk/lib/chains.ts | Chain + token registry (must match Facilitator) |
scripts/kk/lib/debridge-client.ts | deBridge DLN REST API (7/8 chains) |
scripts/kk/lib/squid-client.ts | Squid Router REST API (7/8 chains, needs integrator ID) |
scripts/kk/lib/bridge-router.ts | Smart bridge selector (picks deBridge vs Squid) |
scripts/kk/config/wallets.json | 24 agent wallet addresses |
scripts/kk/config/allocation.json | Per-agent per-chain allocation plan |
docs/planning/KK_FUND_DISTRIBUTION_REFERENCE.md | Full operational reference |
memory/kk-fund-distribution.md | Fund tracking & inventory snapshots |
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.