
boha v0.19.0
暗号バウンティ、パズル、チャレンジのデータライブラリ
@agntn/puzzles
🧩 11のコレクションにまたがる333個の公開暗号パズルとバウンティを、型付きレコードとして収録。パズルを要求すれば、そのアドレス、鍵素材、そしてオンチェーンで何が起きたかが手に入る。
なぜ?
パズルのスレッドには必ず同じ3つのものがある。アドレス、賞金、そして誰が何を解いたか。スキャナやトラッカーは毎回それをスレッドから打ち直し、そのたびに少しずつ違うものになる。だからここに一度だけ、コードとして置いておく。パズルはTypeScriptのレコードだ。テストが読む前に型チェッカーが読む。CLI、MCPサーバー、そしてPiとOMPの拡張機能は1つのレジストリを読む。
ドキュメント、パズルごとに1ページ、そしてライブプレイグラウンド: puzzles.agntn.dev。
[!WARNING] 1.0未満。API、CLIフラグ、データモデルはまだ動く可能性がある。その上に何かを作るなら、正確なバージョンを固定すること。
✨ 機能
- 🧾 コードとしてのデータ。 パズルごとに1つの
PuzzleSpecリテラルを、そのチェーン用のファクトリで構築。JSONもビルドステップもなし。 - 🕳️ 無いものは無い。 解答者や賞金のないパズルにはそのキーが存在しない。何もnullとしてシリアライズされない。
- 🔑 あらゆる形の鍵素材。 Hex、WIF、BIP38ペイロード、シードフレーズ、秘密分散、あるいは単なるビット幅。ビルダーは1つ。
- 💤 遅延レジストリ。 パッケージをインポートしてもレコードは読み込まれない。
get("b1000/71")は1つのコレクションモジュールをインポートする。 - ✅ 検証は値。 公開された鍵がアドレスを導出するか、しないか。不正なレコードでも何もスローされない。
- 💰 ライブ残高。
@agntn/explorers経由のpuzzle.balance()。基本単位はbigint、APIキーはエラーから伏せられる。 - 🤖 6つのエージェントツール。 MCP、Pi、OMPの背後に1つのエグゼキュータ。どこでも同じ答え。
- 🌐 どこでも動く。 Fetch API上のニュートラルなESM。Node、ブラウザ、エッジワーカー。
📦 インストール
pnpm add @agntn/puzzles
CLIにはNode.js 24以降が必要。
🚀 最初の呼び出し
npx @agntn/puzzles stats
Total: 333
Solved: 131
Unsolved: 93
Claimed: 11
Swept: 96
Expired: 2
With pubkey: 237
鍵も設定もネットワークも不要。レコードはパッケージ内に同梱されている。以下で単にpuzzlesとあるのは、ローカルでpnpm addした後のpnpm exec puzzles、あるいはpnpm add -g @agntn/puzzlesした後のpuzzlesのこと。
puzzles show b1000/71
b1000/71 unsolved 7.100226 BTC 1PWo3JeB9jrGwfHDNpdGK54CRas7fsVzXU
コマンド
| Command | 出力内容 |
|---|---|
puzzles stats | 合計とステータス件数。--jsonで賞金の合計を追加 |
puzzles collections | コレクションごとに1行: キー、件数、作者 |
puzzles show <id> | 1つのパズル。--jsonでレコード全体 |
puzzles list [collection] | 1行に1つのパズル。--statusと--with-pubkeyで絞り込み |
puzzles verify [id] | 公開された鍵をそのアドレスと照合。--allで全パズル、不一致なら終了コード1 |
puzzles balance <id> | ライブ残高。Ethereumには--api-keyまたはETHERSCAN_API_KEY |
puzzles export | data_version付きのデータセット全体 |
puzzles mcp | stdio経由のMCPサーバー |
--jsonはどこでも同じシリアライザで、bigintは文字列として、存在しないフィールドは省略される。フラグと終了コードはCLIガイドにある。
🧠 ライブラリ
import { get, stats, verifyPuzzle } from "@agntn/puzzles";
import { b1000 } from "@agntn/puzzles/collections/b1000";
const puzzle = await get("b1000/71"); // loads the b1000 collection, nothing else
puzzle?.address().value; // "1PWo3JeB9jrGwfHDNpdGK54CRas7fsVzXU"
puzzle?.keyRange(); // [2n ** 70n, 2n ** 71n - 1n]
verifyPuzzle(b1000.require(1)).verified; // true, key 1 derives its address
(await stats()).unsolved; // 93
(await b1000.require(71).balance()).totalUnits(); // 7.10190014 when I ran it, mempool.space decides
ほぼこれで全部だ。コレクションはそれ自体がエントリで、その上のものはすべて同期的。コレクションをまたぐビューはロードを待つ。エラーはPuzzlesErrorから派生し、残高にはBalanceErrorの下に独自のファミリーがある。残りはガイドにある: records、registry、lookups、verification、balances。
🗺️ コレクション
| Key | Puzzles | Chains | 内容 |
|---|---|---|---|
b1000 | 256 | bitcoin | 1〜256ビットの鍵、それぞれ1アドレス |
rushwallet | 30 | bitcoin | 2014年のコンテストのブレインウォレット |
zden | 15 | bitcoin, ethereum, litecoin, decred | Zdenのビジュアルパズル |
arweave | 12 | arweave, ethereum | Tiamatのウィーブパズル |
warp | 6 | bitcoin | Keybaseのscryptブレインウォレットチャレンジ |
hash_collision | 6 | bitcoin | Peter ToddのP2SH衝突バウンティ |
ballet | 3 | bitcoin | 物理ウォレットに印刷されたBIP38鍵 |
bitimage | 2 | bitcoin | 写真からハッシュ化されたシード |
bitaps | 1 | bitcoin | 3 of 5の秘密分散スキーム |
gsmg | 1 | bitcoin | 多段階の画像パズル |
movie_enigma | 1 | bitcoin | シードワードとしての映画タイトル、2026年に解決 |
識別子はcollection/name。3つのシングルトン、gsmg、bitaps、movie_enigmaは単にそのキーそのもの。各コレクションにはストーリー、癖、そしてすべてのパズルを載せたページがある: puzzles.agntn.dev/collections。
🤖 エージェント
claude mcp add puzzles --scope user -- npx -y @agntn/puzzles mcp
pi install npm:@agntn/puzzles
{
"mcpServers": {
"puzzles": { "command": "npx", "args": ["-y", "@agntn/puzzles", "mcp"] }
}
}
6つのツール: puzzles_stats、puzzles_collections、puzzles_show、puzzles_list、puzzles_verify、puzzles_balance。プロセスの外に出るのは最後の1つだけで、そのアノテーションがそう明示している。テキストが何を運び、制限がどこにあるかはエージェントガイドに。
🚫 これがやらないこと
何も解かない。スキャナも、カンガルーも、ブレインウォレットクラッカーも、トランザクションリストからステータスを推測することもない。solved、swept、claimed、expiredは手で書き込まれている。なぜなら、クレームトランザクションと公開された鍵があっても、それは解決済みを意味するからだ。チェーンの事実は@agntn/chainsから、鍵導出は@agntn/keysから、残高は@agntn/explorersから。このパッケージはそれらのどれも再実装しない。
🧩 パズルの追加
src/collections/<key>/の下に1つのレコードファイルと、コレクションモジュールに1行。あとはpnpm testがデータゲートを実行する: 一意なid、アドレスとtxidのフォーマット、鍵導出、BIP38ペイロード、アセットパス、nullなし。レコードの形はPuzzle recordsに、ルールはCONTRIBUTING.mdにある。
🛠️ 開発
pnpm install
pnpm --dir docs install # the docs site; lint and test read the Nuxt types it generates
pnpm lint # oxfmt and oxlint, docs included
pnpm typecheck # builds first, then checks src, Pi and OMP
pnpm test # unit tests and the data gate
pnpm test:packed # packs the tarball and runs every published entry without src/
pnpm docs # the Docus site on localhost
💛 謝辞
このパッケージはAnthropicとOpenAIのオープンソースプログラムのおかげで存在している: Claude for Open SourceとCodex for Open Source。