Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions lens-b20/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
name: lens-b20
description: B20 token skill on Base via LENS. Use when an agent wants to create a B20 token (Base's native precompile token standard, shipped with the Beryl upgrade), validate a config with a live gas + admin-balance check plus a LENS rug-risk read on the config, build a complete ABI-encoded EIP-1559 deployment transaction, read any ERC-20 on Base, check wallet ETH balances, get current gas, or verify a tx receipt. No authentication required. Supports Base mainnet and Base Sepolia.
metadata:
{
"clawdbot": {
"emoji": "\u25c9",
"homepage": "https://lnsx.io/b20"
}
}
---

# LENS B20

Deploy and vet B20 tokens on Base — the native precompile token standard that ships with Base Beryl. ERC-20 compatible, role-gated, with compliance policies built in. No Solidity required.

Built by **LENS** (https://lnsx.io), the on-chain rug-risk scanner for Base. What makes this skill different: every config you `validate` or `prepare` also gets a **LENS read**, so you can see how the choices you make (retained admin, freeze, allowlist) would score on a public trust scan *before* you deploy.

All actions use real Base RPC calls — gas, nonces, and balances are fetched live from the chain, nothing is mocked. No auth, no API key.

## When to use

Use this skill when the user wants to:
- create / deploy a B20 token on Base, or build the deployment transaction for one
- check whether a token config looks safe (rug-risk / centralization read) before deploying
- read any ERC-20 on Base (name, symbol, decimals, supply, balances)
- check an address's ETH balance, current gas, or a transaction receipt

## How to use

Run the helper script with an action. Read-only actions (`info`, `gas`) take no body; the rest take a JSON payload.

```bash
# live chain status, gas, and the B20 standard overview
scripts/lens.sh info

# current EIP-1559 gas + B20 deploy cost estimate
scripts/lens.sh gas

# ETH (and optional ERC-20) balance for an address
scripts/lens.sh balance '{"address":"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"}'

# read any ERC-20 on Base
scripts/lens.sh token_info '{"address":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"}'

# validate a config: live admin-balance check + LENS rug-risk read
scripts/lens.sh validate '{"name":"LENS","symbol":"LENS","variant":"asset","decimals":18,"admin":"0x...","policies":{"freeze":true}}'

# build a full unsigned EIP-1559 deploy tx (live gas + nonce)
scripts/lens.sh prepare '{"name":"LENS","symbol":"LENS","variant":"asset","decimals":18,"supply_cap":"1000000000","admin":"0x...","network":"mainnet"}'

# check a deploy receipt + parse the new token address
scripts/lens.sh receipt '{"tx_hash":"0xabc...","network":"mainnet"}'
```

The script just wraps the public endpoint `https://lens-liard.vercel.app/api/b20-skill`, so any action can also be called directly with `curl` (see `references/lens-b20.md`).

## Safety

- This skill is **read-only by default**. `validate`, `prepare`, `token_info`, `balance`, `receipt`, `info`, and `gas` never move funds and never sign anything.
- `prepare` returns an **unsigned** transaction only. Signing and broadcasting is the user's decision and happens in their wallet, not here.
- B20 activates on Base mainnet with **Beryl on 25 Jun 2026, 18:00 UTC**. Before then you can `validate` and `prepare`, and deploy on **Base Sepolia** testnet. Only sign and broadcast on mainnet once B20 is live.

## LENS read

The `validate` and `prepare` responses include a `lensCheck` block with a **CLEAR / CAUTION** verdict. It flags a retained `admin` and a `freeze` policy as centralization risk, because that is how they score on a public LENS trust scan. For a token that reads CLEAR: no freeze, open transfers, and `adminless: true` (or renounce admin) once setup is done.

See `references/lens-b20.md` for the full action reference, token parameters, variants, compliance policies, and networks.
23 changes: 23 additions & 0 deletions lens-b20/catalog.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"schemaVersion": 1,
"slug": "lens-b20",
"provider": "LENS",
"providerUrl": "https://lnsx.io",
"logo": null,
"demo": {
"title": "lens-cli.sh",
"language": "bash",
"code": "# Live Base chain status, gas + the B20 standard overview\nscripts/lens.sh info\n\n# Validate a B20 config + a LENS rug-risk read before you deploy\nscripts/lens.sh validate '{\"name\":\"TKN\",\"symbol\":\"TKN\",\"variant\":\"asset\",\"decimals\":18,\"admin\":\"0x...\",\"policies\":{\"freeze\":true}}'\n\n# Build a full UNSIGNED EIP-1559 deploy tx (live gas + nonce)\nscripts/lens.sh prepare '{\"name\":\"TKN\",\"symbol\":\"TKN\",\"supply_cap\":\"1000000000\",\"admin\":\"0x...\"}'\n\n# Read any ERC-20 on Base\nscripts/lens.sh token_info '{\"address\":\"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\"}'"
},
"setup": [
"Install: `install the lens-b20 skill from https://github.com/BankrBot/skills/tree/main/lens-b20`",
"No API key or auth required",
"Read-only by default; `prepare` returns an unsigned transaction only, it never signs or broadcasts",
"B20 mainnet deploy activates with Base Beryl on 25 Jun 2026 18:00 UTC; until then validate/prepare or deploy on Base Sepolia"
],
"install": {
"type": "bankr",
"repoPath": "lens-b20",
"command": "install the lens-b20 skill from https://github.com/BankrBot/skills/tree/main/lens-b20"
}
}
165 changes: 165 additions & 0 deletions lens-b20/lens-b20.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
# LENS B20 — Full Reference

On-chain B20 token tooling for Base, built by [LENS](https://lnsx.io). This document is the detailed reference for the `lens-b20` skill. The high-level instructions live in `../SKILL.md`; the runnable wrapper is `../scripts/lens.sh`.

**Endpoint:** `https://lens-liard.vercel.app/api/b20-skill`
**Auth:** none
**Manifest:** `https://lens-liard.vercel.app/api/b20-skill?action=manifest`

> B20 activates on Base mainnet with the Beryl upgrade on **25 Jun 2026, 18:00 UTC**. Before that you can `validate` and `prepare`, and deploy on Base Sepolia. Sign and broadcast on mainnet once B20 is live.

---

## Actions

| Action | Method | What it does |
|--------|--------|-------------|
| `info` | GET | Live chain status, gas prices, B20 standard overview |
| `gas` | GET | EIP-1559 gas breakdown with deploy cost estimate |
| `balance` | POST | ETH balance + optional ERC-20 balance for any address |
| `token_info` | POST | Read name, symbol, decimals, total supply for any ERC-20 on Base |
| `validate` | POST | B20 config check + live admin balance vs gas + a LENS risk read |
| `prepare` | POST | Complete unsigned EIP-1559 deployment tx with live gas + nonce |
| `receipt` | POST | Tx hash status + deployed token address from factory logs |

---

## Direct calls

### GET `?action=info`
```bash
curl 'https://lens-liard.vercel.app/api/b20-skill?action=info'
```
Returns current block, base fee, gas tips, the B20 factory address, variant descriptions, and the feature list.

### GET `?action=gas`
```bash
curl 'https://lens-liard.vercel.app/api/b20-skill?action=gas'
```
EIP-1559 breakdown (base fee, maxFeePerGas, priority tips at 25/50/75th pct) + estimated B20 deploy cost in ETH.

### POST `balance`
```bash
curl -X POST https://lens-liard.vercel.app/api/b20-skill \
-H 'Content-Type: application/json' \
-d '{ "action": "balance", "address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" }'
```
Add `"token": "0x..."` to also check an ERC-20 balance at the same address.

### POST `token_info`
```bash
curl -X POST https://lens-liard.vercel.app/api/b20-skill \
-H 'Content-Type: application/json' \
-d '{ "action": "token_info", "address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "holder": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" }'
```
Reads name, symbol, decimals, total supply via live `eth_call`. Add `"holder"` to also return that address's balance.

### POST `validate`
```bash
curl -X POST https://lens-liard.vercel.app/api/b20-skill \
-H 'Content-Type: application/json' \
-d '{
"action": "validate",
"name": "LENS",
"symbol": "LENS",
"variant": "asset",
"decimals": 18,
"admin": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
"policies": { "freeze": true }
}'
```
Validates the config, fetches the admin wallet's live ETH balance vs the deploy cost, and returns a `lensCheck` block: a CLEAR / CAUTION verdict on whether the config (admin retained, freeze on, allowlist on) would read as a centralization risk on a LENS scan.

### POST `prepare`
```bash
curl -X POST https://lens-liard.vercel.app/api/b20-skill \
-H 'Content-Type: application/json' \
-d '{
"action": "prepare",
"name": "LENS",
"symbol": "LENS",
"variant": "asset",
"decimals": 18,
"supply_cap": "1000000000",
"admin": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
"policies": {},
"network": "mainnet"
}'
```
Returns ABI-encoded calldata for the B20 factory and a complete **unsigned** EIP-1559 transaction with live gas and nonce. Sign and broadcast once B20 activates.

### POST `receipt`
```bash
curl -X POST https://lens-liard.vercel.app/api/b20-skill \
-H 'Content-Type: application/json' \
-d '{ "action": "receipt", "tx_hash": "0xabc123...", "network": "mainnet" }'
```
Returns `success` / `pending` / `failed`, gas used, block number, and the deployed token address parsed from factory logs.

---

## Token parameters

| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `name` | string | yes | Max 64 chars |
| `symbol` | string | yes | Max 11 alphanumeric chars |
| `admin` | string | yes | 0x wallet — required unless `adminless: true` |
| `variant` | `asset` \| `stablecoin` | — | Default: `asset` |
| `decimals` | integer 6-18 | — | Default: 18. Fixed at 6 for stablecoin. |
| `supply_cap` | string | — | Integer string. `"0"` = uncapped. |
| `adminless` | boolean | — | No admin. Irreversible — no minting or policy changes ever. |
| `policies.allowlist` | boolean | — | Only allowlisted addresses can hold or receive |
| `policies.blocklist` | boolean | — | Blocked addresses cannot send or receive |
| `policies.freeze` | boolean | — | Admin can freeze any account and seize its balance |
| `contract_uri` | string | — | IPFS URI for token metadata |
| `network` | `mainnet` \| `sepolia` | — | Default: `mainnet` (Base, chainId 8453) |

---

## B20 variants

**`asset`** — general-purpose. Configurable decimals (6-18), rebasing support, issuer metadata. Good for governance tokens, on-chain-native assets, and RWAs.

**`stablecoin`** — fiat-focused. Fixed 6 decimals, currency code field. Good for fiat-backed stablecoins and regulated assets.

Both are ERC-20 compatible — no changes needed in wallets, DEXes, or indexers.

---

## Compliance policies

Policies are set at deploy time and encoded as a bitmask in the factory call.

| Policy | Bit | Description |
|--------|-----|-------------|
| `allowlist` | 0 | Only allowlisted addresses can hold or receive |
| `blocklist` | 1 | Blocked addresses cannot send or receive |
| `freeze` | 2 | Admin can freeze an account and seize its balance |

`allowlist` and `blocklist` can both be enabled — allowlist takes precedence.

### LENS note on policies

The LENS read in `validate` and `prepare` flags `freeze` and a retained `admin` as centralization risk signals, because that is how they score on a public trust scan. For a token that reads CLEAR: no freeze, open transfers, and `adminless: true` (or renounce admin) once setup is done. Note: `adminless` is irreversible — if you need to mint the full supply or do post-deploy setup, deploy with admin retained, finish setup, then renounce.

---

## Networks

| Network | Chain ID | RPC |
|---------|----------|-----|
| Base (mainnet) | 8453 | https://mainnet.base.org |
| Base Sepolia (testnet) | 84532 | https://sepolia.base.org |

Pass `"network": "sepolia"` to any POST action to target testnet.

---

## Links

- **LENS** — https://lnsx.io
- **B20 page** — https://lnsx.io/b20
- **Scanner / Markets** — https://lnsx.io/markets
- **API manifest** — https://lens-liard.vercel.app/api/b20-skill?action=manifest
- **X** — https://x.com/lnsx_io
55 changes: 55 additions & 0 deletions lens-b20/scripts/lens.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/usr/bin/env bash
#
# LENS B20 skill — thin wrapper around the public LENS API on Base.
# Read-only by default. No authentication required.
#
# Usage:
# scripts/lens.sh info
# scripts/lens.sh gas
# scripts/lens.sh balance '{"address":"0x..."}'
# scripts/lens.sh token_info '{"address":"0x..."}'
# scripts/lens.sh validate '{"name":"LENS","symbol":"LENS","variant":"asset","decimals":18,"admin":"0x..."}'
# scripts/lens.sh prepare '{"name":"LENS","symbol":"LENS","supply_cap":"1000000000","admin":"0x...","network":"mainnet"}'
# scripts/lens.sh receipt '{"tx_hash":"0x...","network":"mainnet"}'
#
# Endpoint can be overridden with LENS_B20_ENDPOINT.
#
set -euo pipefail

ENDPOINT="${LENS_B20_ENDPOINT:-https://lens-liard.vercel.app/api/b20-skill}"
ACTION="${1:-info}"
PAYLOAD="${2:-}"

usage() {
echo "usage: lens.sh <action> [json]" >&2
echo "actions: info gas balance token_info validate prepare receipt manifest" >&2
}

case "$ACTION" in
-h|--help|help)
usage; exit 0 ;;

info|gas|manifest)
curl -fsS "${ENDPOINT}?action=${ACTION}"
echo ;;

balance|token_info|validate|prepare|receipt)
PAYLOAD="${PAYLOAD:-{}}"
if command -v jq >/dev/null 2>&1; then
BODY=$(printf '%s' "$PAYLOAD" | jq -c --arg a "$ACTION" '. + {action:$a}')
else
INNER=$(printf '%s' "$PAYLOAD" | sed -e 's/^[[:space:]]*{//' -e 's/}[[:space:]]*$//')
if [ -n "$(printf '%s' "$INNER" | tr -d '[:space:]')" ]; then
BODY="{\"action\":\"${ACTION}\",${INNER}}"
else
BODY="{\"action\":\"${ACTION}\"}"
fi
fi
curl -fsS -X POST "$ENDPOINT" -H 'Content-Type: application/json' -d "$BODY"
echo ;;

*)
echo "unknown action: $ACTION" >&2
usage
exit 1 ;;
esac