qmax について
qmaxは、Qubicのトレーダーやアプリ向けのDEXルーティングサービスです。QXの注文板とQSwapのプールを比較し、コストを加味して必要に応じて注文を分割します。
主な機能
- 01QXとQSwapの最良価格見積もり
- 02ルーティングと注文の分割
- 03手数料・価格影響・板の深さの計算
- 04アセット一覧と市場の稼働状況
- 05HTTP APIとSDK
活用シーン
- 01Qubic取引の前に取引先を比較
- 02一括見積もりで注文サイズを選択
- 03他のDEXサイトで市場価格を表示
MCP 対応
エージェント向けのMCPサーバーを含みます。MCPクライアントにQMaxの市場見積もりと取引プラン作成機能を提供します。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://qmax.exchange/api/mcpclaude mcp add --transport http profitphil-qmax https://qmax.exchange/api/mcp{"mcpServers":{"profitphil-qmax":{"type":"http","url":"https://qmax.exchange/api/mcp"}}}Cursor で開く{"servers":{"profitphil-qmax":{"type":"http","url":"https://qmax.exchange/api/mcp"}}}VS Code で開く{"mcpServers":{"profitphil-qmax":{"type":"http","url":"https://qmax.exchange/api/mcp"}}}{"mcpServers":{"profitphil-qmax":{"serverUrl":"https://qmax.exchange/api/mcp"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
ツール
詳細
QMax
このリポジトリについて。 これは QMax の公開部分です。ルーター、HTTP API、ウェブサイト、SDK、MCP サーバー、x402 ヘルパーが含まれます。QMax 自体のデプロイに関する一部は含まれていません。Max プランナー、Max パスのロジック、Discord ボット(QU 価格フィードを除く)、サーバーのデプロイファイル、すべてのシークレットが該当します。ここにあるコードが非公開部分に依存する箇所には、型を維持し、その旨を示す小さな代替ファイルを用意しているため、残りの部分はビルドして実行できます。すべての権利は留保されています。ライセンスは付与されていません。
QMax は、Qubic で支払った金額に対して最大限の成果を得るための最適なルートを見つけます。buy 5000 ASSET を指定すると、QX のオーダーブックと QSwap プールで注文価格を計算し(手数料、価格への影響、送金コストを含む)、より安い取引先を選ぶか、両方に分割します。
npm i
npm run qmax -- buy 100000 [--snapshot file.json] [--no-split]
npm test
費用がかかるもの、かからないもの
Qubic の他のサイトが無料であることを踏まえ、普及を促すため、ほぼすべてが無料です。ウェブサイト(パス不要、取引ごとの手数料なし)、HTTP API(キー不要、課金なし)、SDK、MCP サーバー、エージェントは無料です。販売される唯一のものはエージェント向けの Max 見積もり(GET /v1/max、API_MAX_PRICE_QU、ライブサーバーではプランあたり 100 QU)です。エージェントはプリペイドキーの残高から支払うか、x402 セッションを保持します。一方、ウェブサイト自体の Max と QMax 自身のキーは支払いません(以下を参照)。Discord ボットのサブスクリプションはコード内にありますが、無効になっています。「無料」は「無制限」という意味ではありません。QMax 自身のキーを持たない呼び出し元は、マーケットエンドポイントで IP ごとのレート制限が適用されます(API_FREE_PER_MIN、デフォルトは 1 分あたり 60 回)。これにより、呼び出し元が Qubic ノードに過剰な負荷をかけることを防ぎます。QMax 自身のキー(Discord ボット)には制限がありません。そのため、収入源はエージェントが購入する Max 見積もり(および支援のチップ)と、再び有効にされた場合の Discord サブスクリプションです。これらは、サブスクライバーの利益分配の原資にもなります(以下を参照)。
API_ACCESS=free(デフォルト):全員がキーなしで利用できます。billing:従来の呼び出しごとのプリペイド料金と x402 セッションです。設定は残されていますが、無効です。private:API_KEYを持つユーザーのみ利用できます。API_MAX_PRICE_QU(デフォルトは 0:Max 見積もりは無料。ライブサーバーでは 100):API_ACCESS=freeの状態で、エージェント向けに Max プランを販売します。この場合、課金対象となるのはGET /v1/maxのみです。キーとチャージは利用できます(POST /v1/keys、GET /v1/topup、POST /v1/topup/claim、GET /v1/account)が、それ以外は課金されません。支払い方法:プリペイドキー(x-api-key)を持つエージェントには、プラン作成後に料金が請求されます。そのため、プランを作成できないリクエストには費用がかかりません(また、その間に残高が使われた場合は、プランではなく 402 が返されます)。x402 セッション(GET /v1/x402、API_SESSION_SECONDSの間有効なAPI_SESSION_PRICE_QU)を持つエージェントは、プランごとの支払いは不要です。それ以外のユーザーには、料金と 2 つの支払い方法を示す402が返されます。**課金されないもの:**QMax 自身のキー(API_KEY、ADMIN_KEY)と、ウェブサイト自体のページから行われるリクエスト(ブラウザーはSec-Fetch-Site: same-originを付与し、ページのスクリプトから変更できないため、他のサイトのページには課金されます)。これは簡易的なチェックであり、ロックではありません。ブラウザー外のプログラムから同じヘッダーを送信すれば料金を回避できるため、価格は低く設定されています。プランごとの支払いは意図的に提供していません。QPayhub は支払いごとに最低 100 QU を受け取り、支払いには約 10 秒かかるため、呼び出しごとに 100 QU を支払うと、手数料ですべての価値が失われます。10,000 QU をチャージすると、約 1% の手数料で 100 プランを購入できます。- ウェブサイトのパスは無効になっています。サイトを再びパス制にするには
VITE_REQUIRE_PASS=onを指定してビルドします(価格は src/config.ts のPAYWALLで設定します)。 - 以下のパス、プリペイド API キー、x402 セッションに関するセクションでは、これらのオプションモードについて説明します。
手数料モデル(qubic/core の Qx.h と Qswap.h に基づく。信頼する前に確認してください)
- QX: 取引手数料は0.3%(
tradeFeeは3,000,000 / 1e9)で、マッチごとに切り上げられます(floor(v*rate)+1)。コントラクトでは売り手のQU受取額から差し引かれるため、買い手に手数料はかかりません(ドキュメントには「QUBICを保有する側」とあります。要確認)。注文に一律手数料はかかりません(2026-10-08にオンチェーンで確認:買い注文は価格×数量のみを正確に添付し、それを超える金額で約定することはありません。例:1,303 QMINEを3,989で注文すると、5,197,667 QUが送金され、費用も正確にその額でした。売り注文は何も添付しません)。100 QUのアセット送金手数料がかかるのは、管理権をQXとQSwapの間で移す場合のみで、これは独立した手順です。 - QSwap: スワップ手数料は0.3%(
swapFeeRateは30 / 10,000)です。買い注文ではQuoteExactAssetOutputを使い(QUの入力額に手数料がかかり、切り上げられます)、売り注文ではQuoteExactAssetInputを使います(QUの出力額から手数料が差し引かれます)。プロトコル、株主、QXへの配分はこの0.3%から支払われ、追加料金ではありません。1回の操作につき一律100,000 QUの手数料に加えてアセット送金手数料がかかるものとして、QSwapの固定費をモデル化しています。 - 手数料、端数処理、固定費は
QxConfig/QswapConfigにあり、ルーターに手を加えなくても変更できます。
HTTP API
他のDEXサイトはHTTP経由でQMaxを呼び出せます(ウォレットやSDKは不要です)。npm run api(環境変数:PORT、SNAPSHOT、任意でAPI_KEY)。
GET /v1/quote?side=buy&asset=DEMO&qty=100000[&split=false]
POST /v1/quote {"side":"sell","asset":"DEMO","qty":500}
GET /v1/quotes?side=sell&asset=DEMO&qtys=1000,10000,50000 (several sizes at once; free access only)
GET /v1/assets[?category=contract|token&q=CF] GET /v1/assets/search?name=CFB
GET /v1/openapi.json GET /health
見積もりレスポンスには、route(取引所、数量、実効価格、価格インパクト、手数料、使用したQXの板の厚み)、totalQu、fillable、単一取引所のalternatives、warnings、および平易な言葉で書かれたsummary(src/quotesummary.ts)が含まれます。summaryは合計額、平均価格、注文の執行先、分割執行の価値を示すため、計算ではなく読み取りを行うアシスタントに適しています。GET /v1/quotes(src/quotesroute.ts)では、マーケットを一度読み込んで同じ注文の最大10通りのサイズを価格計算し、各サイズが最小サイズよりどの程度不利か(averageVsSmallestPct)を返すため、ボットは1回の呼び出しで分割サイズを選べます。ただし、利用できるのはAPI_ACCESS=freeの場合のみです。プリペイド方式のデプロイでは分割注文ごとに課金されるため、まとめて見積もりを取得するとそれを回避できてしまいます。アドレスごとに制限されるすべての呼び出しには、X-RateLimit-Limit、X-RateLimit-Remaining、X-RateLimit-Reset(秒)が付与されるため、呼び出し元は429とRetry-Afterで拒否される前に呼び出し頻度を下げられます。また、すべてのエラーには、説明文に加えて一貫したcode(bad_request、unauthorized、payment_required、not_found、rate_limited、…)が含まれます。CORSは許可されているため、ブラウザーから直接呼び出せます。API_KEYを設定すると、x-api-keyヘッダーが必要になります。
アセット一覧
GET /v1/assetsは、取引可能なアセット(QXの板またはQSwapのプール)を流動性の高い順にすべて返します。各アセットにはid、symbol、issuer、category(contract=スマートコントラクトの株式、token=それ以外すべて)、venues、priceQu、liquidityQuが含まれます。最初のネットワークスキャンが完了するまではreadyがfalseで、結果は.cache/catalog.jsonにキャッシュされるため、再起動後すぐに利用できます。
src/catalog.tsは、すべてのコントラクト株式(ゼロIDが発行)、assets.jsonに記載されたトークン、およびネットワークの発行一覧(RPCによって150件までに制限されています)からリストを作成します。リストにないトークンは、GET /v1/assets/search?name=ABCで追加できます。ネットワーク上で名前を検索し、取引可能か確認して、リストに保持します。発行者が異なるトークンに同じ名前が付いている場合、トークンのIDはGARTH.PHOENのようになりますが、コントラクト株式には通常のシンボルが維持されます。スキャンは3リクエスト/秒に制限され、専用のクライアントを使うため、見積もりが遅くなることはありません。
アクティビティフィルター
GET /v1/assets の各アセットには、activity(active、inactive、unknown)と lastActiveAt が含まれます。inactive は、2エポック(14日間)以内に QX の注文もプールの変更もなかったことを意味します。src/activity.ts は、アーカイブの Query API(/query/v1/getTransactionsForIdentity、注文タイプ 5 と 6、100,000 tick 単位のウィンドウで取得し、10,000 件の結果上限に達したウィンドウは分割します)から QX の注文履歴を読み込みます。最初のスキャンでは数分で14日分を取得し、その後は新しい tick のみ読み込みます。進捗は .cache/activity.json に保存されます。最初のスキャン中は、レスポンスに activity: { ready, progress } も含まれます。
制限事項:これは QX で発注された注文(マーケットメーカーの注文を含む)を数えるもので、約定した取引ではありません。QSwap には低コストで取得できる履歴がないため、QMax が監視を開始してからリザーブの変化を確認したプールは、アクティブとしてカウントされます。プールが静穏と判定されるのは24時間監視した後だけで、それまでは unknown となり、非表示にはなりません。
ライブデータ
npm run api は Qubic のライブデータを提供します(別のシードファイルを使うには ASSETS=file を設定します。これはトークン名、または { symbol, issuer } オブジェクトの JSON リストです。RPC を変更するには QUBIC_RPC_URL を設定します。デフォルトは https://rpc.qubic.org です)。そのファイルがない場合、または SNAPSHOT=file が設定されている場合は、デモスナップショットを提供し、起動時にその旨を表示します。
src/live.ts は、各アセットについて /live/v1/querySmartContract を通じて次のデータを読み込みます。
- QX(コントラクト 1):
Fees(取引手数料、送金手数料)とAssetAskOrders/AssetBidOrdersを取得します。1回につき256件、offsetを使って片側あたり最大2,048件までページングします(上限に達するとQX book has N+ ordersの警告が表示されます)。 - QSwap(コントラクト 13):
Fees(スワップ手数料、送金手数料)と、リザーブを取得するGetPoolBasicStateを使用します。スワップごとの一律 100,000 QU の手数料は、コントラクトのQSWAP_ADDITIONAL_FEEです。 - 状態はアセットごとに5秒間キャッシュされ、読み込みに失敗した場合は再試行され、キャッシュされません。
- 各 QSwap の割り当ては、コントラクト独自の
QuoteExactAssetOutput/QuoteExactAssetInputと照合され、onChainCheckとして報告されます(differenceQuは 0 になるはずです)。
トークンを常に含めるには、その名前を assets.json に追加します。src/data.ts で MarketData を実装すれば、スナップショットベースまたはカスタムのソースを使用できます。
Web アプリとウォレット
web/ は Vite + React アプリです(npm run dev)。web/wallet/ のウォレットコードは、double-k-3033/QRaffle-frontend の接続モジュールを移植したもので、同じ4つのログイン方法(MetaMask Snap、WalletConnect(既存の WalletConnect プロジェクト ID を含む)、プライベートシード、.qubic-vault ファイル)に加え、5つ目として Qubic Wallet ブラウザー拡張機能(qubic/wallet-extension、ベータ版。ページに window.qubic を設定します。web/wallet/extension.ts)を利用できます。QubicConnectContext.getSignedTx は、接続中の方法でトランザクションに署名します。拡張機能はその中でアクティブなアカウントを使って署名するため、返される署名済みバイト列は、ブロードキャスト前に要求内容(アカウント、送信先、金額、tick、呼び出し、データ)と厳密に照合されます(src/signedtx.ts)。また、拡張機能内でのアカウント切り替えや切断は、ページにも反映されます。WalletConnect セッションと拡張機能の接続は、ページを再読み込みしても復元されます(シードやボルトはメモリ内にしか保持されないため、これらはダイアログから開始します)。スマートフォンではウォレットアプリを開くとブラウザーがスリープ状態になり、ページが破棄される場合があります。そのため、ページを離れている間に届いた WalletConnect の承認は、戻ってきたときに処理されます(ページはペアリングを開始したことを記憶します)。タブに戻るとダイアログはすぐに再確認し、スマートフォンではボタンから QMax 独自のハンドオフページ(Discord ボットが使う /open)に進みます。
Qraffle モジュールからの変更点:接続モーダルは通常の React/CSS で実装されています(Tailwind や UI キットは使用しません)。jotai の残高ストアは削除され、ボルトでログインすると選択したアカウントのシードが表示され、署名に使用できるようになります。また、localStorage に保存されるウォレットに秘密鍵は含まれません(元の実装では平文で保存されていました)。
アプリは API 経由で見積もりを取得し(開発時の /api は npm run api にプロキシされます。それ以外の場合は VITE_API_URL を設定してください)、API が提供するアセットを一覧表示します。npm run api と npm run dev で両方を起動します。スマートフォンで試す場合(同じ Wi-Fi に接続):npm run start:lan を実行すると、API とウェブサイトが起動し、アクセス先のアドレスが表示されます。例:http://10.0.0.4:5173。ネットワーク上で共有されるのはウェブサイトのみです(同じ開発サーバーを使用しますが、.env や .cache は読み取れません)。API は 127.0.0.1 上にとどまり、ウェブサイトのサーバーが /api を API に転送します。ページは通常の http で配信されるため、スマートフォンのブラウザーでは安全でないコンテキストとして扱われます。閲覧、チャート、取引ダイアログは動作しますが、HTTPS を必要とするウォレット接続は動作しない場合があります。macOS のファイアウォールで node の通信を許可する必要があります。また、デバイス間の通信を分離するゲストネットワークは使用できません。
見た目と操作感。 このインターフェースはランディングページではなく、トレーディングターミナルです。細い境界線のあるフラットなチャコール色のパネル、すべての数値に等幅数字を使った小さなシステムフォント、青のアクセントカラー、アクティブなタブのオレンジ色のマーク、そして買いと売りにのみ使う緑と赤で構成されています。ロゴには提供されたアートワーク(brand/qmax-logo-source.jpg)を使用します。「QMa」の文字と、「x」の代わりに置かれた2本の矢印の X です。文字部分はテキストカラーの上にCSSマスクとして使われる画像なのでテーマに合わせて色が変わり、Xはベクターです。ロゴ全体を表示する余地がない場所(スマートフォンのタイトルバー、ファビコン、ホーム画面アイコン)では、Xだけを表示します。npm run brand(scripts/make-brand.mjs、macOS)を実行すると、アートワークからweb/public/brand、favicon.svg、favicon-32.png、apple-touch-icon.pngを再生成します。デザインシステムはweb/style.cssに集約されています(先頭に色、角丸、フォントのトークンがあり、太陽/月ボタンで切り替えるダークテーマとライトテーマを備えています。選択されるまではシステム設定に従い、選択後はこのブラウザーに記憶されます)。ワークスペースのレイアウトと高密度表示の上書き設定は、最後に読み込まれるweb/styles/zz-terminal.cssにあります。幅1000px以上ではページはワークスペースになります(幅1000~1260pxではワークスペース全体を縮小表示します。web/media.tsのuseWorkspaceScaleが、通常のブラウザーウィンドウでもスマートフォン向けではなく同じ3パネルレイアウトを表示します。チャートは逆方向に拡大縮小されるため、ポインターとクロスヘアの位置は正確に保たれます)。Trade、Orders、History、Pools、Swapの画面を備えたタイトルバー、市場バー(資産数と最新の取引)、左側のウォッチリスト(Mine、Favorites、All、Contracts、Tokens。列見出しをクリックすると並べ替えられます。Vol:の横で24h、72h、7dを選ぶと、出来高と価格変動の列の両方に同じ期間が適用されます)、そしてthinkorswimのようなトレーディングプラットフォームの配置で、幅と高さの大部分を占める中央のチャートとそのツールを備えています。左側に資産、中央に大きなチャート、右上に最新の取引、その下の右側に注文パネル(売買方向、数量、見積もり、準備状況、BuyまたはSellボタン)があります。最初に目に入るのはチャートです。資産を選ぶまでは、中央にQubic独自の価格チャート(web/QubicDesk.tsx。MEXCとGate.ioのローソク足データを使い、どの資産でも同じチャートとツールを表示します)が表示され、その横に全資産の最新取引、さらにその下には、資産の注文パネルが表示される場所にSwapパネル(Swapセクションのフォーム。QSwapでQUをトークンに、またはトークンをQUに交換し、あるいはMaxを有効にしてトークン同士を交換します。SwapPanelのcompactモード)が表示されます。上部のシンボルには矢印と検索機能があり、何も閉じずに別の資産へ移動できます([と]で出来高順の前後の資産に移動し、/で取引ダイアログの検索を開きます)。「Hide order panel」ストリップを使うと注文パネルを隠せます(このブラウザーに記憶されます。取引表示は残ります)。「Wide chart」を使うと右側全体が隠れ、チャートがさらに広くなります。ウォッチリスト、チャート、右側パネルの間にある仕切りはドラッグして幅を変更できます(ダブルクリックすると元に戻り、フォーカスして矢印キーを使っても調整できます。web/Resizer.tsxとweb/layout.tsでは、それぞれの幅がこのブラウザーに保存され、設定範囲内に保たれ、チャートが指定の最小幅を下回らないようになっています)。チャート専用のボタン(表示範囲に合わせる、最新表示、設定、画像、全画面表示)は、チャートの右上に重ねて表示されます。取引リストにはこの資産の取引と、すべての資産の取引を表示するタブがあります(列は時刻、売買方向、数量、価格、QU、市場です。1時間未満の時刻は4 minのように表示し、「ago」は付きません)。幅1000px未満(タブレットやスマートフォン)では、同じ3つの列が1行に並ぶ3つの画面となり、横にスワイプできます。その先にはポートフォリオ画面があります(web/Pager.tsx。1行のスクロールスナップで、ワークスペースと同じコンポーネントを使ったレイアウトです)。左側はAssets(市場:Favorites、All assets、Contracts、Tokens。検索、並べ替え、フィルターあり)、中央はChart(最初に開く画面です。資産を選ぶまではQubicのチャートが表示され、表示中の2つの右側画面のどちらにも、シンボルバーと数値が上部に固定されます)、右側はTrades & order(最新の取引とその下の注文パネル、またはQubic用のSwapパネル)、最後がPortfolio(資産の価値と損益を表示するMy assets、Orders、History、Pools、Swap。ワークスペースのPortfolio、Orders、History、Pools、Swapページと同じタブです)です。画面下部のストリップには画面名が表示され、タップすると別の画面に移動します。リストから資産を選ぶとそのチャートに移動し、数量を開くリンクを選ぶと注文パネルが開きます。チャートを横方向にタッチドラッグすると、チャートをパンする代わりに次の画面に移動します(マウスではチャートをパンし、ピンチでズームし、チャート上部のボタンで移動できます)。上下にドラッグすると画面がスクロールします。リストの上にはまずタブバーがあり(スマートフォンでは2段になり、上段に自分の項目、下段に市場が並ぶため、横スクロールが発生しません)、その後に検索、並べ替え、フィルターがひとまとまりで続きます。並べ替えとフィルターは同じセグメントコントロールです。スマートフォンでは並べ替えメニューに24h、72h、7dの選択肢もあり、出来高と価格変動の期間を設定できます(幅の広い画面ではVol列の見出しにあります)。フィルターは一度に1つを選択します(Both markets:QXとQSwapの両方で取引される資産、Active:過去2エポック以内に取引された資産、Arbitrage:Maxの一部です)。選択中のフィルターをもう一度選ぶと、リスト全体が再表示されます。スマートフォンでは、各資産が列見出し(Asset、Price、24h change、Vol。見出しをタップすると並べ替えます)の下にコンパクトな行で表示されます。星、ロゴ、資産名とその下に取引市場(QX、QSwap、または両方)、価格、変動率、出来高が並びます。評価、資産の種類、「cheaper on」のヒントは、チャートのヘッダーに表示されます。行全体を選ぶと資産が開くため、ここにはBuyとSellのボタンもスプレッド表示もありません。タイトルバーの下にある最新取引のストリップは、右から左へゆっくり流れ、新しい取引は右端に加わります。ポインターを置くか一時停止ボタンを使うと停止し、システムで動きを減らす設定が有効な場合は、通常の行として手動でスクロールします。すべての画面で共通の要素はweb/ui.tsx(アイコン、QMaxのマーク、Escで閉じてフォーカスを内部に保つアクセシブルなModal、アバター、ステップマーカー)と、ページフレーム(タイトルバー、残高付きウォレットメニュー、市場バー、ステータスバー)であるweb/chrome.tsxにあります。/を押すと検索にフォーカスします。ウェブフォントは読み込まず、資産ロゴはQMax独自のアドレスから配信されるコピーです(web/public/logos。npm run logosでqubictrade.comから保存されます。独自のロゴがない資産には文字入りのバッジが表示されます。読み込み後に、白または透明の四隅を持つ無地の正方形に丸いロゴが表示される場合は、そのロゴの縁の色でバッジを塗り、画像を円形に切り抜いて白い四隅が見えないようにします。src/logofill.ts、web/logofill.ts)。そのため、ページの描画にサードパーティーから何も取得しません。
指値注文。 各注文チケットには、成行/指値の切り替えがあります。指値注文とは、指定した価格での QX の買い注文または売り注文です。その価格またはそれより有利な価格で板にすでに並んでいる注文はすぐに約定し、残りは約定するか、「注文」からキャンセルするまで板に残ります。QSwap は注文板のないプールなので、指値注文は QX のみで利用できます。注文は、資産リストにある自分の価格、数量、資産、発行者を使ってブラウザーで作成され(src/limit.ts)、署名前にそれらと完全に照合されます(QX への買い注文または売り注文が 1 件、正しい資産、価格、数量、買い注文には価格と数量の積を添付し、それ以外は何もないこと)。その後、ウォレットと注文板を再度読み込み、約定した数量と待機中の数量を結果に表示します。
保有資産:評価額、取得額、損益。 「保有資産」タブ(およびワークスペースの「ポートフォリオ」ページ)では、各保有資産を今売却した場合に実際に得られる金額を表示します。POST /v1/liquidation は、実際の売却で使われるルーターを通して保有資産全体を処理するため、QX の注文板とプールの流動性、すべての手数料が反映されます(市場が保有資産をすべて受け入れられない場合はその旨が表示され、受け入れ可能な分だけが計算されます)。その横には、ウォレットの過去 365 日分の取引台帳(src/portfolio.ts)に基づく平均取得額と、この売却価値に対する損益、最初に購入した時期が表示されます。それ以前に購入した数量や、別のウォレットから受け取った数量には評価額はありますが、損益はありません。合計はドル建てでも表示されます。サーバーの負荷と、それを小さく抑える仕組み: 売却価格の算出では、各資産のライブ注文板とプールを読み込みます(保有資産が 25 件の場合、約 10~15 秒かかります。公開ノードがリクエストを制限している間は、さらに時間がかかります)。同じ資産の同じ売却は一度だけ価格を算出し、2 分間、問い合わせたすべてのユーザー間で共有します(LIQUIDATION_CACHE_SECONDS)(多くのウォレットは同じ少数の株式を保有しています)。同時に価格を算出するポートフォリオは最大 3 件で、アドレスごとの制限もあります。ページには最後に算出した価格がブラウザーに保存され、「保有資産」を再度開くとすぐに表示されます。価格が 15 分以上前のものになったとき、または「更新」を押したときにのみ再計算されます(数値の下の行に経過時間が表示されます)。購入履歴の読み込みが高負荷の処理です(リクエスト頻度に制限のある公開アーカイブを読み込みます)。そのため、ウォレットの台帳は一度作成すると 5 分間、すべてのユーザー間で再利用されます(LEDGER_CACHE_SECONDS)。同時に作成できる台帳は 2 件のみです(それ以外のリクエストには数秒後に再度問い合わせるよう通知し、自動で再試行します)。ウォレットの履歴はブラウザーに 15 分間保存され、アーカイブからリクエスト頻度を制限しているという応答があった場合は、30 秒間、新しい台帳の作成を開始しません。
接続せずにウォレットを見る。 初めて見つけたサイトにウォレットを接続したくない人もいますが、ポートフォリオに表示される情報はすべて Qubic ネットワーク上で公開されています。そのため、どのポートフォリオ画面(「保有資産」、「注文」、「履歴」、「プール」)にも、アドレスを貼り付けるボックスがあります(web/ViewWallet.tsx、web/viewwallet.ts)。貼り付けた内容(大文字小文字を問わず 60 文字のアドレス、またはエクスプローラーのページへのリンク)からアドレスを取得し、末尾 4 文字とチェックサムを検証するため、タイプミスがあれば空のウォレットを表示するのではなく、理由を示すメッセージが表示されます。ポートフォリオには、そのウォレットの保有資産(今売却した場合の評価額、取得額、損益)、未約定注文、取引履歴、プールのポジションが表示されます。誰のウォレットを表示しているかと、読み取り専用であることを示す行もあり、「変更」と「表示を停止」も選べます。この方法で表示しているウォレットについて、署名が必要な操作はできません。「購入」、「売却」、「スワップ」ボタンは「開く」に変わり、注文はキャンセルできず、プールのポジションには「追加」や「削除」が表示されません。「スワップ」には自分のウォレットが必要であることが示されます。アドレスは、表示を停止するまでこのブラウザーに記憶され(qmax.view)、自分のウォレットを接続すると表示が終了します。接続済みウォレットの場合と同様に、公開ノードと QMax の台帳 API から直接データを読み込みます。
Max と QMax Pro。 通常の購入と売却は通常の注文で、どれもすでに最良のルートを通ります(ルーターは各市場単独の場合と分割する場合の価格を計算し、最も安いものを選びます)。Max は、取引に最適な ポジション(実行方法、数量、2つの市場間の裁定取引、保有資産の最適な決済方法)を探す機能です。これは設定にある Max mode という1つの切り替えで、GET /v1/max が提供します。Max プランナーはこのリポジトリには含まれていません。src/maxplan.ts には型(API のドキュメントに記載されたプランの形式)と、その旨を示すスタンドインが含まれています。また、その背後にあるパスロジック(src/pro.ts、src/proapi.ts、src/procover.ts)も、Max を無料にするスタンドインです。QMax のサーバーでは、実際の実装が稼働しています。
ウェルカムウィンドウ(web/WelcomeModal.tsx)は、サイトの読み込み時に開きます。QMax の機能(誰でも無料で使え、キーは自分で管理すること)を簡潔に説明し、Support QMax ボタン(サポート用メールアドレス、QMax の X が入った QR コード、Copy ボタン)と「次回から表示しない」チェックボックス(このブラウザーに保存されます)を表示します。
リアルタイム価格。 ページが表示されている間は20秒ごとにリストを再取得し、ページが再び表示されたときにもすぐに再取得します。開いている資産のヘッダーも同様です。価格は QX から取得します。 すべての資産は QX で取引されます(QSwap プールは追加の市場であり、唯一の市場になることはありません)。そのため、常に QX 価格があります。直近の QX 取引(7日以内)がある場合は、その資産の最新の取引価格です。QSwap プールの価格は準備金の比率にすぎず、誰も取引しなければ変わりません(QMINE の価格は、QX で 3,994 で取引されている間、数日間 4,157 のままでした)。また、流動性の低い QX 板の中間価格が、どの取引価格からも大きく離れている場合があります(QSILVER の中間価格は365万でしたが、最後の取引価格は100,001でした)。古い取引価格は市場の現状を反映しなくなることがあるため(QEARN の146日前の価格は、今日の最良売り気配を上回っていました)、現在の QX の買い気配と売り気配の範囲内に収めます。QX での取引がない資産には、QX の買い気配と売り気配の中間価格を使用します。GET /v1/assets はその価格を priceQu に設定し、lastPriceQu(未加工の取引価格)、lastTradeAt、bookPriceQu(注文板またはプールの価格)、probedAt(公開ノードへの負荷を抑えるため、板を最後に読み込んだ時刻。10分ごと)も返します。サーバーでは15秒ごとに取引一覧を読み込み、ウェブサイトのリストは20秒ごとに読み込みます(src/api.ts の priceFromQx、src/liveprice.ts)。取引一覧とティッカーは数秒ごとに更新され、Qubic のドル価格は毎分更新されます。
All と Max。 保有するトークンのすべて、またはプールに投入できる QU のすべてを入力するボタンには、All と表示します。Max は、最適なポジションを探す QMax の機能と、ある資産を別の資産に交換する機能にのみ使用します。
検索以外で Max モードが利用可能にする機能。 Max をオフにしても、通常の取引画面は変わりません。以下は Max の機能です(無料で使える機能の一覧は src/chartaccess.ts に記載されています)。最近の取引リストに表示される、各取引が行われた市場(Max がオフの場合は「—」が表示されます)、どちらの市場の価格が安いかを示す通知(リストの各行、および取引パネルの QX と QSwap の比較。Max がオフの場合、行には価格がさらに安い市場があることだけが表示されます)、アービトラージ関連の表示(行の ARB タグ、アービトラージフィルターとその件数、市場バーのアービトラージ数値、取引パネルのリアルタイムアービトラージチェック。Max がオフの場合、タグ、フィルター、数値は Max を有効にするための控えめな案内として表示され、フィルターは適用されず、リアルタイムチェックも行われません。Max がオンの場合は、設定のアービトラージ上限が適用されます。API の /v1/arbitrage はこれまでどおりです)、そしてチャートの大部分です。無料で使えるチャート機能は、ローソク足と折れ線、すべての期間、すべてのローソク足幅(自動、1 分、5 分、15 分、30 分、1 時間、4 時間、1 日)、出来高、20 本のローソク足の平均、線形軸、市場の選択、トレンドラインと水平線、全体表示、全画面表示、画面サイズの画像保存です。それ以外のチャートスタイル、その他のインジケーター、エポック線、ギャップの補完、対数軸とパーセント軸、チャート設定パネル、画面より大きな画像、その他の描画ツールには、文字で「Max の機能です」(ツールチップ)または「· Max」(選択肢)と表示されます。Max がオフの状態でこれらを選ぶと、Max が有効になります。Max の機能は無料になったため、目印は表示されなくなりました。Max がオンのときに選んだ設定は保持され、Max を再びオンにすると復元されます。
取引カード。 成行注文、指値注文、またはスワップに署名すると、ダイアログの上部にカードが表示され、その進行状況を追跡します(src/tradecard.ts、web/TradeCard.tsx)。各ステップとウォレット確認に対応した区分のあるバー、待機中の対象(ウォレット、チェーン、確認)、所要時間、進捗状況が表示されます。処理の状況に応じて、ダイアログ全体の枠線が変わります。処理中は青の枠線、ウォレットが処理の完了を確認すると緑の枠線と弾む動き、ステップが失敗した場合(または署名前に注文が拒否された場合)は赤の枠線と左右に揺れる動き、確認が必要な場合(処理の一部が完了した場合、または何も進んでいない場合)は、動きのない琥珀色の枠線になります。動きを減らす設定を使用しているユーザーにはアニメーションが表示されませんが、色は変わります。
QU の価格。 タイトルバーの中央には、QU のドル価格と過去24時間の値動きが常に表示されます。クリックすると、他のすべての資産と同じチャートが開きます(ローソク足のスタイル、1分から1日までの時間間隔、インジケーター、描画ツール、エポック線、出来高、チャート設定、画像の保存)。QU 1枚は1セントのごく一部に相当するため、価格はQU 100万枚あたりのドル額で表示されます(GET /v1/qu、/v1/qu/candles)。価格は5つの情報源を照合して算出した中央値で、Discord のサブスクリプション料金の算定にも使われるものです(bot/price.ts)。市場データは CoinGecko のもので、ローソク足は MEXC の QUBIC/USDT 市場のものです(MEXC に接続できない場合は Gate.io を使用し、USDT はドルとして扱います)。1回の応答につき最大5,000本を取得し、500本ずつ読み込みます。MEXC で QU が上場したのは2024年7月17日です。4時間足または日足でより長い期間を表示する場合、上場前の日付には Gate.io のデータを使用します。Gate.io では QU の取引が2024年5月9日に始まりました(Gate.io はそれより前の時間足またはそれより細かいローソク足を提供しておらず、無料で利用できる情報源にそれ以前の価格はありません)。CoinGecko の無料プランで遡れるのは1年までのため、市場データと、interval を指定しない /v1/qu/candles の1年以内のローソク足には CoinGecko のデータを使います。すべてのデータは範囲と幅ごとに1分から数分間キャッシュされるため、多数のユーザーがチャートを開いても、サーバーが取引所に問い合わせるのは数回だけで済み、ユーザーごとに問い合わせる必要はありません。interval を指定しない /v1/qu/candles は、引き続き CoinGecko 独自のローソク足を返します。
チャート設定。 チャートの歯車アイコンをクリックすると、配色、単色またはグラデーションの背景、ローソク足・ヒゲ・ラインの色、中空ローソク足、線の太さ、グリッド、出来高の強さ、書体、文字サイズを設定できます。設定はこのブラウザーに保存され、読み込み時に再確認され(src/chartstyle.ts)、保存した画像にも適用されます。エポック(水曜日 12:00 UTC、src/epochs.ts)は、あらゆるローソク足チャートに表示できます。
取引
src/exec.ts は、見積もりをウォレットが署名する順序付きのトランザクションに変換します。見積もり API は route[].execution で各レッグの制限を返すため(slippageBps で設定、デフォルトは 100 = 1%)、どのフロントエンドでも同じトランザクションを構築できます。
| レッグ | コントラクト呼び出し | 送信する QU | 保護 |
|---|---|---|---|
| QX で購入 | AddToBidOrder | 指値価格 x 数量(超過分は返金) | 指値価格 = 到達した最悪の売り気配 + スリッページ |
| QX で売却 | AddToAskOrder | 0 | 指値価格 = 到達した最悪の買い気配 - スリッページ |
| QSwap で購入 | SwapQuForExactAsset | 最大 QU + 手数料 100,000(超過分は返金) | 最大 QU = 見積もり + スリッページ |
| QSwap で売却 | SwapExactAssetForQu | 手数料 100,000 | 最小 QU 出力 = 見積もり - スリッページ |
| シェアの移動 | TransferShareManagementRights | 移転手数料(100) | 売却のみ:シェアは取引する取引所によって管理されている必要があります |
| QMax パス | QPAYHUB.Pay | 1,000 QU、24 時間に 1 回 | パスの有効期限が切れている場合のみ(下記参照) |
ExecuteModal は署名の直前に見積もりを再取得し、価格が変動していれば警告を表示します。ウォレット残高(購入時)とシェア保有数(売却時)を確認した後、各トランザクションに順番に署名してブロードキャストし、完了を待機します(web/exec/)。最初に失敗した時点で停止します。API が実行ヒントを返すのは、ライブデータを提供する場合のみです。
取引後、ExecuteModal はウォレットを再読み込みし(src/verify.ts)、署名時点の基準値と QU 残高およびシェア保有数を比較します。その後、約定したシェア数と要求した数、実際に支払ったまたは受け取った QU(取引所手数料を含む)、実際の価格と見積もりとの差、および板に残っている QX 注文(注文内でロックされている QU を含む)を報告します。未約定の QX 注文は EntityBidOrders / EntityAskOrders で読み込みます。
実資金での利用実績。 ウェブサイトで行われた取引は、メインネットで署名、ブロードキャスト、確認されています。これには QX 取引、QSwap スワップ、QSwap の流動性変更が含まれます。利用記録(GET /v1/stats、「利用状況の追跡」を参照)では、集計対象の各取引をチェーン上で検証するため、この件数は主張ではなく実測値です。ペイロードのレイアウトとトランザクションサイズも、コントラクトのソースと Qubic ライブラリに照らしてユニットテストされています。Discord ボットとエージェント SDK も同じコードで同じトランザクションを構築しますが、実資金での利用実績はウェブサイトより少ないため、まずは少額から始めてください(エージェントの場合はドライランの agentPlan を使用してください)。新しいものを試すときは、最初にごく少額で取引してください。既知の制限:QX の買い注文が全数量約定しない場合、未決済注文として板に残ります。また、残高の更新には数ティックかかることがあるため、結果の確認に少し時間が必要な場合があります。
市場比較、裁定取引、注文、取引準備
- 価格比較(
src/arbitrage.ts、comparePrices):QX と QSwap の両方にある資産について、0.3% の手数料を差し引いた単位あたりの買値と売値を、カード(「QSwap では 5% 安く購入」)と取引パネルに表示します(どちらも Max モードの機能です)。 - 裁定取引フラグ(
findArbitrage):一方の市場で購入し、もう一方の市場で売却したときに、すべての手数料(QX の 0.3%、QSwap の 0.3% と一律 100,000 QU。QMax では追加手数料なし)、プールの価格への影響、QX の注文板の最上位の厚みを考慮して、最終的に QU が増える組み合わせを探します。該当する資産には ARB ピルを表示し、裁定取引フィルターと、その内容を説明する取引パネルも用意しています。これはあくまでスナップショットです。2 つの取引は別々のトランザクションであり、QMax が裁定取引を代行することはありません。 - ライブ裁定取引チェック(
GET /v1/arbitrage?asset=ID、findArbitrageVenues):カードのフラグは最大 10 分前のキャッシュ済み最上位注文データに基づくため、取引パネルでは表示前に最新の完全な注文板とプールを再確認します。執筆時点では、2 つの市場に対応する 16 資産のいずれにも該当するものはありませんでした。 - 設定(ヘッダーの歯車、
src/settings.ts、web/settings.tsx):デフォルトのスリッページ(上限 10%)、取引の少ない資産の非表示、デフォルトの並べ替え、価格の省略表示または全桁表示、裁定取引フィルター(下記参照)を設定できます。ブラウザーの localStorage に保存され、保存値が無効な場合はデフォルト値が使用されます。 - 未約定注文(
src/verify.tsのfetchAllRestingOrders、web/OrdersPanel.tsx):すべての資産にわたるウォレットの QX の未約定買い注文と売り注文を一覧表示し、RemoveFromBidOrder/RemoveFromAskOrder(src/exec.tsのbuildCancelStep)でキャンセルします。キャンセルは無料で、キャンセルした買い注文のロック済み QU は返却されます。 - 取引準備チェックリスト(
src/readiness.ts):確認を有効にする前に、パネルでウォレットの接続、十分な流動性、手数料分の十分な QU(売却時も含む)、適切なコントラクト内のシェア(または必要な追加移動ステップ)を確認し、取引の少ない市場や手数料の高い取引について警告します。問題がある場合は取引をブロックし、警告のみの場合はブロックしません。
オーダーブックと価格チャート
- オーダーブック(
GET /v1/book?asset=ID[&levels=15]、src/book.ts):価格ごとにまとめたQXの注文と累積数量・コスト、最良買値と最良売値、中間値とスプレッド(および、1回のクエリで返される256件を超える注文がQXにあるかどうか)、さらにQSwapプールの価格、準備金、手数料、プールの0.1%、0.5%、1%、2%、5%にあたる取引で価格がどれだけ動くか(手数料を含み、QSwapの固定手数料100,000 QUを上乗せ)を表示します。ルーターが使用するものと同じライブデータを読み取ります。 - 価格履歴(
GET /v1/history?asset=ID&range=1d|7d|30d|90d|all[&interval=1h|4h|1d]、src/history.ts、src/trades.ts、src/events.ts):2つのソースを統合し、1本の線にします。過去の取引: QXはマッチした注文ごとにTradeMessageを記録し、QSwapはスワップごとにSwapMessageを記録します。アーカイブのQuery APIは、これらのイベントログ(/query/v1/getEventLogs、ベータ版)を提供します。QMaxはこれらを一度読み込み、TRADE_HISTORY_DAYS(既定値は1,825日、5年)まで遡ります。これは実在する期間よりはるかに長い期間です。Qubicアーカイブの取引ログは207エポック(2026年4月)頃までしか遡れないため、それ以前のものは見つからず、取引がある最初の月で検索を止めます。アーカイブに古いログが追加されれば、それも取り込まれます。QMaxはデータをアセットおよび取引所ごとの分単位に集計し(出来高加重価格、始値/高値/安値/終値、出来高を含みます。時間足、および1日以内の任意の整数分間隔のローソク足は、ここから作成されます。初版では時間単位で保持していました。そのファイルは.cache/trades.json.v1.bakに退避し、データをすべて新しい順に一度読み直します)、.cache/trades.jsonに保存します。その後は新しいティックだけを読み取るため、再起動後も停止した箇所から再開します。取引がある各時間が、src: "trades"としてマークされた履歴ポイントになります。QSwapプールを持つアセットは、そのスワップから描画されます(ライブ価格がプール価格であるため)。それ以外のアセットはQXの取引から描画されます。初回の読み込みには約1.5分かかり、読み込みながらチャートが埋まっていきます。ライブサンプル: カタログが市場を再読み込みするたび(約10分ごと)に、QMaxは各アセットの価格、最良買値と最良売値、プール価格、流動性を.cache/history.jsonに保存します。記録済みのサンプルは常に優先されます。再構築されたポイントが追加されるのは、記録がない時間(古いデータを間引いた場合は日単位)だけです。レスポンスのrecordedSinceは、ライブ記録の開始時点を示します。取引のない時間にはポイントがありません(線は隣り合うポイントの間に描画されます)。また、スワップ価格にはプール手数料と価格への影響が含まれるため、再構築されたポイントはプールの限界価格とわずかに異なります(比較対象のアセットでは約0.0~0.4%)。最近のサンプルはすべて保持され、3日より古いデータは1時間ごとに、90日より古いデータは1日ごとに間引かれます。intervalは始値/高値/安値/終値のローソク足も返します。TRADE_HISTORY=offで取引の検索を無効にできます。npm run trades-check -- 210を実行すると、何も書き込まずに検索結果を確認できます。アーカイブ自体の件数と照合済みです。QXは完全一致(27エポックで21,518件の取引)し、QSwapで最も取引の多いエポックでは、137,339件のイベントのうち137,305件をデコードしました(残りはサイズがゼロです)。 - 過去のQX履歴(Quhub)、任意: Qubicアーカイブには2026年4月以前の取引記録がありませんが、Quhub(QXサービスのオープンなコピーを運営するコミュニティサイト)には2024年10月まで遡る日次サマリーがあり、全期間の取引数が1,000件以下のアセット(大半が該当)については、すべての取引とその時刻も記録されています。
npm run import-quhubは一度だけQuhubを読み込み(自身のページで使われている公開APIに約150件のリクエストを1秒ごとに送信します。--dry-runでは書き込みを行わず、--only CFBでは1つのアセットだけを試します)、.cache/quhub.jsonに保存します。サーバーは起動時にこのファイルを読み込み、QMaxは稼働中にQuhubを呼び出しません。古いローソク足がアーカイブのデータより前に追加されるのは、ローソク足チャート上だけで、QXだけが対象です(「QSwapのみ」ではありません。また、該当するデータがある場合、「Best market」はQXとQSwapの両方を意味するため、古いQXローソク足の後に続く系列はQSwap単独のものではありません)。対象はアーカイブの最初の日より前の日付のみで、APIではsrc: "quhub"としてマークされます。チャートの下の行にもその旨が表示されます。取引の多いアセットでは、日次サマリーをローソク足として描画します(前日の平均価格で始まり、その日の平均価格で終わります)。そのため、これらのアセットについては2026年4月以前に日単位より細かいデータはありません。チェーンで確認できないデータであり、両方のソースがある場合、約1%以内で一致します(いくつかのアセットや日付では、さらに差があります)。そのため、バックテスター、健全性評価、プールなど、その他すべては引き続きアーカイブで確認されたデータだけを読み取ります(src/quhub.ts)。 - ローソク足と出来高(
GET /v1/candles?asset=ID&range=1d|7d|30d|90d|all[&interval=1m|5m|15m|30m|1h|4h|1d][&venue=auto|QX|QSwap|all]、src/chart.tsのcandleChartSvg):同じ時間単位の取引集計から作成した、ローソク足ごとの実際の始値、高値、安値、終値、QU建ての出来高、数量、取引件数を返します。ローソク足の幅は最低でも1分で、取引のない時間帯にはローソク足がありません(チャートには空白が残り、詰めて表示されることはありません)。幅は期間に応じて既定で設定されます。venue=allはQXとQSwapを1つの市場として扱います(高値と安値は両方の市場を対象とし、出来高は合算されます)。autoはライブ価格の取得元の市場に合わせます。レスポンスには、両市場を合わせた直近24時間の出来高も含まれます。ウェブチャートでは既定で出来高パネル付きのローソク足が表示され(「Line」はワンタップで切り替えられます)、Discordの/chartでも同様に「Line」ボタンから切り替えられます。SDKのQMaxClient.candles()。 - ウェブサイトのチャートにはTradingView Lightweight Charts(Apache-2.0)を使用しています(各チャートに表示される「TradingView」の帰属表示リンクは、ライセンスの要件に従って維持されます)。このライブラリは渡されたデータを描画するだけなので、残りはQMaxが追加しています(
web/ChartView.tsx、web/LwChart.tsx、web/chart/、テスト済みの純粋なコードはsrc/):- スタイル: ローソク足、平均足、OHLCバー、エリア、価格履歴の折れ線です。ローソク足の幅(自動、または1、5、15、30分、1時間、4時間、1日。取引は分単位で保持されるため、どの幅も実データです。自動では1Dに5分、7Dに15分、30Dに1時間、90Dに4時間、Allに1日が選ばれ、いずれも数百本のローソク足が表示されます。1回のレスポンスに含まれるのは最新の最大5,000本です)と市場(「QX chart」と「QSwap chart」のボタンがあり、後者はQSwapで取引されるアセットだけに表示されます。QXで始まり、QSwapでしか取引されないアセットではQSwapで始まります)は固定ではなく、選択できます。期間は1DからAllまでです。期間が静かすぎて読み取りにくい場合(ローソク足が12本未満)は、自動的に1段階広げてその旨を表示します。ただし、ユーザーが期間を選択した場合は除きます。データは1分ごとに更新され、ズーム位置は維持されます。
- インジケーター(
src/indicators.ts、独立した計算結果と照合済み):価格上にはSMA 20および50、EMA 21、ボリンジャーバンド(20、2)、VWAP(表示中の最初のローソク足以降に取引されたQUと数量から算出する実際の平均取引価格)を表示します。その下の個別パネルにはRSI 14、MACD(12、26、9)、ストキャスティクス(14、3、3)、ATR 14、OBVを表示します。価格軸は線形、対数、**%**に切り替えられ、出来高の表示も切り替えられます。凡例には、クロスヘア位置の有効な値がすべて表示されます。インジケーターの計算対象は実際に存在するローソク足です。そのため、市場が静かな場合、20本平均が20本分を超える時間を対象にすることがあります(Fill gapsを有効にすると、空のローソク足に直近の価格を引き継ぎ、系列を途切れさせません)。必要なローソク足の数が期間内の数を超えるインジケーターには、その旨が表示されます。 - 描画ツール(
src/drawings.ts、web/chart/drawings-primitive.ts):トレンドライン、レイ、水平線、垂直線、長方形、フィボナッチ・リトレースメント、計測ツール(QUの変動、割合、ローソク足数、時間)です。クリックして配置し、描画をクリックして選択し、ドラッグするか点を動かして変更します。Deleteキーで削除し、Escキーでキャンセルできます。色は6色です。描画は時刻と価格に固定されるため、ローソク足の幅や軸を変更しても位置が変わりません。このブラウザー内でアセットごとに保存され(localStorage。読み込み時に検証され、外部へ送信されることはありません)、保存画像にも含まれます。 - レイアウト: 取引ダイアログはウィンドウのほぼ全体を占め、チャートが主な領域となり、その横に細い注文入力パネルが表示されます。チャートはコントロールの下に残った高さ全体に広がり、描画ツールは取引端末と同じように左側に並びます。Wide chartを選ぶと注文入力パネルが非表示になり、「Show ticket」で再表示できます。スマートフォンではツールが「Chart tools」ボタンの背後にまとめられ、チャートが先に表示されます。
- 画像: カメラボタンを押すと、描画を含めたチャートを画面サイズ、Full HD、4K、**8K(横幅7,680 px)**のPNGとして保存できます。大きな画像は、チャートをオフスクリーンでそのサイズに合わせて再構築したものです。種類、線、描画もサイズに応じて拡大されるため(
web/chart/build.ts)、スクリーンショットを引き伸ばした画像ではなく、鮮明に表示されます。ブラウザーが大きすぎるキャンバスに対応できない場合は、次に小さいサイズを使用します。画面上のチャートは、ディスプレイのネイティブ解像度で描画されます。 - その他: 最新のローソク足への移動、全体表示、全画面表示(ブラウザーのFullscreen API)です。対応しない機能:テキストメモ、チャート上に描画するアラート、TradingView独自の全ツールセット(別製品のAdvanced Chartsライブラリには、同社からライセンスを取得する必要があります)。
- チャート(
src/chart.ts):単純な数値からSVGテキストとして描画する価格ラインと板状チャートです。ウェブサイト(インライン表示)とDiscordボットで共用されます。Discordボットでは@resvg/resvg-jsを使ってPNGに変換します。テキストの描画にはボットの実行環境にフォントが必要です。MacやWindows PCにはフォントがありますが、最小構成のLinuxサーバーにはDejaVuなどが必要です。画像を描画できない場合、ボットはブロック文字の行にフォールバックします。 - ウェブサイト: 取引パネルにはOrder bookとChartのタブがあります(オーダーブックは開いている間、20秒ごとに更新されます。チャートには1D/7D/30D/90D/Allがあり、履歴がまだ短い場合はその旨が明確に表示されます)。
- Discord:
/book ASSET(板状チャートとプール行を含むテキストの価格一覧)、/chart ASSET [range]、および/menuホーム画面のOrder bookとChartボタン(ドロップダウンからアセットを選ぶか、名前で検索します。チャート画面には期間ボタンとオーダーブックへの切り替えがあります)。すべて無料です。 - APIとSDK: どちらのエンドポイントも無料で、キーなしでIPごとにレート制限されています(課金されません)。SDKの
client.book()とclient.history()が利用でき、priceChartSvg/depthChartSvgがエクスポートされています。 - 他サイトのデータ: QubicTradeもQubicSwapもAPIや開発者向けドキュメントを公開していません(どちらの
/api、/docs、/developersも404です)。QubicTradeのページは、専用のプライベートWebSocketサーバーを通じて取引履歴と出来高を取得していますが、これは同サイト向けです。QMaxはこれを使用しません。両者の履歴データを利用したい場合は、アクセスを問い合わせてください。
Arbitrage の設定(Web、Discord、API)
誰でも、表示する価値のある Arbitrage の条件を3つのフィルター(src/arbfilters.ts。0は下限または上限なし)で設定できます。QUでの最小利益、投じるQUに対する最小利益率、そして投じるQUの上限である予算です。フィルターは検索中に適用されるため、予算を指定すると、その予算内に収まる最良のループ(より小さいループ)が返されます。最大のループを返して残りを切り捨てるわけではありません。また、最低条件を満たす結果がない場合は「なし」が返されます。
- Web: 設定(歯車アイコン)の Arbitrage セクションで、QUでの最小利益(デフォルトは10,000)、最小利益率、予算を設定できます。これらの設定は、カードのARBフラグ、Arbitrage フィルター、取引パネルのライブチェックに反映されます。他の設定と同様に、そのブラウザーにのみ保存されます。
- Discord:
/arbitrage-settings min_profit min_profit_pct budgetでDiscordアカウントに保存できます(オプションを指定しないと設定を表示し、resetで消去します)。すべての/arbitrageでこの設定が使われ、サブスクライバー以外に表示されるプレビューにも適用されます。 - API:
GET /v1/arbitrage?asset=ID&minProfitQu=…&minProfitPct=…&maxCostQu=…。条件を満たす結果がない場合は「なし」が返され、料金はかかりません。そのため、フィルターによって請求額が増えることはありません。
シェア管理(QXとQSwap)
取引できるのは、各取引所が管理するシェアのみです。QXで購入したシェアはQXが、QSwapで購入したシェアはQSwapが管理します。QMaxはこの処理を2つの方法で行います。
- 売却に必要な分を先に移動します。
buildExecutionPlanは、各レッグのシェアを管理しているコントラクトを確認します。QSwap経由の売却(単独または分割取引の一部)では、まずTransferShareManagementRightsを呼び出して、不足分だけをQSwapの管理下に移します。QXのレッグでも逆方向に同じ処理を行います。移動は独立したトランザクションであり、スワップまたは売却注文を送信する前に承認される必要があります。手順には「QSwapが売却できるように40 CFBをQXの管理下からQSwapの管理下へ移動」と表示され、取引準備チェックリストにも記載されます。手数料は、シェアを受け取るコントラクトに支払われます。移動するのは不足分のみなので、分割売却ではQXのレッグが自身のシェアを保持します。他の場所(たとえばスマートコントラクトにステークされたシェア)が管理するシェアはここでは売却できず、その旨をエラーで通知します。 - すべてを1つのコントラクトの管理下に維持します(任意、デフォルトはQX)。 購入を組み立てる際に確認されます。確認ダイアログには、QX(デフォルト)またはQSwapを選ぶ After buying, keep my ASSET under one contract という項目があり、ルートによって追加される処理が表示されます(「QSwapからQXへ400 CFBを移動、手数料は約100 QU」。QXのみを使うQXでの購入では、移動はありません)。チェックを入れると、購入の承認後に、確認をもう一度求めずに最後の手順として移動を署名します。また、別のコントラクトの管理下にすでにある、そのアセットのシェアも移動します。保存済みの設定(設定、シェア管理)は最初に選択される項目だけを指定します。売却後には、残ったシェアを移動するボタンが表示されます。My assets > Keep all under one contract では、ウォレット内のすべてのアセットを一度に移動し、アセットごとに1つの署名付きトランザクションを実行します(
src/consolidate.ts。他のコントラクトの管理下にあるシェアは一覧表示されますが、移動されません)。Discordでは、購入見積もりにBuy nowとBuy and keep under QXの2つのボタンが表示されます(後者は最後の手順として移動を実行します)。/keep-shares under:では、その選択肢がメインボタンになり、売却後に移動するオプションも表示されます。/consolidateはすべてを移動します。ボタンを押すまでは何にも署名されません。また、各移動では、受け取り先のコントラクトの移転手数料がかかります(QXとQSwapからリアルタイムで取得)。
QMax パス(任意、デフォルトでは無効)
現在、取引は無料です。これは VITE_REQUIRE_PASS=on で再び有効になるパスについて説明しています。 QMax は取引から何も受け取りません。価格、見積もり、市場全体の表示は無料ですが、取引の実行にはパスが必要です。src/config.ts で設定されている PAYWALL.priceQu(1,000 QU)を一度支払うと、PAYWALL.hours(24)時間、無制限に取引できます。
- 支払い方法: QPayhub(コントラクト 29、トークン QPAY)を通じて支払うため、QPAY に還元されます。ウォレットは 1,000 QU を添えて
Pay(seller = QMax address, resourceId = "QMAXPASS", nonce)に署名します(src/pass.ts)。QPayhub はその 0.75%(最低 100 QU)を株主と QPAY 保有者のために保持し、残りを同じトランザクション内で QMax アドレスに転送して、領収記録を保存します。 - 仮定ではなく検証: QPayhub は支払いを拒否した場合に返金します(トランザクションはそのまま確定します)。そのため、支払い後にアプリはコントラクトから領収記録を読み取り(
fetchReceipt:ComputeReceiptKeyの後にGetReceiptを実行し、数秒間再試行)、その後でのみパスを保存します。メインネット上の実際の QPayhub 支払いで、領収記録の照会を確認しました。 - 表示場所: 取引準備チェックリストには「QMax pass」の項目があります。パスがない場合、ボタンには「Unlock trading: 1,000 QU for 24 hours」と表示され、
PassModalが開きます。署名の直前に、確認ステップでパス(有効期間の 24 時間以内であること、および QPayhub が引き続き領収記録を保持していること)を再確認します。ネットワークに接続できない場合は保存済みのパスを信頼するため、一時的な不具合で二重に支払うことはありません。 - 制限事項: 正直に説明すると、パスは 1 つのウォレットに紐付き、そのブラウザーに記憶されます(別のブラウザーでは再度支払いを求められます。パスが有効な間の支払いもブロックされません)。確認はユーザー自身のブラウザーで行われるため、独自のトランザクションを作成したり、アプリを編集したりする人を止めることはできません。また、24 時間の起点はブラウザーに保存した時刻であり、オンチェーンの領収記録が証明するのは支払いが行われたことだけです。すべての呼び出し元にペイウォールを強制するには、QX と QSwap 自体を呼び出す QMax のスマートコントラクトが必要です。
仕組み
- QX の板の厚み: 板の注文を 1 件ずつ処理します。見積もりには使用した注文数と消費した板の厚みの割合が表示されます。板の厚みを超える注文の場合、QX は「約定不可」を返します。板に 256 件の注文(クエリ上限)がある場合、さらに注文が存在する可能性があるため警告が表示されます。
- QSwap の取引サイズ依存性: 価格は取引サイズに依存するため、ルーターは各取引所について注文の 25/50/75/100% のサイズで見積もりを取得し、これらの見積もり間を補間して最適な分割を選びます。その後、選ばれたサイズの前後で見積もりを追加し、再度検索します。最終価格は常に実際の見積もりであり、固定コストを差し引いても単一の取引所での実行を上回る場合にのみ分割が選ばれます。
quoteCallsには、この処理にかかった見積もりの回数が表示されます。 src/venues.ts:取引所モデル。src/router.ts:段階的な見積もりと分割検索。src/cli.ts:JSON スナップショットを使って実行します。
未対応の項目
- ライブデータ:取引所のデータはスナップショットから読み取ります。アダプターでは Qubic RPC から QX の注文板と QSwap の準備金を取得するか、
variableNetQuフックを通じてオンチェーンの Quote* 関数を呼び出す必要があります。 - 実行:見積もりのみ対応しています。トランザクションの構築には対応しておらず、見積もりから約定までの間に状態が変化した場合のスリッページ保護もありません。
Discord ボット
Discord ボットのソースコードはこのリポジトリに含まれていません(QMax 独自のサーバーで実行されています)。このセクションではホスト型ボットについて説明します。bot/price.ts の QU 価格フィードを除き、API やウェブサイトはボットに依存していません。
npm run bot を実行すると、Discord から取引できます(QMax API が起動している必要があります。npm start で起動します)。ボットがキーを保持することはありません。WalletConnect 経由で、ユーザー自身のウォレットに署名を求めるだけです。
/menuはタップで操作するダッシュボードなので、何も入力する必要はありません。あなた専用で、操作に合わせて内容が変わります。Buy / Sell / Quote(ドロップダウンから資産を選択します。売却時は保有資産、それ以外では最も流動性の高い資産、または 名前で検索… を選択します。次に数量ボタン、売却時は すべて、または カスタム数量… を選びます。その後はコマンドと同じ見積もりボタンと確認ボタンを使います)、Arbitrage(すべての資産をスキャンする、1つを確認する、またはフィルターを設定する)、Wallet、Connect / Disconnect、Subscribe、Settings(アービトラージのフィルター、保有分の扱い、すべてを QX または QSwap に移動する設定)があります。各画面には Menu または Back ボタンがあり、スラッシュコマンドも引き続き使えます。コマンドも同じコードを使用するため、サブスクリプションやチェックは同じように適用されます。Discord のドロップダウンは項目が 25 個までで、ボタンでは入力を受け付けられないため、名前で検索… と カスタム数量… を選ぶと小さなポップアップフォームが開きます(bot/menu-ui.ts)。/connectは Qubic ウォレットをペアリングするための QR コード(スマートフォン用リンクも)を表示します。/walletはアドレス、残高、プランを表示し、/disconnectは接続を解除します。/quote、/buy、/sellは、ウェブアプリと同じルーターを使って QX と QSwap を横断して取引価格を算出します。/buyと/sellには Confirm ボタンが追加されます。その後、各ステップで署名リクエストがウォレットに届き、ボットは実際にウォレット内で移動した内容を報告します。- 誰でも無料で利用でき、サポートする方法もあります。 QMax の所有者は 2026-10-07 にコミュニティへ提供することを決定しました。ボットのサブスクリプションは無効になっています(
BOT_SUBSCRIPTIONSは未設定です。onにすると以下の機能がすべて再び有効になります)。そのため、取引とアービトラージの詳細を含め、Discord のすべての機能が無料です。/support(および/menuの Support QMax)は Q+Pay チップジャーを使います。SUPPORT_URLに QPay ダッシュボードのチップジャーリンク(https://useqpay.com/tipjar/<id>、https のみ)を設定すると、Support にそのリンクの QR コード(QMax X 入り)と Q+Pay でチップを送る ボタンが表示されます。サポーターは Q+Pay のチェックアウトで金額を選択します。SUPPORT_URLが設定されていない場合(または https の URL でない場合)は、代わりに QU の送金先となる QMax のアドレス(SUPPORT_ADDRESS、デフォルトは QMax への支払い先アドレス)をテキストと QR コードで表示します。ウェブサイトでは、タイトルバーに Qubic のハート(ピクセルアートのハート。web/ui.tsxのQubicHeart。以前 Max の切り替えスイッチがあった場所に配置)があり、SUPPORT_URLが設定されている場合はチップジャーへの直接リンクになり、設定されていない場合はアドレスと QR コードを含む Support ウィンドウを開きます。また、フッター、Settings、ウェルカムウィンドウにも Support QMax ボタンがあります。GET /v1/plansはsupport: { url, address }とagents: { maxPriceQu, sessionPriceQu, sessionSeconds }(エージェントが支払う金額。同じ設定を参照)を返します。ウェルカムウィンドウのエージェント料金の行にはこれらの数値が表示されるため、古い価格が表示されることはありません。この項目の残りの説明は、サブスクリプションが有効になっている場合についてです。 - ボットで有料なのはアラートのみです(
BOT_ALERTS_PRICE_QU:ライブサーバーではBOT_SUB_DAYS(30)日間で 100,000 QU。未設定の場合は無料)。ボットはアラートごとに毎分ほど市場をチェックするため、実際のリソースを消費します。これを設定すると、/subscribe(および/menuの Subscribe)で、以下のサブスクリプションと同じように QPayhub 経由でアラートプランを購入できます(QMAXSUBの領収記録を購入成立前に確認し、各支払いを一度だけ計上します。期限前の支払いでは日数が加算されます)。どの種類のアラートでも利用にはプランが必要です。プランがない状態で/alerts add-…を実行すると料金が表示され、サブスクリプションの期限が切れるとアラートは削除されずに一時停止します。一時停止中は市場チェックのコストが発生せず、再度サブスクリプションに加入すると自動的に再開します。取引、見積もり、チャート、アービトラージの詳細、その他すべての機能は引き続き無料です(BOT_SUBSCRIPTIONSは無効のままです)。ローンチ時の無料期間(BOT_FREE_UNTIL)はアラートには適用されません。GET /v1/plansはdiscord.alertsPriceQuを返し、ウェブサイトのウェルカムウィンドウにもその金額が表示されます。これはサブスクリプション収入なので、サブスクリプションと同じように加入者の利益分配に充てられます。 - 取引ごとの手数料がない単一のサブスクリプション(ウェブパスとは別です)。料金は30 日間で 100,000 QUです。固定額(
BOT_SUBSCRIPTION_PRICE_QU)で、期間はBOT_SUB_DAYSで設定します。BOT_SUBSCRIPTION_PRICE_QUを設定しない場合、代わりにライブ QU 価格でBOT_SUBSCRIPTION_USDドル(デフォルトは $1)相当の料金になります(以下を参照)。GET /v1/plansは現在の料金、期間、無料期間をウェブサイトに返します。/menuの Subscribe(または/subscribe)から、ウェブパスと同じように QPayhub 経由で支払い、QPAY にも収益が入り、オンチェーンの領収記録が残ります。ボットは支払い成立前に領収記録を確認し、各支払いを一度だけ計上します。また、支払いを再試行すると同じ nonce が再利用されるため、二重払いが発生した場合、QPayhub が返金します。期限前に再度支払うと、残りの日数に加算されます。- サブスクリプションが必要: Discord からのすべての取引。
/buyと/sellは、ルート(単一市場、または両市場に分割)を問わず必要です。また、/arbitrageの詳細(資産、方向、サイズ)にも必要です。/arbitrage ASSETは単一の資産を全板情報でリアルタイムに確認します。資産を指定しない場合は、両方の市場ですべての資産をスキャンします。サブスクリプションがない場合も、/buyと/sellは見積もり全体を表示して料金を案内します。また、/arbitrageは機会の件数と最も利益の大きい機会の価値を表示しますが、どの機会かは表示しません。 - 無料:
/quote(分割を含む最適なルート全体)、/connect、/wallet、/disconnect、/consolidate、/keep-shares、設定コマンド、/menu自体。
- サブスクリプションが必要: Discord からのすべての取引。
- ローンチ時の無料期間(
BOT_FREE_UNTIL。例:2026-11-06)。この日までは、サブスクリプションの有無にかかわらず、誰でも Discord から取引でき、アービトラージの詳細を確認できます。また、メニューとウォレット画面には「…までは誰でも無料」と表示されます。これはボットの応答でのみ有効です(支払いなし、領収記録なし、オンチェーンでの記録なし)。そのため、有料サブスクリプションの期間は延長されず、無料期間を超えて有効なサブスクリプションは、無料期間の終了後も有効です。Subscribe 画面では、まだ支払う必要がないことが案内されます。この設定を省略すると、サブスクライバーのみが取引できます。 - 接続コード(ウェブサイトの WalletConnect 手順とボットの
/connect)は、中央の白いプレートに QMax X を配置した QR コードです(src/qrlogo.ts:誤り訂正レベル Q。読み取り時に隠れた中央部分を復元できます。420、300、240、180 ピクセルでデコードできることを確認済みです)。ウェブサイトでは、コードとその下のボタンの幅が統一されています。 - QU 価格が変動しても $1 を維持(固定の QU 価格が設定されていない場合のみ)(
bot/price.ts)。ボットは 5 分ごとに、独立した 5 つの情報源(CoinGecko、CoinPaprika、Gate.io、MEXC、Bitget)から QU 価格を取得し、互いに一致する情報源の中央値を使用します。取引所のペアは USDT で、ドルとして扱います。中央値から 15%以上離れた価格は除外され、複数の価格帯に分かれる情報源は採用されません。最後に採用された価格から 25%を超える変動は、2 つ以上の情報源が裏付けた場合にのみ採用されます。金額は $1 をその価格で割り、3 桁の有効数字で切り上げます(例:1,760,000 QU)。そのため、$1 未満にならず、超過分も 1%を超えません。誰かが Subscribe を押すと、金額は 15 分間固定され、Pay ボタンに表示されます。ボタンには表示されていた金額が適用されます。固定価格の期限切れ、または価格の変更後に支払いを試みた場合は、自分が確認していない金額を支払う代わりに、新しい金額が提示されます。同じ支払いに対して提示された金額はどれも支払いとして有効なので、2 回の提示の間に価格が変動しても、支払い済みの人が取り残されることはありません。すべての情報源から価格を取得できない場合、ボットは最長 6 時間、最後に取得した有効な価格を使用します。その後は価格を算出できない旨を伝えます(その他のコマンドは引き続き使えます)。安価にテストするには、BOT_SUBSCRIPTION_PRICE_QUに固定の QU 額を設定します(この場合、ライブ価格は使われません)。ウェブパスと API の料金は引き続き QU 建てです。 - ウォレットで開く(Discord と同じスマートフォンで利用)。Discord のボタンから開けるのはウェブアドレスのみです。そのため
BOT_PUBLIC_URL(スマートフォンから API にアクセスできるアドレス。例:https://api.example.com)を設定すると、Connect 画面に API の/openページ(src/openpage.ts)を開く Open in wallet ボタンが表示されます。このページは、アドレスの#以降からペアリングリンクを読み取ります。ブラウザーはこの部分をサーバーに送信しないため、リンク内の秘密情報がログに記録されることはありません。リンクが有効期限内の正規の WalletConnect リンクであることを確認し、qubic-wallet://pairwc/…(ウェブサイトで使用するものと同じアドレス)でウォレットアプリを開き、アドレスバーからリンクを消去します。また、バックアップ用の Copy link ボタンも用意されています。外部サイトから何も読み込まず、外部への送信も行いません(厳格なContent-Security-Policy、no-store、リファラーなし)。BOT_PUBLIC_URLが設定されていない場合、Connect 画面には QR コードと Copy link ボタンが表示され、リンクのみがプライベートメッセージで送信されます(長押しして Copy Text を選択)。 - ウォレットに関係する返信はすべて、ペアリング用 QR コードを含め、ユーザーにのみ表示されます(エフェメラル)。
セットアップ:discord.com/developers でアプリケーションとボットを作成し、トークンを
.envのDISCORD_TOKENに設定します。cloud.walletconnect.com から無料のWALLETCONNECT_PROJECT_IDを取得し、価格を 1 ドル以外にしたい場合はBOT_SUBSCRIPTION_USDも設定します(.env.exampleを参照)。applications.commandsスコープを指定してボットを招待します。状態(ウォレットアドレス、セッション ID、プラン終了日)は.cache/bot/に保存されます。
他のサイト向け API 課金(任意、デフォルトではオフ:API_ACCESS=billing)
API は現在無料です(「料金が発生するもの」を参照)。ここでは、API_ACCESS=billing で再び有効になる前払いモードについて説明します。
他のサイトが料金を支払う対象は分割ルートです。QX と QSwap のルーティング単独なら、qubictrade.com や qubicswap.com などの DEX がすでに提供しているため、API が課金するのは、両方の取引所をまたぐ分割ルートが最適ルートとなる見積もりのみです。サイトは残高を前払いし、QPayhub 経由でチャージします。そのため、QPAY にも還元されます。ドキュメント:GET /v1/openapi.json。
- 課金対象: 両方の取引所を使うルートが最適ルートとなる
/v1/quoteリクエストをx-api-key付きで送信すると、API_SPLIT_PRICE_QU(デフォルトは 100 QU)が課金されます。機会を見つけた/v1/arbitrageの確認にはAPI_ARBITRAGE_PRICE_QU(デフォルトは 50 QU)が課金されます。「現時点ではありません」は無料です。また、単一の取引所に解決される見積もり、失敗した呼び出し、一覧、検索、ドキュメントも無料です。レスポンスにはx-qmax-charged-quとx-qmax-balance-quが含まれます。残高が不足している場合、分割ルートの見積もりではルートを非表示にした402が返され、分割によってどれだけ節約できたか(splitWouldSaveQu)が示されます。裁定取引の結果では詳細を非表示にした402が返され、利益(opportunityProfitQu)が表示されるため、サイトは得られる利益を確認できます。split=falseを送信すると、常に単一の取引所の見積もりが無料で取得できます。 - キーなしの場合: 見積もりは利用できますが、IP ごとに
API_FREE_PER_MIN(デフォルトは 60)までに制限されます。QMax のウェブアプリや試用には十分ですが、アクセスの多いサイトには足りません。無料の見積もりもノードを使用するため、キーにはその 10 倍の上限が設定されます。管理下のプロキシの背後で使用する場合は、TRUST_PROXY=1を設定して、制限に実際のクライアント IP が使われるようにします。 - 利用開始:
POST /v1/keysは{ key, keyId }を返します(無料、残高 0。一度だけ表示。IP ごとに 1 時間あたり数個まで)。GET /v1/topup?keyId=…&amountQu=…は、任意のウォレットで署名する取引を返します。これは指定された量の QU を送る QPayhub のPayです(QPayhub が各支払いから少なくとも 100 QU を保持するため、最低額はAPI_MIN_TOPUP_QU、デフォルトは 10,000 QU)。レシートにはキー名が記録されます。- 支払いが確定したら、
POST /v1/topup/claim { keyId, payer, nonce }を呼び出します。サーバーは QPayhub からレシートを読み取り、支払われた金額を残高に加算します。各支払いは一度だけ計上され、支払いはレシートに記載されたキーにのみ加算されるため、他の人の支払いを請求することはできません。 GET /v1/accountで残高を確認できます。10,000 QU を前払いすると、分割ルートの見積もりを 100 回利用できます。
- 独自のキー:
API_KEYは課金や制限の対象になりません。Discord ボットがこれを送信します(ボットの.envに設定するAPI_KEYと一致させる必要があります)。ADMIN_KEY(別の値で、ボットの環境変数には設定しません)は、登録者一覧、利益分配、支払い、利用統計に使う所有者のキーです。ボットのキーが漏れても、マーケットへのアクセスしか漏れません。メーター(API_METER=off)を使わない場合、API は公開状態になるか、従来どおりAPI_KEYのみで保護されます。 - 制限について: 残高はサーバー上の
.cache/meter.jsonに保存されます(前払い分の記録なのでバックアップしてください)。呼び出しごとの課金は 0.5 秒以内に書き込まれます。また、チャージの請求は、QPayhub にレシートが保持されている間(約 2 エポック)に行う必要があります。無料枠は IP ごとに適用されるため、重い利用は抑制できますが、アドレスを切り替えるユーザーを阻止するものではありません。安定した利用量を確保するには、有料の利用方法が適しています。
市場インテリジェンス(他のQubicサイトにはない情報)
すべて、同じ公開データを基に構築されています。アーカイブのイベントログ(src/trades.ts)にある6か月分のすべてのQX約定とQSwapスワップ、ライブの板情報とプール、そして手数料に関するコントラクトのソースです。すべてのエンドポイントは/v1/openapi.jsonに記載され、型付きのQMaxClientメソッドがあり、MCPツールでもあります(mcp/)。各項目には、対象外となるデータも明記しています。
- アセットの健全性(
GET /v1/health?asset=ID、GET /v1/health/all、src/health.ts):0〜100のスコアとA〜Eの評価を、価格から2%以内の厚み(プールがある場合は、幅の広いQX板の中値ではなくプール価格を基準に測定)、スプレッド(QXの価格は整数QU単位なので、1 QUの差は「広い」とはみなしません)、取引頻度と経過時間から算出し、分かりやすい理由も示します。ウォッシュトレードの検出は意図的に厳格です。アーカイブには何が取引されたかは記録されていますが、誰が取引したかは記録されていないため、通常の取引ではあり得ないパターンだけを検出します(1時間に少なくとも300件の小口スワップがあり、平均額が5,000 QU以下で、同じリズムで繰り返されるパターン)。実データでは、エポック211の10日間におけるCFBの1アセットだけが該当します。1つのウォレットが103 QUのスワップで売買を繰り返し、137,096件のスワップがプール出来高の約0.1%を占めていました。「そのように見える」として報告され、過去の急増は参考情報にとどまります(wash-past、スコアへの減点なし)。大口のウォッシュトレードはこの方法では検出できないため、フラグがないことは健全性の保証にはなりません。 - Marketsタブ(
GET /v1/premium?asset=ID&range=...、src/premium.ts):QXとQSwapの価格差が1時間ごとにどれほどあったか、また、指定した取引額での取引コストを上回る差が何時間あったかを示します(損益分岐点は手数料定数から算出します。プール手数料0.3%、QXの売り手手数料0.3%、QSwapの固定手数料100,200 QUのため、10M QUでは約1.3〜1.6%、1M QUでは10%超です)。これは利益ではなく、上限値です。時間ごとの平均値にはQXの売買スプレッド(コストを上回ることもよくあります)や、2つの取引の間の遅延が含まれません。carryを指定して価格を最大3時間分の代表値として扱わない限り、両方の市場で取引があった時間だけを比較します。 - Pools(
GET /v1/pools、GET /v1/pools/detail、src/pools.ts):実際の手数料収入に基づいて、すべてのQSwapプールを順位付けします。コントラクトのソースとライブのFees関数によると、スワップではQU側の0.3%が支払われ、そのうち64%が流動性提供者のためにプールに残ります。そのため、各スワップの出来高の0.192%がLPに渡ります(残りはQSwapの株主、QX、報酬、バーンに回ります)。スワップ、追加、削除ごとの固定100,000 QUは、LPの収入にはなりません。手数料APRは直近の実績で、価格変動とインパーマネントロスはスワップ価格から算出し、預け入れ額を指定すると手数料とILを見積もる計算機能もあります。出来高が少ないプールや急増に偏ったプールにはフラグを付け、正常なプールより下位に順位付けします。情報を隠したり、上限を設けたりはしていません。 - バックテスト(
POST /v1/backtest、src/backtest.ts):実際の時間足ローソク足と各取引所の実際の手数料を使って、hold、dca、bandsを再生します(QXの売り手手数料0.3%、QSwapのスワップごとの固定手数料100,100 QU。QSwapの0.3%は記録された価格にすでに含まれているため、二重に課金しません)。判断は1時間足の終値で行い、約定は次の1時間足の始値で行います。取引のない時間に価格を捏造することはなく、結果には常に警告が付されます。履歴に注文板の厚みがないため(大口の場合は楽観的な結果になります)、また、近隣の価格から40%超離れていた時間足も数えています。QDOGEに週500,000 QUを90日間DCAした場合、開始時のQUの13%を手数料に支払い、約+8%のリターンでした。固定のQSwap手数料があるため、小口の定期購入にはQXが適しています。 - ライブテープと注文フロー(
GET /v1/tape、GET /v1/flow、src/tape.ts):両方の市場における新しい約定とスワップを、売買方向とともにまとめて配信します。QSwapスワップの方向はイベントに含まれています。QXの約定は両サイドで同じように記録されるため、方向は原因となったトランザクションから判定します(送信者がテイカーです。コール6=買い、5=売り)。これは、ある1日のQX全トランザクションについて、誰がシェアを受け取ったかと照合して確認済みです(109件中107件が完全一致し、残り2件はアカウント自身との取引でした)。メモリから配信するため、頻繁にポーリングしても負荷は低く抑えられます。取引インデックスは15秒ごとに新しいティックを読み込みます。 - ウォレット台帳と損益(
GET /v1/ledger?identity=ID&format=json|csv&days=1..365、src/ledger.ts、Historyタブ):アーカイブのイベントログから再構築した、ウォレットによるQXとQSwapでの売買記録です(QUとシェアの移動をトランザクションごとにまとめます。公開チェーンデータのため、どのidentityでも利用できます)。価格、手数料、継続保有数、平均取得原価による実現損益、現在価格での含み損益を表示します。CSVエクスポートは固定列(date、tx hash、kind、venue、asset、issuer、quantity、price、QU net、estimated fee、position、realized P&L)の後にポジション表が続きます。実際の7つのウォレットと707件の取引で確認済みです。サンプル取引232件中232件がコントラクト自身の記録と完全一致し、QXの売却手数料は59件中59件が一致しました。また、シェアが移動したすべての自身のトランザクションに記録があります。これは推定値であり、制約も明記します。アーカイブには2026年6月10〜14日ごろのイベントが一切なく(この期間のデータは欠落し、台帳に警告が表示されます)、送金または対象期間より前に受け取った単位は取得原価が不明です(それらを売却した場合は利益ではなく、別扱いとして計上されます)。QSwapの流動性変更は送金として表示され、含み損益には中値またはプール価格を使うため、流動性の低い市場では誤解を招く可能性があります。作成にはアーカイブへのリクエストが3〜29回(約1〜13秒)必要で、ウォレットごとに60秒間キャッシュされ、同時実行は最大2件です。税務アドバイスではありません。 - スワップとMaxスワップ(Swapタブの
web/SwapPanel.tsx):タブは2つの部分で構成されています。Maxをオフにすると、通常のスワップになります。QSwapプールを通じて、トークンをQUに、またはトークンをQUに戻します(GET /v1/venue-quoteから取得するQSwap専用の見積もりで、取引と同様に署名します。プールのあるトークンだけが一覧に表示され、プールが支払い全額を受け取ってしまうほど少額の買いは拒否されます)。Maxモード(Settingsの切り替え)をオンにすると、別のアセットへのスワップが可能になります。これはQMax Proの一部です(しばらく無料で試用できます。「MaxとQMax Pro」を参照してください)。My assets内の各保有アセットにあるSwapボタン(Maxをオンにした場合のみ表示)も同じ機能です。この段落の残りはMaxスワップについて説明します。トークン間スワップ(署名用のPOST /v1/swap-quote、src/swap.ts、web/SwapModal.tsx):売却元と購入先のトークン、数量、および最良条件の根拠を含むライブのプランを提供します。compare: trueを指定すると、サーバーは同じスワップをさらに4通り計画し、売却と購入をそれぞれQXまたはQSwapのどちらかに固定して、各組み合わせの価値をQMax独自のルート(bestDeal)と比較します。「価値」は、購入した単位数に、残ったQU(そのプラン独自の購入価格で評価)を加え、前払いした手数料を差し引いて算出します。単位数だけでは誤解を招くためです。より有利な価格で購入するプランでは、最悪ケースの上限価格を基に数量を決めるため、購入できる単位数が少なくなる一方、残りのQUを保持できる場合があります。利用できない組み合わせはその理由とともに表示され、単一市場がすでに最良の場合には、利益があるとは主張しません。あるトークンをQUに換えてから、そのQUで別のトークンを購入します。1回の確認画面で計画と署名を行いますが、取引は2件であり、不可分な1つのトランザクションではありません。この設計にはその点が織り込まれています。第2段階の数量は、第1段階で上限内に得られる最小額に合わせて設定されます(minOutQty。どちらの価格もスリッページ上限を超えて動かない場合にのみ保証されます)。第1段階で必要な固定手数料分のQUは事前に表示され、第1段階の決済後、ウォレットの実残高に基づいて第2段階の数量を再調整します。ウォレットにないQUを送ることはなく、足りない場合は拒否します(QUはウォレットに残ります)。独立監査では、Qx.hとQswap.hから資金計算を再導出し、両コントラクトのシミュレーターを使い、各段階の間に市場価格を変動させながら4,000件のランダムスワップでテストしました。その結果、4つのバグが見つかって修正されました。最も重大だったのは、実際のコントラクトにあった罠です(下記参照)。運用者が上限を設定しない限り、数量制限はありません(サーバー環境変数のSWAP_MAX_OUTLAY_QUを設定すると、リスクにさらすQUがその額を超える可能性のあるプランを拒否します)。これ以外の制限は各コントラクト独自のものです。未検証の項目:実際のトランザクション、および署名要求が2回続く実際のウォレットフロー。 - QMaxがすべての買いで回避するようになったコントラクトの罠。
Qswap.hのSwapQuForExactAssetでは、買いに必要なQUがプロトコル手数料の36 QUを下回ると、コントラクトはその少額分だけを返金し、固定手数料の100,000 QUも含め、送信された残りのすべてを保持します。プールのみのアセットで、約1 QUのトークンを数単位だけ買うと、100,000 QUを失う可能性がありました。route()は、入力が1,000 QU未満で済むQSwapの買いを提示しなくなりました(QSWAP_MIN_BUY_QU。売却が失敗した場合は固定手数料が毎回返金され、この罠はありません)。見積もりにはその理由が表示されます。これを回避できるのは、注文数量を独自に設定するプロセス内の呼び出し元(独自のチェックを行うスワッププランナー)だけであり、APIリクエストからは回避できません。 - QSwapでの流動性の追加と削除(
GET /v1/liquidity/positions?identity=ID、GET /v1/liquidity/pool?asset=ID、src/liquidity.ts、web/LiquidityModal.tsx、web/PoolPositions.tsx、Poolsタブ):「Your liquidity」には、ウォレットのポジション(単位数、プールに占める割合、すべて削除した場合の受取額、プール価格での価値、コントラクト独自のearnedFees)が表示されます。GetLiquidityOfとGetPoolBasicStateからライブデータを読み取ります。プールの「Add liquidity」やポジションの「Remove」を選択すると、署名の直前にプールの状態を再確認するプランが開きます。計画のみを行い、署名はウォレットで行います。すべてをQswap.hから1行ずつ確認し、拒否されるすべての経路を洗い出しました。プランナーが対処する、ソースで検証済みの3つの罠:- **追加時にトークンの端数が気付かれないまま渡される可能性があります。**添付したQUの額によって預け入れ額が制限される場合、コントラクトはその全額を受け取り、切り捨てたトークン数を適用しますが、
quAmountMinは確認しません。そのため、価格が下落しても処理は中止されません(実際にQCAPの預け入れでは、21トークンに対して6,000,000 QUが投入され、さらに別のケースでは150,186 QUが失われました)。QMaxはトークン側の数量を固定し、コントラクトが正確な経路を通るだけのQUを添付するため、丸め誤差は数QU程度です。スリッページ余地としてトークン1個分を残せないほど少額の預け入れ(QCAPは1トークンあたり約270,000 QU)は拒否され、実行可能な最小額が表示されます。 - 最小額を指定せずに削除すると、支払いがゼロのまま固定手数料が差し引かれ、流動性が焼却される可能性があります。削除には両側とも最低1の最小額を指定して署名するため、コントラクトは代わりに処理を拒否して返金します。また、いずれかの側の受取額が0になる削除は、事前に拒否されます。
- トークンの整数単位で支払われるため、端数はプールに残ります。一部削除の場合、同じトークン数を支払うために必要な流動性の最小量だけを焼却し、残りはポジションに残します。
追加と削除のそれぞれに固定の100,000 QUもかかります(流動性が実際に移動した場合のみ徴収され、拒否された場合は毎回返金されます)。トークンはQSwapの管理下にある必要があります(QMaxはまずQXから移動します。この手順では100 QUを添付しますが、そのまま返金されます)。プールの作成(最初の預け入れ。1,000単位が永久にロックされます)は提供していません。読み取り専用のSDKメソッド
liquidityPositions/liquidityPoolとMCPツールを利用できます。構築と署名はWebアプリでのみ行います。npm run liquidity-checkは、エポック内のすべてのQSwapイベントをライブコントラクトと照合して再生します(直近の実行では、adds 7 matched / 0 not, removes 1 / 0, swaps 189 / 0)。独立監査ではQswap.hを再確認し、BITEの初回預け入れから全履歴を再生しました(追加14件中14件、削除5件中5件、スワップ123件中123件が一致し、最終状態はライブプールと同じでした。これはトークン側の経路を網羅しています)。計算に誤りは見つかりませんでした。周辺部分では問題が見つかり、修正しました。シェア移動と預け入れの間にプールを再読み込みしていなかった問題(その間に価格が上がると最大でトークン約1個分の損失があり得ましたが、現在は確認画面、署名時、移動後に停止します)、「何も変わらなかった」というメッセージが、ウォレットによる拒否ではなくコントラクトを責めていた問題、手数料未満の価値しかない残高が残り得る一部削除(現在は警告します)、変更後にポジション一覧が古いままになる問題(fresh=1)、および預け入れ額が薄いプールの20%を超える場合の警告です。100,000 QUの手数料に満たない価値の削除、および価値が200,000 QU未満の預け入れは、意図的に拒否されます。未検証の項目:実際の追加・削除トランザクション、および接続したウォレットでの署名フロー(署名拒否、ティック失効、シェア移動拒否)。利用前に、流動性の高いプール(GARTHまたはCFB)で少額の預け入れと削除を実際に1回ずつ行ってください。
- **追加時にトークンの端数が気付かれないまま渡される可能性があります。**添付したQUの額によって預け入れ額が制限される場合、コントラクトはその全額を受け取り、切り捨てたトークン数を適用しますが、
- アラート(Discordの
/alerts、src/alerts.ts、bot/alerts.ts):価格の到達、独自のフィルターに基づく裁定機会(サブスクリプションの一部)、大口取引(テープから取得)を通知します。既存の見積もり・ウォレット署名フローを開く、ワンタップのBuy/Sellボタン付きのダイレクトメッセージとして配信されます。価格ルールは、設定した水準を超えている間ずっと毎分通知するのではなく、その水準を超えた瞬間にクールダウン付きで発火します。DMを閉じている場合は、理由とResumeボタンを表示してアラートをオフにします。 - ホスト型MCPサーバー(
https://qmax.exchange/api/mcp、src/mcphost.ts):MCPのストリーミング可能なHTTPトランスポートで同じツールを提供するため、アシスタントは何もダウンロードしたり実行したりせずに接続できます(claude mcp add --transport http qmax https://qmax.exchange/api/mcp)。ステートレスで無料、キー不要です。有料のMaxプランも不要ですが、その費用はx402を通じて呼び出し元自身のウォレットが支払います。ツールは、呼び出し元のアドレスを指定したループバックアドレスでAPIにアクセスするため、直接呼び出す場合と同様にアドレスごとの無料利用制限が適用されます。MCP呼び出し自体は、アドレスあたり毎分120回に制限されます。MCP_HOSTED=offを設定すると提供を停止します。 - 自分で実行するMCPサーバー(
mcp/、mcp/README.mdを参照):上記の機能をAIエージェント向けのツールとして提供します。すべて読み取り専用で、qmax_build_planは呼び出し元自身のウォレット向けの未署名トランザクションを返します。x402による任意の支払いは、自分でシードを設定しない限りオフで、上限が設けられています。
節約の明細(ルーティングの価値)
src/savings.ts は、各見積もりのルートを、それぞれの市場と個別に比較します。見積もりにすでに含まれている単一市場の価格(alternatives)を使うため、この数値は別のサイトについての推測ではなく、見積もりに基づく計算です。取引チケットには、各市場の合計額とともに、「QX と QSwap に分割すると、最良の単一市場と比べて N QU(x%)節約できます」と表示されます(1 つの市場が勝る場合は、もう一方の市場を使うといくらかかったかが表示されます)。取引後の明細には、署名前に提示された価格で同じ節約額が実測値として表示され、実際の結果と並んで「明細をコピー」の行が表示されます。このブラウザーではウォレットごとに(Discord ボットのストアではユーザーごとに)累計が記録され、ウォレットメニューに表示されます。集計されるのは保守的な数値(分割取引で最良の単一市場と比べた節約額。部分約定の場合は約定割合に応じて減額)のみで、より不利な市場と比べた節約額は含まれません。また、取引で何も動かなかった場合は加算されません。
使用状況の追跡(QMax 経由で取引した人)
ウォレットが注文に署名し、アプリがネットワークに送信するため、QMax にもそのことを知らせる必要があります。2 つの方法を併用します。**注文は QMax 経由で送信されます:**ページ(Discord ボットや、SDK を使うエージェントも同様)は、署名済みの注文を POST /v1/broadcast に送信します。これは QX または QSwap の注文、スワップ、流動性の変更であることを確認し(それ以外は中継されません:src/relayable.ts)、指定されたウォレットによる署名であることを確認したうえで、変更を加えずに Qubic ノードへ渡し、集計用にトランザクション ID を記録します(src/relay.ts)。送信された時点で集計されるため、注文が確定する前にページを閉じても集計されます。また、QMax は自ら中継したものだけを集計するため、他人の注文を自分のものとして申告することはできません。QMax が注文を受け付けられない場合(停止中、応答が遅い、または拒否された場合)、送信側は少し待ってからネットワークに直接送信するため、QMax が取引を妨げることはありません。**注文は別途報告もされます:**ステップが確定すると、アプリはトランザクション ID も報告します(POST /v1/trade-report;フックは web/exec/run.ts と web/usage.ts にあります)。これにより、中継を利用できなかった場合にも対応でき、また、中継を導入する前の集計方法も維持されます。どちらの場合も、src/usage.ts は集計前に すべての ID をアーカイブと照合します。トランザクションは、そのウォレットから QX または QSwap に送信され、買い、売り、スワップ、または流動性の変更であり、30 分以内に報告されている必要があります(古い履歴を後から追加できないようにするためです)。また、約定済みである(コントラクト自身のイベントログから資産、数量、QU を取得できます)か、QX の注文板に残っている注文である必要があります(後者は未約定注文として別に集計し、注文価格での価値を記録します。資産、サイズ、価格は注文自身の入力から読み取ります)。コントラクトが買い注文の QU をそのまま返した場合、その注文は除外されます。拒否されたスワップや他人のウォレットも除外され、その理由は集計されます。不正な形式の ID は即座に拒否されます。アーカイブに存在しない ID は 15 分間再試行されます(実在する ID なら通常 1 分ほどでインデックスに登録されます)。イベントの反映が遅れている場合やアーカイブが停止している場合は、最大 2 時間再試行されます。1 つの IP アドレスで待機できる ID は最大 100 件です。また、報告と中継にはレート制限があります(QMax 自身のキーとボットのキーは対象外です)。そのため、単一の呼び出し元がキューを埋めたり、中継を使ってノードに大量のリクエストを送ったりすることはできません。
- 確認方法:所有者のキーを使って
GET /v1/stats?days=30を呼び出します(x-api-key: $ADMIN_KEY。別のADMIN_KEYが設定されていない場合は$API_KEYを使用します。どちらも設定されていなければ、誰も読み取れません)。日別、ref別(パートナーのリンクタグ、またはdirect)、チャネル別、取引所別の合計、上位の資産、出来高上位 20 件のウォレット、検証件数が返されます。合計には、注文数(orders:約定した注文とスワップに加えて、QX で未約定のまま残っている注文も含む)、取引数(trades:約定したもの)、未約定注文数とその価値(restingとrestingQu。約定していない注文と注文価格での価値であり、取引量ではありません)、ウォレット数、約定時の QU 取引量、新規ウォレット数、流動性操作が含まれます。GET /v1/stats?wallet=IDでは、指定した 1 つのウォレットの取引と支払いが一覧表示されます。データは.cache/usage.jsonに保存され、sinceは集計開始時期を示します。 - **売上の報告は不要です。**QPayhub はコントラクトであるため、QMax のアドレスへの支払いはすべてオンチェーンに記録されます。数分おきに
scanPaymentsがPay呼び出しを読み取り、QMax のアドレス宛てのものを保存して、それぞれの用途(リソース ID:QMAXPASSはパス、QMAXSUBは Discord サブスクリプション、QMAXAPIは API のチャージ、その他の x402 セッションなどはother)を記録します。支払いが集計されるのは、QPayhub が QMax に転送した場合に限られます(拒否された支払いもトランザクションとしては確定しますが、資金は返金されます)。そのため、イベントログの転送記録が証拠となり、拒否された支払いは別に集計されます。実際のチェーンで確認したところ、これまでにスキャンで見つかった Discord サブスクリプションは 1 件です。 - **証明できることと、できないこと。**QMax が中継した注文は、QMax 経由で送信されたことが確認できます(QMax はその注文を通過時に確認しています)。以前からある報告経由の方法は、証明力がより弱いものです。そのウォレットがその取引を行ったことは証明できますが、QMax 経由であったことは証明できません(誰でも、どのウォレットの実在する直近の取引でも指定できるためです)。また、オンチェーンにはマーカーが存在しません(マーカーを付けるための取引ごとの手数料がないため)。したがって、注文数は QMax が送信した注文と、QMax に報告された注文を合わせた数です。未約定注文は発注時に 1 回だけ集計されます。後で約定しても再集計されません(約定はコントラクトによるもので、ウォレットが送信したトランザクションではありません)。売り注文では返金するものがないため、コントラクトへの登録後に拒否された売り注文(アプリが先に保有数を確認するため、まれです)も発注済みとして集計されます。プライバシー設定をオフにした人、または Discord で
/privacy count:falseを設定した人は集計されません。これは測定された使用状況として扱い、誰かへの支払いの根拠とはしないでください。 - **注文の種類ごとの集計方法。**ウェブサイトは
webとして集計されます(リンクのパートナーrefも記録されます)。Discord ボットはdiscordとして集計されます。ボットは独自のキーを使って各注文を QMax 経由で送信し、確定した注文を報告します。各ユーザーは/privacy count:falseでいつでも無効にできます(ユーザーごとに保存され、ウォレット単位で適用されます。注文プレビューには注文が集計されることが表示されます)。SDK のagentTradeを使うエージェントはagentとして集計され、既定では QMax 経由で送信します。ネットワークに直接送信するにはreportTo: falseを指定します。Discord サブスクリプション、パス、API のチャージは、別途チェーンから集計されます(下記を参照)。 - **プライバシー。**報告には、ウォレットアドレスとトランザクション ID が含まれます。どちらもネットワーク上で公開されています。確認ダイアログにはその旨が 1 行で記載され、設定には、すべての報告を停止して注文をネットワークに直接送信するスイッチ(プライバシー:QMax に注文の集計を許可する)があります。サーバーで
TRADE_USAGE=offを設定すると集計を停止し、ORDER_RELAY=offを設定すると注文の中継を停止します(注文はネットワークに直接送信され、報告だけをもとに集計されます)。 - 自分で確認するには:
npm run usage-checkを実行すると、実際の直近の取引をアーカイブと照合し、他人のウォレットと遅れて届いた報告が拒否されることを示し、実際の QPayhub 履歴を使って支払いをスキャンします。
資産を売却したのは誰か(Sellers タブ)
各資産の取引セクションの下にある Sellers タブ(web/SellersView.tsx、GET /v1/sellers?asset=ID、src/sellers.ts)では、過去7日間にQXまたはQSwapでその資産を売却した人、保有期間、購入価格、そして売却価格がそれを上回ったか下回ったかを確認できます。公開アーカイブからデータを読み取ります。アーカイブの持分移動イベントは資産で絞り込めるため、1回のクエリで1つの資産について1週間分(QDOGEの場合は689件といった数百件)の、誰が誰に何を送ったかというイベントを取得できます。送信数が最も多い人(デフォルトでは12人。QDOGEの場合は8人で、送信された単位数のおよそ58%を占めます)について、それぞれの取引台帳(Portfolioが使用するものと同じ台帳で、過去1年分)を読み取り、各売却を、その元となった購入または移転に先入れ先出しで対応付けます。これにより、売却ごとに、単位の保有期間(過去7日以内に購入、8~30日前、1~3か月前、3~12か月前、1年以上前)、購入価格(手数料込み)、売却結果のほか、移転で受け取った単位(分配、エアドロップ、別のウォレットからの移動など、記録上の取得原価がないもの)を確認できます。売却せずに別のウォレットへ送られた単位は、売却ではなく移動として表示されます。同じ週に売却した数とほぼ同数の単位を受け取った売り手には、往復取引(ボット、マーケットメーカー、または単位の中継)としてフラグが付けられます。保有していた単位のほぼすべてを売却した売り手には、売却済みとしてフラグが付けられます。
このページでは、数字が示す内容を平易な文章(「数字が示すこと」)で説明し、動機を断定することはありません。チェーンから分かるのは、誰が何を売り、いくら支払ったかであり、なぜ売ったかではありません。読み取りには1~2分かかります(ウォレットごとにアーカイブへのリクエストがおよそ20回、毎秒2回のペースで実行されます)。そのため、資産への最初のリクエストには、進捗状況とその時点で判明している数値とともにstatus: "working"が返され、ページは4秒ごとに再度リクエストします。読み取りが完了すると、その結果は6時間保持されます。ほかの用途に使えるアーカイブの余力を確保するため、読み取りは一度に1件まで、1時間あたりの新規読み取りは最大12件です。読み取れないウォレットはスキップされ(読み取り可能なウォレットが1つもない場合にのみエラーとなります)、最も利用の多い5つの資産は6時間ごとに先読みされます(SELLERS_WARM=offで先読みを停止し、SELLERS=offでこの機能を停止します)。アシスタントではqmax_get_sellersツールとQMaxClient.sellersから利用できます。
トークンページ(すべての資産にページを用意)
GET /token/<id>(src/tokenpages.ts)は、一覧にあるすべての資産について、1つのテンプレートとAPIがすでに提供しているリアルタイムデータを使ったプレーンHTMLページです。価格(およびドル換算額)、24時間と7日間の変動率と取引高、QXの最良買値と最良売値、QSwapのプールに加え、現在の価格で約10 million、100 million、1 billion QU相当の3つのサイズを売買した場合に得られる額を表示します。見積もりは、両方の市場を1回読み取ったデータを使い、ルーターが算出します(buildQuotes)。GET /token/には、取引高の多い順に一覧が表示されます。各ページにスクリプトはなく、独自の厳格なポリシーを適用して配信されるため、検索エンジンやAIアシスタントがそのまま読み取れます。サイズごとの価格見積もりでは市場を読み取るため、訪問回数にかかわらず、資産ごとに10分に1回、同時に1件だけ実行されます。クローラーがすべてのページを巡回しても、APIがページごとにノードを読み取ることはありません。
検索エンジンに提供される内容。 過去7日間に取引された資産だけがindexの対象となり、GET /sitemap-tokens.xmlに掲載されます(lastmodは最終取引日です)。取引のない資産にも利用者向けのページは用意されますが、noindexが設定されるため、取引のないトークンが多数あっても、内容の薄いページでインデックスが埋まることはありません。取引が始まったり止まったりすると、自動で掲載・除外されます。スマートコントラクトのシェアにも同じルールが適用されます。同じシンボルを共有する2つの資産には、IDを使った別々のページが作成されます(TWINとTWIN.BBBBB)。アドレスの別表記(大文字と小文字の違い、末尾のスラッシュ)は、301で正規のアドレスに転送されます。不明な資産には404を返します。ネットワークの初回スキャンがまだ実行中の場合、ページは404ではなくRetry-Afterを付けて503を返すため、クローラーはそのページが存在しないと判断せずに再訪します。TOKEN_PAGES=offにすると、これらのページの配信が停止します。
nginxは/token/、/token、/sitemap-tokens.xmlをAPIに転送します(deploy/nginx-tokens.shは稼働中のファイルを一度だけ修正し、新規インストール用のdeploy/nginx-qmax.confには同じ場所の設定が含まれています)。robots.txtには2つ目のサイトマップが記載されています。
購読者と利益分配
購読者はチェーン上でウォレットごとに追跡されます。 Discord の購読は、購読者自身のウォレットが署名する、QMax のアドレス宛ての QPayhub 決済です。レシートのリソース ID には Discord ユーザー ID(QMAXSUB)が含まれます。そのため、支払元ウォレットはオンチェーンに記録され、紐付けやログインをしなくても、ウェブサイトは同じウォレットを認識します。GET /v1/membership?wallet=ID(公開、任意のウォレットを照会可能、独自のレート制限あり)では、そのウォレットが有効なメンバーかどうか(購読期間は各決済から BOT_SUB_DAYS 日間で、ボットと同じく延長されます。パスは24時間です)、有効期限、および獲得額を確認できます(どの Discord アカウントの分を支払ったかを確認できるのは所有者のみです:GET /v1/subscribers)。決済したばかりのメンバーはすぐに反映されます。照会時に、5分ごとのスキャンを待たず、そのウォレット自身の決済を読み取るためです。現在、取引は誰でも無料で利用できるため、メンバーシップによってウェブサイト上で利用可能になる機能はありません。ウォレットメニューには、接続中のウォレットのメンバーシップ(および利益分配)が表示されます。決済したウォレットである必要があります。別のウォレットから支払われた購読は、そのウォレットに属します。
- 分配対象。 UTC の暦月ごとに期間を設定します。分配プールは、その月の純収入、つまり QPayhub が QMax のアドレスに送金した金額の
PROFIT_SHARE_PCT(75)%です。他の機能がすべて無料である現在、これは Discord の購読料です(該当するモードが有効な場合は、PROFIT_SHARE_INCOMEによってパス、API のチャージ、x402 セッションを追加できます。アドレスに送られたその他の金額はカウントされません)。プールは、その月に各購読者が支払った金額に比例して(QPayhub の手数料を差し引いた額を基準に)、厳密な整数演算で切り捨てて分配されます。また、どのウォレットも支払額のPROFIT_SHARE_CAP(1)倍を超えて獲得することはありません。この上限によって公平性が保たれます。分配額は各ウォレット自身の決済額に基づくため、1件の購読を複数のウォレットに分けても利益はなく、支払額を超える返金が行われることもありません。上限と丸めによって分配されずに残った金額は QMax に留まります。QMax 自身のアドレスとPROFIT_SHARE_EXCLUDEに指定されたウォレット(テスト用ウォレット)は、すべて対象外です。プログラムはPROFIT_SHARE_START(最初に有効化された月)から計上します。期間が終了し、決済スキャンがその終了時点を過ぎて読み取った場合にのみ、その月の分配額が確定します。 - 確認方法(所有者のキー、
x-api-key: $ADMIN_KEY、または専用のキーがない場合は$API_KEY):GET /v1/subscribers(これまでに購読した全員:Discord ID、有効期限、支払額、獲得額、支払済み額、未払い額)、GET /v1/profit-share?period=2026-10(種類別の収入、プール、各ウォレットの分配比率、分配額、上限と獲得額、警告)、GET /v1/profit-share/balances。実際のチェーンで現在確認できているのは、Discord の購読者1人(1,810,000 QU、QPayhub の送金額は1,796,425 QU)です。そのため、10月のプールは1,347,318 QUで、そのウォレットの推定分配額は全額です(上限の1,810,000 QU未満)。それが自分のテスト用ウォレットの場合は、PROFIT_SHARE_EXCLUDEに追加してください。 - 支払い:署名するのはあなたで、QMax がキーを保管することはありません。
npm run payoutは未払い額と支払いに使用するトランザクションを表示しますが、署名は行いません。npm run payout -- --sendは QMax のアドレスのシードを求めます(入力内容は非表示なので、シェルの履歴やプロセス一覧には残りません。ファイルやチャットには絶対に記録しないでください。QMAX_PAYOUT_SEEDも使用でき、read -sで設定します)。支払い計画を確認し、QMax のアドレスと一致しないシードや、支払いに必要な残高がないウォレットを拒否した後、合計額の入力を求めて、各バッチに署名し送信します。1つのバッチは、最大25個のウォレットに支払う1件の QUtilSendToManyV1トランザクション(コントラクト4、プロシージャ1)です。添付する QU は、各支払い額と QUtil の手数料の合計に正確に一致する必要があります(10 QU。毎回コントラクトから読み取られ、焼却されます)。一致しない場合、QUtil はすべてを返金します。署名処理では、署名前にバイト列と一覧にあるウォレットおよび支払い額を再確認し(checkBatchView)、計画の概要ではなく、バッチ自体から表示額、必要資金、確認内容を集計します。また、同じウォレットに2つのバッチで支払う計画、QMax 自身のアドレスへの支払い、未払い額を超える支払いも拒否します(checkPlan)。台帳(.cache/profitshare.json。直前の保存内容は.bakとして保持されます)は、バッチを予約した時点、またはそのトランザクションが報告された時点でディスクに書き込まれます。台帳が存在するのに読み取れない場合、過去の支払いを全員分もう一度計画してしまうことがないよう、利益分配はメッセージを表示して自動的に無効になります。送信済みバッチを放棄するのは、署名から1時間経過した後にアーカイブ自体が処理済みで、トランザクションが見つからない場合に限られます(アーカイブが遅れている場合やエラーが発生した場合は、ウォレットの予約を解除しません)。後からトランザクションが見つかった場合も、支払いとして計上されます。PROFIT_SHARE_MIN_PAYOUT_QU未満の残高は、次回の支払いまで保留されます。 - 支払済みかどうかはチェーンが決定します。 バッチは準備済み(計画段階で、再度要求すると問題なく置き換えられます)、送信済み(署名中、またはトランザクションが見つかった状態で、対象ウォレットは再計画できないよう予約されます)、検証済みの順に移行します。検証済みとなるのは、所有者自身の QUtil 宛てトランザクションが、正確にそのペイロードと金額で記録され、QUtil の送金イベントで各ウォレットが一覧の金額どおりに受け取ったことが確認された場合だけです。QMax は、各バッチのバイト列に一致する所有者自身の一括送金トランザクションも検索するため、QMax に知らせずに署名されたバッチや、計画が破棄された後に遅れて署名されたバッチも検出され、計上されます。同じバッチが2回署名された場合はフラグが付けられ、帳簿とチェーン上の記録が一致するよう両方の支払いを計上します。返金されたトランザクション(手数料の誤り)は計上されず、対象ウォレットの予約は解除されます。翌月に再び未払いとなる同じ明細は新しいバッチとなり、時刻に基づいてそのバッチ固有のトランザクションと照合されます。
- 制限事項について。 これまで実際の支払いに署名したことはありません。ここに記載した内容はすべて、偽のチェーンでのテストと実際のチェーンに対する読み取り専用の確認によるものです(実際の QUtil 一括送金を調査してデータ構造と送金イベントを確認しました。ライブで読み取った手数料は10 QUです)。ウェブサイトが認識するメンバーシップはチェーン上の情報に基づくため、ボットの記録とは数秒ずれることがあります(ボットは確認した時点から期間を延長します)。Discord ID とウォレットはオンチェーンで公開されます(決済のリソース ID に Discord ID が含まれます)が、公開メンバーシップ照会ではそれらを開示しません。支払いを行った顧客への手数料収入の分配は、あなたや顧客がいる地域によって、証券や税務上の影響が生じる可能性があります。「利益分配」ではなく手数料の払い戻しとして告知する場合も含め、告知する前に確認してください。
エンドポイントの追加
機能は、サーバーを編集せずに独自のエンドポイントを追加できます。src/routes.ts で Route(method、path、limited、doc、handler)を定義し、createApi に routes: Route[] を渡すと、組み込みのエンドポイントと並べて提供されます(ほかのマーケットエンドポイントと同様にレート制限が適用され、limited: false でない限り、同様に x402 セッションによる支払いが必要です)。各 doc は /v1/openapi.json に統合されます。ハンドラーは JSON を返すか、ダウンロードの場合は new Raw(body, contentType, filename) を返し、リクエストを拒否する場合は RouteError(status, message) をスローします。Web 機能のスタイルは web/styles/*.css に配置します(自動的に読み込まれます)。
エージェントに見つけてもらう(および検索)
MCP サーバーと SDK は、サイトの /agents/ 配下でホストされています(ガイドページ、qmax-mcp.mjs、qmax-sdk.tgz、qmax-sdk.js、SHA256SUMS)。npm run agents:build(scripts/build-agents.mjs)は、それらを web/public/agents/ にビルドします(MCP ファイルのデフォルトアドレスには稼働中の API を設定し、SDK をパッケージ化し、プランナー用の型宣言をプランの形状に絞り込み、チェックサムを生成します)。デプロイでは、サイトのビルド前にこの処理を実行します。/llms.txt とサイトマップからそれらにリンクしています。
ダウンロードの検証
SHA256SUMS(/agents/ 配下の各ファイルのハッシュ)には、メンテナー自身の minisign 鍵で署名します。この鍵はメンテナーのコンピューターに保管され、サーバーには置かれません。公開鍵:
RWRMUiy37f8/2tR95zGd1GrgIuOk9ichS/Ohe99rlJrq7Xtd3d+Dfu3c
curl -O https://qmax.exchange/agents/SHA256SUMS
curl -O https://qmax.exchange/agents/SHA256SUMS.minisig
minisign -V -P RWRMUiy37f8/2tR95zGd1GrgIuOk9ichS/Ohe99rlJrq7Xtd3d+Dfu3c -m SHA256SUMS # the list came from the key's owner
shasum -a 256 -c SHA256SUMS # each file matches the list
この README は、信頼する鍵のコピーです。確認対象はウェブサイトなので、サイトだけから鍵を入手しないでください。scripts/sign-release.sh が署名を作成します(デプロイで実行されます)。
web/index.html には、タイトル、説明、正規アドレス、Open Graph と Twitter カード(1200x630 の web/public/brand/og.png)、JSON-LD(WebSite、WebApplication、WebAPI)、/llms.txt と OpenAPI ドキュメントへの <link>、および JavaScript を実行しないクローラー向けの <noscript> の概要が含まれています(アプリ自体はクライアント側でレンダリングされるため、これがないとクローラーには空のページが表示されます)。web/public/robots.txt はクローラーを歓迎し(API のエンドポイントへのアクセスは防ぎますが、OpenAPI ドキュメントへのアクセスは防ぎません)、sitemap.xml には単一のページが記載されています。/llms.txt(src/llms.ts、nginx 経由で配信)は、エージェントが最初に読む Markdown ガイドです。QMax の概要、API のアドレスと主なエンドポイント、無料で使える内容、Max プランの料金、x402 での支払い方法を説明しています。API と同じ設定(PUBLIC_BASE_URL、API_MAX_PRICE_QU、セッション設定)から生成されるため、古い料金が記載されることはありません。OpenAPI ドキュメントでは、API の公開アドレスが servers に記載されているため、クライアントは有効な URL を組み立てられます(PUBLIC_BASE_URL=https://qmax.exchange/api を設定してください。これは、x402 チャレンジが指定する resource.url でもあります)。
エージェント向け:自己署名取引(および任意の x402 セッション)
エージェントは、ほかのユーザーと同様に無料 API を利用できます。ただし、Max プランは 100 QU です(GET /v1/max、QMaxClient.max()、MCP ツール qmax_best_position)。これはプリペイドキーの残高から支払うか、x402 セッション内であれば無料になります。API_MAX_PRICE_QU を設定すると、ほかのすべてが無料のままでも、メーターと x402 ゲートが有効になります。API のその他の部分で x402 セッションを利用できるのは API_ACCESS=billing の場合に限られますが、エージェントが自分で取引に署名する仕組みはそのまま適用されます。
QMax は Q+Pay と同じ x402 ワイヤーフォーマット(qubic-x402:スキーム exact、ネットワーク qubic:mainnet、アセット QUBIC、QPayhub 経由の決済)に従うため、すでに Q+Pay のリソースに支払っているエージェントは、アカウントもキーも必要なく、同じ方法で QMax に支払えます。
- 呼び出しごとの支払いではなく、セッションを使う理由。 分割見積もりは 100 QU、アービトラージ結果は 50 QU ですが、これは QPayhub が受け付ける最小支払額(100 QU)を下回ります。また、最小手数料も 100 QU のため、約 13,334 QU 未満では手数料が支払額を上回ります。さらに、支払いの確認には約 10 秒かかります。そのため、エージェントは一度だけセッションを購入します。
API_SESSION_PRICE_QU(デフォルトは 10,000 QU)でAPI_SESSION_SECONDS(デフォルトは 3,600)利用できます。セッション内では呼び出しごとの料金はかからず、レート制限はキー認証時の制限(無料時の 10 倍)となり、アドレス単位ではなくセッション単位でカウントされます。API_X402=offで無効にできます。また、メーターも有効にする必要があります。 - 利用の流れ。 エージェントが無料利用の制限を超えた場合(または
GET /v1/sessionを呼び出した場合)、価格、QPayhub アドレス、販売者、リソース、チケットを含む402が返されます(GET /v1/x402では402を返さずにオファーを確認できます)。エージェントはQPAYHUB.Payで支払い(ノンスはチケットから取得し、金額は正確に一致させる必要があります)を行い、X-PAYMENTを付けてリクエストを再送します。サーバーは QPayhub のレシートから支払いを取得し、支払者、販売者、リソース、ノンス、金額、経過時間を検証して、各支払いを一度だけカウントし(.cache/x402-used.json)、セッションの残り時間に使える署名済みトークンをX-ACCESS-GRANTで返します。チケットと付与トークンは、.cache/x402-secrets.json(モード 0600)に保存されたシークレット、または設定した場合はX402_TICKET_SECRETとX402_GRANT_SECRETを使って HMAC 署名されます(どちらか 1 つを両方に使うこともできますが、実運用では異なるものを使ってください。チケットのシークレットが漏れると、第三者がチケットを発行できるためです)。トランザクションがまだ確認されていない場合、理由としてinvalid_transaction_stateが返されます。同じヘッダーを付けて、確認されるまで再送してください。 - エージェントは自分の取引に署名します。 QMax はエージェントのキーを保持せず、エージェントに代わって取引することもありません。
@qmax/sdk/agentは見積もりを取得し、エージェントが設定した制限に照らして見積もりを検証し、エージェント自身のシードで署名して各ステップを送信します。maxOutlayQuは必須で、手数料を含めてウォレットから出ていくことが許される QU の最大額です。売却では、売却時の支出は手数料のみのため、minAveragePriceQuも必要です。maxAveragePriceQuとallowedAssetsは任意です。見積もりのヒントは信頼できないものとして扱われます。プランが呼び出せるのは QX と QSwap(および両者の間でのシェア管理の移動)のみで、x402 の支払者が支払えるのは QPayhub のみです。これは402の内容にかかわらず変わりません。制限に抵触するものがあれば、署名は行われず、TradeRefusedに理由が列挙されます。ステップは 1 つずつ送信され、最初の失敗で停止し、その後ウォレットを再確認して結果を報告します。agentPlanはドライランです。同じ見積もり、同じ制限チェック、同じステップを実行しますが、署名も送信も行いません(ウォレットの公開残高を読み取るため、ウォレットで取引を実行できるかどうかも示されます)。1 つのTradeBudget(new TradeBudget(totalQu))をすべてのagentTrade呼び出しに渡すと、同時にいくつ実行しても、エージェントのすべての取引で使用できる合計額に上限を設定できます。各取引はチェックに通ると最悪ケースの支出額を確保し、ウォレットに渡した後もその額を保持します。 - ユーザーへの影響はありません。 ウェブアプリ(ウォレット署名、QMax パス)、Discord ボット(サブスクリプション)、プリペイドキーは、これまでどおり機能します。x402 によってセッションが追加され、無料利用制限を超えた場合の応答が、エージェントが対応できる
402に変わります(従来は429)。 - 試してみる。
npm run agent-demoを実行すると、オファーが表示され、支出は発生しません(稼働中のサイトを指定するにはQMAX_API=https://qmax.exchange/apiを設定してください。デフォルトではローカルサーバーが使われます)。自分のターミナルでQMAX_AGENT_SEEDを設定し、--max QDOGE --yesを実行すると、エージェントの一連の処理が一度に実行されます。Max プランをリクエストすると402が返され、QPayhub 経由で一度だけセッション料金(10,000 QU)を支払い、プランを取得した後、セッション内で再度リクエストするため、追加の支払いは発生しません。--session --yesはセッションを購入するだけです(実行終了時に破棄されます)。--buy CFB 10 --max-outlay 5000 --yesは、制限付きの取引を実行します。支出額の表示は支払いを送信した時点から計上されるため、まだ確認されていない支払いも含まれます。エクスプローラーで確認してください。テストに使ってもよい分だけを保有するウォレットを使い、シードをチャットやファイルに貼り付けないでください。 - 制限事項について。 支払いの有効期間はティック単位で判定されます(1 ティック 0.55 秒。2026 年 10 月にメインネットで測定。ネットワーク速度が変わった場合は
src/x402.tsのTICK_SECONDSを変更してください)。レシートは QPayhub に約 2 エポック保管され、それ以降の再利用防止にはローカルの使用済み支払い台帳を使います。QMax はConsumeを呼び出さず、オンチェーンの USD 価格オラクルも使用しません(セッション価格はウェブパスと同様、QU で固定されています)。未対応の項目:MCP サーバーのラッパー、および検証を Q+Pay ファシリテーターに委任する機能。
他のサイト向け:SDK とリンク
どちらからでも利用できます。詳しくは sdk/README.md をご覧ください。
- SDK(
sdk/、npm run sdk:buildでビルドし、Node またはブラウザーで実行):QMaxClientは API をラップし(見積もり、フィルター付きアービトラージ、キーの作成、チャージと請求)、型付きの応答と、拒否された呼び出しで得られたはずの利益を示すQMaxErrorを提供します。buildExecutionPlanは見積もりをウォレットが署名するトランザクションに変換します(売却時は最初に権利を移動し、その後、会場ごとに 1 回ずつ呼び出します)。そのため、すでに独自のウォレットフローを持つサイトは、それらに署名するだけで済みます。 - 事前入力済みリンク:
?asset=CFB&side=buy&qty=5000&ref=partnerを指定すると、注文が入力された状態で QMax の取引画面が開きます(src/deeplink.tsのbuildDeepLink/parseDeepLink)。リンク内の不正な部分は破棄され、不明なアセットにはメッセージが表示されます。refはPOST /v1/ref(リンクのオープンと、トランザクション ID を含む取引の完了)で記録され、QMax 独自のキーを使ってGET /v1/refsで読み取られます(.cache/refs.json)。レポートはユーザーのブラウザーから送信されるため、どのパートナーがトラフィックを送っているかは分かりますが、何の証明にもなりません。報酬を支払う前に、トランザクション ID をオンチェーンで確認してください。
セキュリティ
2026 年 10 月にプロジェクト全体(ウェブアプリ、API、ボット、SDK/MCP、支払い)のレビューを実施しました。発見事項と対応内容は .cache/security-review/TRACKER.md に記載されています。実行時に知っておくべきこと:
- キーとシークレット。
.envと.cache内のすべてのファイルは所有者のみがアクセスできる状態です(モード 600/700。コードはファイルをそのモードで書き込み、次回保存時に以前のファイルの権限も厳しくします)。長くランダムな値を使用してください。API_KEYとADMIN_KEYにはopenssl rand -hex 24を使用します。ボットが取得するのはAPI_KEYのみです。ADMIN_KEY(サブスクライバー、利益分配、支払い、統計)はサーバー上と、npm run payoutを実行するシェル内に保管します。npm run payout -- --sendを実行すると、支払い用シードは入力時に非表示になります。QMax はシードを一切保存しません。 - API はデフォルトで公開されています。アドレスごとにリクエスト数を制限し(
API_FREE_PER_MIN)、Qubic ノードへのキューに上限を設けています(ノードが混雑している場合は、待機中のリクエストが積み上がるのではなく、Retry-Afterとともに 503 を返します)。悪意ある入力にはクラッシュではなくエラーで応答します。独自のプロキシの背後で使用する場合は、TRUST_PROXY=1(運用しているプロキシの数)を設定してください。設定しない場合、転送元アドレスのヘッダーは無視されます。API はこのマシン上でのみリッスンします(127.0.0.1)。HOST=0.0.0.0にするとネットワークからアクセスできるようになりますが、その場合は独自のプロキシの背後に置いてください。 - ウェブサイトは API に資金の安全性を委ねません。 署名の前に、見積もりのトランザクションが依頼内容と一致すること(同じアセット、発行者、売買方向、数量であること。QX と QSwap のみであること。上限が指定したスリッページより緩くないこと。コントラクトの実際の手数料であること)を確認します。確認ダイアログには、ウォレットから出ていく可能性がある最大額が表示されます。厳格なコンテンツセキュリティポリシーとセキュリティヘッダーも設定されています(
vite.config.ts、web/public/_headers)。 - エージェントとボットは、同じプランチェック(
prepareTrade)を実行します。エージェントの取引ではTradeBudgetを共有できます。ボットは Discord ユーザーごとの 1 分あたりの操作を制限し、誰かにメンションを送ることはなく、ログからペアリングリンクを削除します。 - アセット名は、チェーンから取得したもののうち、通常の英字と数字のみ(最大 7 文字)の場合に限って表示されるため、悪意ある発行者がサイト、ボット、API にマークアップや紛らわしい文字を埋め込むことはできません。
- 対象外の事項: 署名に使用するウォレットの保護は、利用者自身の責任です。QMax はトークンのオンチェーン価格を検証しません(流動性の低い板は価格を動かせます。ヘルスグレードと確認ダイアログで、可能な範囲を示します)。
npm auditでは、このアプリが使用しない MetaMask snap ライブラリの依存関係に中程度の問題が報告されています。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。