nano-pay について
nano-pay は、AI エージェント向けのセルフホスト型 Nano(XNO)ウォレット、x402 決済クライアント、マーチャントサーバーです。ローカル署名に加え、支出上限、決済記録、台帳での確認機能を備えています。
主な機能
- 01Nano ウォレットとローカル署名
- 02x402 決済ハンドシェイクの処理
- 03決済ごとの価格上限設定
- 04未完了決済の記録と再試行
- 05マーチャント側の検証と決済確定
活用シーン
- 01Nano で API の従量料金を支払う
- 02支払い前にエンドポイントの価格を確認
- 03Nano 決済対応の API サービスを運用
MCP 対応
価格上限付きで x402 決済を行う MCP ツール `x402_pay` を提供します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
nano-pay · Feeless402
AI エージェント向けに構築された、自己管理型 Nano(XNO)ウォレットと x402 決済クライアント、そして加盟店サーバーです。クライアントは支払い、nano-pay serve は収益を得ます。有料エンドポイント、オンレジャーでの検証/決済(ファシリテーター不要)、スターターファウセット、訪問したエージェントにオンボーディング方法を案内する railHint x402 拡張機能を備えています(SPEC-railhint.md を参照)。サイト:site/index.html + site/llms.txt。
他プロジェクトへの働きかけに関する注意: Feeless402 は、他のプロジェクトでイシュー、プルリクエスト、提案を作成しません。他の場所で「Nano レール」を売り込み、Feeless402 の名前を挙げている投稿は、当社とは無関係のアカウントによるものです。リポジトリにそのような投稿が届いた場合は、自由にクローズしてください。ご質問は、こちらでイシューを作成してください。
売り文句を数字ひとつで: 同じ 5 ドルで、1 回あたり USDC-on-Base x402 決済(加盟店が価格の下限を 0.001 USDC に設定)の API 呼び出しを 5,000 回支払うことも、Nano で実際の従量制価格(nano-gpt.com で実稼働時に確認され、オンレジャーで検証済みの 1 回あたり 0.0000096 ドル)で数十万回の呼び出しを支払うこともできます。一度チャージすれば、ずっとマイクロペイメントを利用できます。
インストール
pip install feeless402 # needs Python 3.10+; pulls nanopy + requests
# (from a checkout: pip install -e .)
nano-pay init # creates ~/.nano-pay/wallet.json (chmod 600)
エージェントのフロー
nano-pay topup 5 # quote: $5 USDC-BASE → ~12.3 XNO (NanSwap)
nano-pay topup 5 --execute # create order (set NANSWAP_API_KEY)
# → send USDC to the returned deposit address; XNO arrives in 30-60s
nano-pay receive # pocket incoming XNO
nano-pay quote https://nano-gpt.com/api/v1/chat/completions \
--json '{"model":"gpt-5-nano","messages":[{"role":"user","content":"hi"}]}'
nano-pay pay https://nano-gpt.com/api/v1/chat/completions \
--json '{"model":"gpt-5-nano","messages":[{"role":"user","content":"hi"}]}'
pay は x402 のハンドシェイク全体を処理します:リクエスト → 402 の見積もりを解析(x402nano/PAYMENT-REQUIRED v2 方言と NanoGPT/accepts v1 方言の両方に対応)→ 価格上限を確認 → 送金状態ブロックにローカルで署名 → PAYMENT-SIGNATURE + X-PAYMENT ヘッダーを付けて再試行します。サーバーはファシリテーター経由でブロックを決済します。サーバーが受け入れない限り、ブロードキャストされることはありません。加盟店からの応答が失われた場合、または 2xx 以外の場合、クライアントは何かを報告する前に、署名したブロックのハッシュについてレジャーに問い合わせます。レシートの settled は true、false、または "indeterminate" のいずれかで、推測で決まることはありません。オンレジャーに記録されたブロックに対して再度支払うことはありません。同じブロックを再提示してください。現在、クライアントはこの再提示を自動で行います。すべての決済は送信前にウォレットの隣のファイル(pending-payments.json)に記録され、再試行時(同じ呼び出し内でも、クラッシュ後でも)には、支払者のブロックハッシュ、メソッド、パスに対する署名を含む X-PAYMENT-PROOF ヘッダーを付けて、同じ署名済みブロックを再送信します。サーバーは、証明付きの再提示を 24 時間受け付けるため、公開ブロックを再生するオブザーバーが支払者の再試行回数を使い切ることはできません。(v0.2.9。 giskard09 から非公開で報告され、独立したハーネスによる修正の再検証も実施されました。アドバイザリー GHSA-cx37-j5vc-c967 を参照してください。v0.2.10 では、この再検証から得られた次の 2 つの改善が追加されました。作成時期が不明なブロックはウィンドウ内と見なされず、転送された IP ヘッダーは設定済みのプロキシからのものだけが信頼されます。)
v0.2.12 では、クライアントが二重に支払う可能性が残っていた経路を解消しました。レジャーに到達できない場合、「未払い」として扱われることはありません。拒否された場合も、他のすべての結果と同じ確認ウィンドウが適用されます。支払い記録を書き込めない、または読み取れない場合は、記録を忘れるのではなく支払いを停止します。また、支払い記録はリクエストの本文とクエリに紐付けられるため、同じ価格の異なる操作が同じ記録を共有することはありません。さらに、レシートチェッカーはノードから応答がない場合に NotFound ではなく Unreachable を返します。また、空の F402_* 設定値は「デフォルトを使う」を意味します(チャージ額が空の場合はチャージしません)。pyfile-toolkit(#10–#14)および enricoaboujaoude-droid(#15–#18)からの報告を受け、それぞれの報告とテストに基づき、修正を独立して作成しました。
v0.2.13 では、pay コマンドが正しい結果を伝えるようになりました。paid フィールドは「ブロックに署名した」ではなく、レジャーの判定(true、false、または "indeterminate")になりました。また、呼び出しが提供され、かつ支払いがレジャー上で確認された場合に限り、pay は終了コード 0 で終了します。それ以外はすべて終了コード 1 で終了し、標準エラー出力にブロックハッシュを表示します。終了コードが 0 以外でも、支払いが発生していないとは限りません。 再度支払う前に、そのブロックを確認してください。有効な 402 に対しては、引き続き quote は終了コード 0 で終了します。vjohannesb(#19)からの報告を受け、報告に基づき修正を独立して作成しました。
設計メモ
- 自己管理: シードは
~/.nano-pay/wallet.json(0600)から外部に出ません。 - ノード不要: パブリック RPC のフェイルオーバー(rpc.nano.to、somenano、
rainstorm.city、nanoslo)を利用します。署名と PoW はすべてローカルで実行されます(nanopy
C 拡張)。まず RPC の
work_generateを試し、失敗した場合はローカル PoW にフォールバックします(約25秒)。CLI は現在のブロックの結果を表示した後、次のブロック用の work を事前にキャッシュするため、 定常状態では支払いが即時に完了します。ライブラリの呼び出し元はオプトインできます。send()、receive_all()、request_with_payment()はprework=を受け取りますが、リクエストの処理経路上に置いてはならず、事前キャッシュには数分かかるため、デフォルトではオフです。 - 安全策: 支払いごとの価格上限(
--max-xno、デフォルトは0.05)があります。quoteコマンドを使うと、支払いを行わずに任意のエンドポイントの価格を確認できます。 残高は常にネットワークから再同期され、ローカルの値を信用することはありません。 - カストディなしのチャージ:
topupは NanSwap の API と直接やり取りしてスワップを見積もり、作成します(1,400以上の入力アセット、最低約$0.02)。このツールが資金を保有したり、送金経路として扱ったりすることはありません。
フォークハザードに関する注意(x402 決済)
x402 の支払いでは、サーバーがブロードキャストするブロックに署名します。サーバーがブロックを受信した後にエラーが発生した場合でも、遅れて決済されることがあります。ウォレットは各操作の前にネットワークからフロンティアを再同期するため、遅れて決済されたブロックも自然に取り込まれます。その間に競合するブロックに署名した場合は、2つのうち一方が無効になるだけです(資金が危険にさらされることはありませんが、1つのウォレットから同時に複数の支払いを実行しないでください)。
ステータス
ベータ版(v0.2.13)。メインネット上で実資金を使って実証済みです。NanoGPT への実際の有料呼び出し(1回あたり$0.0000096、台帳上で確認済み)、加盟店の一連の処理(検証 → 決済 → 確認、ファシリテーターなし)、PoW が必要なフォーセットの請求、および見知らぬエージェントの完全なライフサイクル(新規ウォレット → PoW による請求 → 有料 API 呼び出し → 確認)を3分以内に完了しました。71件のテストでオフラインの支払い処理経路をカバーしています(2件のフォーセットテストにはオプションの mcp エクストラが必要です)。監査は受けていないため、運転資金のみを入れてください。
掲載先
- gold-402 — キュレーションされた x402 ディレクトリ。
/premiumリファレンスエンドポイントは APIs に、この Python クライアントは SDKs に掲載されています。 - Official MCP registry —
com.feeless402/nano-pay。 - agent-tools.cloud — x402、MCP、A2A の掲載情報。
実際の資金を保管する前にお読みください:セキュリティに関する注意事項
- 自己管理:シードは
~/.nano-pay/*.json(0600)にのみ保存されます。 どのツールやログのパスにも出力されません。オフラインでバックアップしてください。 - 運転資金のみ:これはベータ版のウォレットソフトウェアです。貯蓄ではなく、数ドルだけを入れてください。
- 支出上限:
payは--max-xno(デフォルトは 0.05)を超える見積もりを拒否します。 MCPx402_payも同じ上限パラメーターを適用します。 - railHint は参考情報です:リモートサーバーからのヒントは信頼できない入力です。
このクライアントはリモートのブートストラップ文字列を実行せず、独自のチェックを通過した構造化オファーに対してのみ動作します。また、
acceptsは常にバインドを使用し、ヒントは使用しません。 - マーチャントのフォーク防止:サーバーは受け入れたフロンティアをキャッシュし、重複したフロンティアのブロックを拒否します。決済前に、支払者の残高、フロンティア、署名がライブ台帳に照らして検証されます。
- プロキシの背後で実行する場合:マーチャントが
X-Real-IP/X-Forwarded-Forを信頼するのはF402_TRUSTED_PROXIES(デフォルトは127.0.0.1,::1)に指定されたプロキシからのものだけです。それ以外のピアはソケットアドレスで識別されます。 リバースプロキシが別のホストで動作している場合は、そのアドレスを追加し、両方のヘッダーを上書きするように設定してください(proxy_set_header X-Real-IP $remote_addr;)。 - ワーカーは 1 つだけ実行してください:フォーク防止機能(
_seen_previous)とリプレイ制限機能(_replays)は、プロセスごとのインメモリ状態です。uvicorn --workers Nで実行すると、各ワーカーがそれぞれ独自のコピーを保持するため、2 つのワーカーが同じ支払者のフロンティアを受け入れ、そのうち 1 つのブロックがフォーク競合に敗れる可能性があります。これらの保護機能を共有ストレージに移すまでは、単一プロセスでサービスを提供してください(ワーカー数を増やすのではなく、前段にロックを置いて拡張してください)。台帳ポーリングの予算はパス全体で共通の値(verify.CONFIRM_WAIT_S)であり、マーチャントの決済ループと x402 クライアントは同じ時間だけチェーンを確認します。それより早くあきらめたワーカーは、実際には成立した支払いについて「判定不能」と報告します。 - 監査済みではありません。MIT ライセンス — 保証はありません。
謝辞
コードを読み、問題を見つけ、報告するために時間を割いてくれた皆さんのおかげで、Feeless402 はより良いものになりました。ありがとうございます。
- giskard09:応答を受信できなかった後に再試行すると二重払いが発生する可能性があることを非公開で報告し、独立したハーネスで修正を再検証してくださいました(勧告 GHSA-cx37-j5vc-c967、v0.2.9 および v0.2.10)。
- pyfile-toolkit:リンク切れの railHint 仕様へのリンク、XNO/raw の正確な変換、蛇口の請求ごとの金額を修正してくださいました(#5–#7)。また、決済パス全体で台帳待機を統一してくださいました(#9、v0.2.11)。さらに、v0.2.12 で修正された台帳に到達できない問題、レシート検証の問題、設定が空の場合の問題を報告してくださいました(#10–#14)。
- enricoaboujaoude-droid:v0.2.12 で修正された決済ジャーナルとリクエストのバインドに関する問題を報告してくださいました(#15–#18)。
- vjohannesb:拒否された支払いと未確認の支払いについて、
payが決済完了を通知していた問題を報告してくださいました(#19、v0.2.13)。 - dhyabi2:単体で使える決済レシート検証ツール
nano_pay.receiptを提供してくださいました(#4)。 - Circadian-agent:railHint 仕様のフィールドが無効化されたデプロイ先を指していることを見つけてくださいました(#2)。
何か見つけましたか?Issue を作成してください。ユーザーに金銭的な損失を与える可能性がある問題は、GitHub のセキュリティアドバイザリーを通じて非公開で報告してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。