9 月 9 日、決済プロトコル x402 のリポジトリに Cardano の実装が取り込まれました。仕様書は今年 4 月から置かれていましたが、動くコードが本体に入ったのは今回が初めてです。
SIPO はこれまで、標準化の議論に名前が載ることと、その標準の上で実際に動くものが出てくることを分けて見てきました。今回はその二つ目の段階にあたります。何が入ったのか、そして Cardano の台帳の性質が決済の設計にどう翻訳されたのかを見ていきます。
■ 402 という空き番号に、機械の支払いを載せる
HTTP には 402 Payment Required という応答コードがあります。仕様の上では古くから予約されていながら、長らく使い道が定まらないままだった番号です。x402 はこれを使い、サーバーが「この先を見るには支払いが要ります」と機械可読な形で返し、クライアントが支払ってから同じ要求を出し直す、という流れを作ります。
この形が注目されているのは、人間がカード情報を入力する前提を外せるからです。AI エージェントが別のサービスを呼び出すたびに少額を払う、といった用途では、承認画面を挟む決済は成立しません。プロトコル本体は現在 x402 Foundation のリポジトリで管理され、複数のチェーンが実装を寄せる場になっています。
Cardano 側の動きは二段構えでした。4 月 23 日に exact スキームの Cardano 仕様書がリポジトリに入り、実装を加えるプルリクエストは 6 月 1 日に開かれます。それが 9 月 9 日に取り込まれました。変更は 99 ファイル、追加は 18,000 行を超えます。提出者は Cardano Foundation の Fabian Bormann 氏です。
■ 署名する側と、送信する側を分ける
入ったのは @x402/cardano というパッケージで、三つの役割が実装されています。
- クライアント:支払う側です。取引を組み立てて署名しますが、ネットワークへは送信しません。
- ファシリテーター:受け取った署名済み取引を検証し、送信し、決済が成立した証拠を返します。
- サーバー:価格の表記を解釈し、支払い要件を組み立てて 402 応答を返します。
署名と送信を分けたことには実務上の意味があります。ファシリテーターは他人が署名した取引を中継するだけなので、手数料も払わなければ資金を持つ必要もありません。運用者が預かる鍵を減らせる構えです。
クライアント側は署名の方法を固定していません。ブラウザのウォレットが CIP-30 経由でこの役割を担うこともできます。サーバーで鍵を扱う場合の参照実装も同梱され、取引の復号には Intersect の Evolution SDK が使われています。WASM を含まない TypeScript 実装なので、導入時に追加のビルド環境を要求しません。
対応ネットワークはメインネットと preprod、preview の三つで、既定の資産としてメインネットと preprod の USDM が登録されています。ADA そのものは米ドルに固定された資産ではないため、金額の上限を扱う既定の仕組みでは対象外になり、使うには明示的な設定が要ります。地味ですが、価格表記と実際の資産を取り違えないための設計です。
■ 「まだ確定していません」を、返せるようにする
今回の実装で最も Cardano らしい部分は、決済の完了をどう定義したかにあります。
Cardano の合意形成は確率的です。ブロックに入った取引でも、その後の巻き戻しが理論上はあり得ます。x402 のような同期的なやり取りに、この性質をそのまま持ち込むと「支払われたのか、まだなのか」が曖昧になります。
実装はここを設定値として外に出しました。要求側は、どこまでの証拠を求めるかを選べます。ファシリテーターが送信を受け付けた時点でよいのか、正規のブロックに入るまで待つのか、その先さらに何ブロック積まれるまで待つのか。ブロック数で指定する場合は 1 から 20 まで選べ、既定は 1 ブロックです。
そして基準に届かないうちは、失敗ではなく「保留」を返します。取引 ID と現在の確認数を添えた応答が返り、要求元は同じ内容で問い合わせ直せます。そのとき二重に送信されることはありません。取引 ID を鍵にした重複防止が入っていて、一つの取引は一度しか送信されない設計になっています。待ち時間の上限は既定で 75 秒です。
検証も、送信の前に済ませられるものは前倒しされています。入力が既に使われていないか、有効期間は範囲内か、出力の最小額を満たしているか、入力と出力に手数料を足した額が釣り合っているか、手数料がプロトコルの下限を超えているか。台帳が受け付けないと分かる取引を、コンテンツを渡す前に落とすためです。
なお、メモリプールに入っただけの状態でコンテンツを渡すことは、仕様として強く非推奨とされています。実装もこれに従い、運用者が明示的に許可しない限り拒否します。
■ できないことも書いてある
README には、この実装でできないことが正面から書かれています。
支払いの方式は三つ用意されていて、そのうち一つは AI エージェント同士の支払いを想定した Masumi のエスクロー契約に資金を預ける形です。契約そのものは Masumi が実際に運用しているものをそのまま使い、アドレスも一致します。しかし売り手の署名が対象とするデータの作り方が Masumi 側と異なるため、この実装が作ったロックを Masumi の既存サービスから動かすことはできません。結果の提出も返金も紛争処理も、x402 側の道具で行う必要があります。
README はこの分岐を「意図的なもの」と説明しています。x402 側の署名は、発行された 402 応答ひとつと支払いを結びつけるために設計されており、そこを Masumi の形式に合わせると、その結びつきが壊れるからです。
互換性の限界を、採用を勧める文書の中に自分で書いておく。実装の成熟度を測るとき、こういう記述があるかどうかは、機能の一覧よりも参考になります。
■ これから見るもの
- ファシリテーターを実際に立てる事業者が出てくるかどうか。プロトコルが動くかどうかと、誰かが運用を引き受けるかどうかは別の問題です
- ブラウザウォレットが支払う側の役割に対応するかどうか。CIP-30 経由で担える設計にはなっていますが、対応は各ウォレットの判断です
- メインネットでの利用例。ネットワーク識別子も既定資産も登録されていますが、実際に資金が動く事例が出てくるかはこれからです
仕様書に名前が載った段階と、他のチェーンと同じリポジトリで同じ手順書に沿って動く段階とでは、開発者から見た距離がまるで違います。今回はその距離が一段縮まった、という出来事です。
一次ソース / 関連リンク
- feat: add Cardano implementation for Typescript package(取り込まれた変更そのもの)
https://github.com/x402-foundation/x402/pull/2537 - @x402/cardano パッケージ(README に設計と制約の記述)
https://github.com/x402-foundation/x402/tree/main/typescript/packages/mechanisms/cardano - Cardano 版 exact スキームの仕様書
https://github.com/x402-foundation/x402/blob/main/specs/schemes/exact/scheme_exact_cardano.md - Cardano 公式アカウントによる告知
https://x.com/Cardano/status/2097644698269585546
