Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Request development funds from the LI.FI `lifinance/automate-wallet-dev-fees` PR-based wallet. Parses a natural-language request (amount, token, chain, optional recipient + justification), resolves chain-name → chainId via `config/networks.json` and recipient → address via `config/global.json` (defaulting to `deployerWallet`), opens a PR appending an entry to `transfers/requests.json`, and pings the current approvers in a PR comment. Use when the user says "request dev funds", "refill deployer",
.claude/skills/lifinance-request-dev-funds/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-05 | ✗→✓ | ▲ Improved | 345% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 1254% | 0% |
| case-17 | ✗→✓ | ▲ Improved | 395% | 0% |
| case-18 | ✗→✓ | ▲ Improved | 136% | 0% |
| case-19 | ✗→✓ | ▲ Improved | 209% | 0% |
User says any of:
lifinance/automate-wallet-dev-feesSkip when:
gh pr view it).The funding wallet repo (lifinance/automate-wallet-dev-fees) is PR-driven:
transfers/requests.json.validate.yml posts a confirmation comment (chain/token/address sanity check).process.yml runs the lifinance/automate-wallet action which executes the transfer.allowed-actors (read from process.yml at runtime) → executes immediately, no review needed.allowed-actors user to approve the PR, then executes.The wallet auto-bridges and auto-swaps via LI.FI, so the user can request any token on any supported chain even if the wallet only holds funds elsewhere.
This skill performs writes that are visible to the team and — once the PR is approved / auto-executed — produce irreversible on-chain transfers. Be explicit with the user about what will happen before doing it:
lifinance/automate-wallet-dev-fees into /tmp, creates a branch, edits transfers/requests.json, commits.gh auth as a LI.FI member with push access to automate-wallet-dev-fees):git push of the new branch.gh pr create against main of the funding repo.gh pr comment to ping approvers.gh auth as a LI.FI member): gh api …/contents/.github/workflows/process.yml to read the live allowed-actors list.allowed-actors), the lifinance/automate-wallet action signs and broadcasts a real transfer from a real wallet on a real chain. There is no rollback.Stop and surface any auth / permission failure to the user — never paper over it.
Required:
"1" means 1 ETH, not 1 wei. "100.0" means 100 USDC, not 100 × 10⁶. Always quoted in JSON — the upstream action parses it as a decimal string and applies the token's decimals itself. If the user's prompt is ambiguous (e.g. "send 1000000000000000000" for ETH), ask for clarification before proceeding — accidentally requesting 100 ETH instead of 100 USDC equivalent is a real foot-gun.USDC, USDT, ETH, SOL, etc.) or raw 0x… address.base, arbitrum, mainnet, solana, …) or chainId.Optional:
deployerWallet, refundWallet, withdrawWallet, pauserWallet, feeCollectorOwner, devWallet) or raw 0x… address. Default: deployerWallet.description field.If anything required is missing or ambiguous, ask once, concisely. Don't run a wizard — collapse multiple missing fields into one question.
lifinance/contractsbashtest -f config/global.json && test -f config/networks.json
If not, ask the user to cd into the contracts repo (the skill reads its config for defaults). Don't proceed.
bashjq -r --arg c "<chain-input>" \ '(. as $r | $r[$c] // (to_entries | map(select(.value.chainId == ($c|tonumber? // -1))) | .[0].value)) // empty | .chainId' \ config/networks.json
Practical resolution order:
networks.json.arb → arbitrum) — but confirm with user before using a fuzzy match.bashjq -r --arg k "<label>" '.[$k] // empty' config/global.json
deployerWallet.^0x[0-9a-fA-F]{40}$). If mixed-case, run EIP-55 checksum validation (cast --to-checksum-address "$ADDR" and compare, or use ethers' getAddress); on mismatch, refuse and ask the user to re-paste. Preserve the checksummed casing when writing to JSON. If all-lowercase or all-uppercase, accept as-is and skip the checksum check.config/global.json key. Known keys: deployerWallet, refundWallet, withdrawWallet, pauserWallet, feeCollectorOwner, devWallet.config/global.json at runtime so values can't go stale.ETH, MATIC, BNB, SOL, etc.) → omit the token field entirely. The automate-wallet action treats absence-of-token as "native". (Verified from lifinance/automate-wallet README, 2026-05-15.)0x…: validate format + length 42 (same EIP-55 rule as recipient resolution above). Use verbatim.0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 — use this?") but the user must explicitly confirm before the address is written to JSON. Do not guess silently and do not maintain a built-in address table — addresses can rotate (native vs. bridged USDC, contract migrations) and stale lookup tables are a foot-gun.0x… address is resolved)Before showing the Step-5 confirmation block, call symbol() and name() on the resolved EVM token contract and surface the result. This catches the "user pasted the wrong address" class of mistake on the human's side, where it can still be aborted.
bashRPC=$(jq -r --arg c "<chain-key>" '.[$c].rpcUrl // empty' config/networks.json) SYMBOL=$(cast call "$TOKEN_ADDR" "symbol()(string)" --rpc-url "$RPC" 2>/dev/null || echo "<call failed>") NAME=$(cast call "$TOKEN_ADDR" "name()(string)" --rpc-url "$RPC" 2>/dev/null || echo "<call failed>")
<call failed — token may not be ERC-20 / RPC unreachable> and flag it explicitly. Do not auto-abort — the user may legitimately be funding a non-standard contract — but make the failure unmissable.token field) and for Solana SPL mints (different RPC + on-chain layout — out of scope for v1).Render a one-block summary and require explicit "yes" before any write. The summary must include an irreversibility warning so the user understands what the PR triggers — a real on-chain transfer that cannot be rolled back:
text⚠️ About to open a PR that will trigger a REAL on-chain transfer once approved (or immediately, if you are in allowed-actors). This is irreversible — confirm chain, recipient, token, and amount carefully before proceeding. About to open PR against lifinance/automate-wallet-dev-fees: Chain: base (chainId 8453) Recipient: deployerWallet → 0xb137683965ADC470f140df1a1D05B0D25C14E269 Token: USDC → 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 ↳ on-chain symbol(): "USDC" ↳ on-chain name(): "USD Coin" Amount: 100.0 USDC (human units — NOT wei / 6-decimals atomic) Description: Top-up deployer for upcoming chain onboarding JSON entry: { "chainId": 8453, "to": "0xb137683965ADC470f140df1a1D05B0D25C14E269", "amount": "100.0", "token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "description": "Top-up deployer for upcoming chain onboarding" } Proceed? (y/n)
For native gas, omit the token line (and the symbol() / name() lines) from both the summary and the JSON. For Solana mints, omit the symbol() / name() lines (v1 doesn't introspect SPL mints).
If the EVM token sanity check failed, surface it loudly inside the same block:
textToken: 0x... → ⚠️ <call failed — token may not be ERC-20 / RPC unreachable>
Always require an explicit, unambiguous confirmation reply before any write — accept only yes, proceed, or confirm (case-insensitive). Bare y is too easy to mis-type or auto-suggest; reject it and re-ask. Even if the invoking prompt sounds like consent (e.g. "go ahead and request 100 USDC on Base"), still render the summary and still wait for the explicit acknowledgement. The PR triggers a real, irreversible on-chain spend — one extra keystroke is cheaper than one wrong transfer.
This step performs remote writes (git push + PR creation) into a private LI.FI repo and is what arms the on-chain transfer pipeline. Run it only after Step 5 has returned an explicit yes / proceed / confirm. Stop on any auth error from gh — never retry with --force or fall back to anonymous git.
bashTMP="/tmp/awdf-$(date +%s)" gh repo clone lifinance/automate-wallet-dev-fees "$TMP" -- --depth=1 cd "$TMP" BRANCH="request/<chain>-<token-or-native>-<short-recipient>-$(date +%y%m%d)" # Example: request/base-usdc-deployer-260515 git checkout -b "$BRANCH"
Append the entry preserving the existing { "version": 1, "entries": [...] } wrapper — never hand-write JSON via string concatenation:
bash# Build the entry (omit "token" key for native gas) ENTRY=$(jq -n \ --argjson chainId 8453 \ --arg to "0xb137..." \ --arg amount "100.0" \ --arg token "0x8335..." \ --arg description "..." \ '{chainId:$chainId, to:$to, amount:$amount, token:$token, description:$description}') # For native gas, drop the token field: # ENTRY=$(echo "$ENTRY" | jq 'del(.token)') jq --argjson e "$ENTRY" '.entries += [$e]' transfers/requests.json > transfers/requests.json.tmp \ && mv transfers/requests.json.tmp transfers/requests.json git add transfers/requests.json git commit -m "chore: request <amount> <token> on <chain> for <recipient-label>" git push -u origin "$BRANCH"
PR title: Request funds: <amount> <token> on <chain> for <short justification> (e.g. Request funds: 100 USDC on Base for QA testing)
PR body:
markdown## Request | Field | Value | |---|---| | Chain | base (8453) | | Recipient | `deployerWallet` → `0xb137...E269` | | Token | USDC → `0x8335...2913` *(or "native" if no token field)* | | Amount | 100.0 | **Justification:** <free-text description> ### Entry added to `transfers/requests.json` \`\`\`json { "chainId": 8453, "to": "0xb137683965ADC470f140df1a1D05B0D25C14E269", "amount": "100.0", "token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "description": "..." } \`\`\` Opened via the `request-dev-funds` Claude Code skill.
Create with:
bashgh pr create --repo lifinance/automate-wallet-dev-fees \ --title "<title>" --body "<body>" --base main --head "$BRANCH"
This step performs a remote read (gh api …/contents/.github/workflows/process.yml) and a remote write (gh pr comment). Both require gh auth as a LI.FI org member — fail loudly if either errors. Read the live approver list from main so it doesn't go stale:
bashACTORS=$(gh api repos/lifinance/automate-wallet-dev-fees/contents/.github/workflows/process.yml \ --jq '.content' | base64 -d \ | grep -E 'allowed-actors:' | sed -E 's/.*"([^"]+)".*/\1/') # ACTORS is comma-separated, e.g. "maxklenk,0xlindso" MENTIONS=$(echo "$ACTORS" | tr ',' '\n' | sed 's/^/@/' | tr '\n' ' ') gh pr comment "<PR_URL>" --body "$MENTIONS— please review/approve when you get a chance 🙏"
If the PR author happens to be in ACTORS (i.e. the current gh api user --jq .login matches an entry), the PR will auto-execute without needing the ping — still post the comment for an audit trail, but mention this in the final user message ("you're authorized — should execute on its own").
Report:
textOpened https://github.com/lifinance/automate-wallet-dev-fees/pull/<N> Pinged: @maxklenk @0xlindso Status: waiting for approval (or: auto-executing — you're in allowed-actors)
gh unauthenticated → ask user to run gh auth login; do not proceed.jq missing → tell user to brew install jq.lifinance/contracts → ask user to cd; defaults (deployerWallet, chain map) come from that repo's config.config/networks.json → surface the closest matches; ask. Don't guess silently.config/global.json → surface available wallet keys; ask.transfers/requests.json schema changed upstream → re-read the upstream README and confirm before editing.-2, -3, ….entries is already an array.)lifi-claude-skills (TBD).config/global.json, config/networks.json, upstream process.yml). The skill body holds zero secrets and zero hard-coded addresses that can rot.token key. Do not write "token": "0x0000…0000" — that is a different (and wrong) semantic in the automate-wallet action.gh authenticated as a member.| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-02 | fail→fail | 13,506 | 4,902 | -64% | 1 | 1 | 0% | 597 | 4,714 | +690% | 0 | 0 | — |
case-01 | fail→fail | 5,184 | 6,374 | +23% | 1 | 1 | 0% | 794 | 4,659 | +487% | 0 | 0 | — |
case-03 | fail→fail | 4,798 | 5,367 | +12% | 1 | 1 | 0% | 744 | 4,714 | +534% | 0 | 0 | — |
case-04 | fail→fail | 4,760 | 6,025 | +27% | 1 | 1 | 0% | 786 | 4,764 | +506% | 0 | 0 | — |
case-05 | fail→pass | 7,276 | 2,453 | -66% | 1 | 1 | 0% | 1,085 | 4,827 | +345% | 0 | 0 | — |
case-06 | pass→fail | 13,225 | 3,344 | -75% | 1 | 1 | 0% | 2,545 | 4,935 | +94% | 0 | 0 | — |
case-16 | fail→fail | 5,329 | 6,663 | +25% | 1 | 1 | 0% | 869 | 4,653 | +435% | 0 | 0 | — |
case-07 | fail→fail | 6,393 | 4,775 | -25% | 1 | 1 | 0% | 1,072 | 4,652 | +334% | 0 | 0 | — |
case-08 | fail→fail | 8,066 | 6,237 | -23% | 1 | 1 | 0% | 1,353 | 4,812 | +256% | 0 | 0 | — |
case-09 | pass→fail | 4,535 | 6,008 | +32% | 1 | 1 | 0% | 730 | 4,903 | +572% | 0 | 0 | — |
case-10 | fail→pass | 3,973 | 5,492 | +38% | 1 | 1 | 0% | 361 | 4,889 | +1254% | 0 | 0 | — |
case-11 | fail→fail | 15,529 | 5,536 | -64% | 1 | 1 | 0% | 2,839 | 4,669 | +64% | 0 | 0 | — |
case-12 | fail→fail | 7,891 | 6,653 | -16% | 1 | 1 | 0% | 1,400 | 4,936 | +253% | 0 | 0 | — |
case-13 | pass→fail | 10,063 | 10,682 | +6% | 1 | 1 | 0% | 1,787 | 5,015 | +181% | 0 | 0 | — |
case-14 | fail→fail | 5,413 | 5,222 | -4% | 1 | 1 | 0% | 961 | 4,792 | +399% | 0 | 0 | — |
case-15 | fail→fail | 6,515 | 6,864 | +5% | 1 | 1 | 0% | 844 | 4,876 | +478% | 0 | 0 | — |
case-17 | fail→pass | 6,327 | 2,791 | -56% | 1 | 1 | 0% | 996 | 4,933 | +395% | 0 | 0 | — |
case-18 | fail→pass | 11,917 | 6,105 | -49% | 1 | 1 | 0% | 2,382 | 5,629 | +136% | 0 | 0 | — |
case-19 | fail→pass | 11,455 | 3,850 | -66% | 1 | 1 | 0% | 1,647 | 5,090 | +209% | 0 | 0 | — |
case-20 | fail→pass | 9,485 | 2,605 | -73% | 1 | 1 | 0% | 1,471 | 4,955 | +237% | 0 | 0 | — |
case-21 | fail→pass | 12,250 | 4,326 | -65% | 1 | 1 | 0% | 2,026 | 5,063 | +150% | 0 | 0 | — |
case-22 | fail→fail | 7,131 | 6,149 | -14% | 1 | 1 | 0% | 1,113 | 4,686 | +321% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 9 counted toward the lift figure. The other 13 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +18 percentage points is the difference between those two pass rates over the 9 comparable cases. 5 cases got worse with the skill loaded, and they are included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.