本文へ移動
ORBITRAONE

開発者ドキュメント

最初の呼び出しから、ファイナライズされた状態まで。

NexusSDK、NexusWASMコントラクト、ノード運用ツールのためのガイド、概念解説、サンプルコード。サンプルはあくまで説明用で、認証情報は環境変数から読み込み、SDK利用権限とともに発行されるサンドボックス環境で動作するように設計されています。

はじめに

概要

NexusSDKが提供する機能と、すべてのサービスが従う規則。

NexusSDKは、ORBITRA ONE™への開発者向けインターフェースです。市場、ID、資産、エージェントの基本機能を型付きサービスとして提供し、その裏側はOrbitra Primeを動かしOrbitra L1上で決済を行う、同じネイティブモジュールが支えています。

サービス

  • 市場APIApexMatch上での注文、オーダーブック、RFQ、クリアリング差分。すべての注文にAegisの事前リスク確認が適用されます。
  • Asset Studio:発行者権限、ライフサイクルイベント、適格性の管理を備えた、トークン化資産の発行と管理。
  • エージェントIDCortexポリシーに紐づけられた、責任を追跡できるIDとして登録されるAIエージェントとボット。
  • データ交換:検証可能な出所を備えたデータセットとシグナルの公開およびライセンス提供。
  • VaultID:本人確認書類を扱うことなく行う、適格性と権限の認証情報の確認。
  • 決済:取引と同じ決定論的ファイナリティの上で行う、支払いリクエストと決済処理。

設計の原則

  • すべての呼び出しは、明示的かつ範囲を限定された権限を持つIDによって行われます。
  • すべての状態変更は、独立して検証可能な署名付きレシートを返します。
  • クライアント側で設定した上限は、プロトコル側でも再度適用されます。
  • 認証情報とエンドポイントは環境変数から取得し、ソースコードに含めることはありません。

はじめに

クイックスタート

SDKをインストールし、環境変数から認証情報を設定して、最初の認証付き呼び出しを行います。

これらのサンプルにおけるパッケージ名およびクレート名は、説明用の命名パターンに従っています。実際に公開されるパッケージ名、サンドボックスの認証情報、エンドポイントはSDK利用権限とともに発行されます。開発者として関心を登録してください。

インストール

NexusSDKをインストール

# TypeScript and JavaScript
npm install @orbitra/nexus-sdk

# Python
pip install orbitra-nexus

# Rust
cargo add orbitra-nexus

認証情報を設定

SDKは二つの環境変数を読み取ります。両方をソース管理の対象から外し、シークレットマネージャーまたはデプロイ環境から読み込んでください。まずはサンドボックスの認証情報から始めてください。サンドボックスは実際の資産や市場から隔離されています。

  • ORBITRA_API_KEY:SDK利用権限とともに発行される、範囲を限定した認証情報。
  • ORBITRA_ENDPOINT:その認証情報とともに発行される環境のエンドポイント。

環境変数を設定

# Both values are issued with SDK access. Never commit them to a repository.
export ORBITRA_API_KEY="<issued-with-sdk-access>"
export ORBITRA_ENDPOINT="<issued-with-sdk-access>"

最初の呼び出し

現在のアカウントを取得

import { NexusClient } from '@orbitra/nexus-sdk';

const apiKey = process.env.ORBITRA_API_KEY;
const endpoint = process.env.ORBITRA_ENDPOINT;

if (!apiKey || !endpoint) {
  throw new Error('Set ORBITRA_API_KEY and ORBITRA_ENDPOINT before running this example.');
}

const nexus = new NexusClient({ apiKey, endpoint });

const account = await nexus.accounts.current();
console.log(account.id, account.permissions);

レスポンスには、その認証情報の背後にあるアカウントの情報が含まれます。VaultIDの認証情報、このキーに付与された権限、アクセス可能な市場です。権限エラーが返る場合、キー自体は有効であるものの、その操作に対する権限範囲が設定されていないことを意味します。以降のサンプルでは、同じ二つの環境変数を読み取る簡略形のNexusClient.fromEnv()を使用します。

概念

アカウントとVaultID

個人、機関、アプリケーション、エージェントのための、IDと認証情報、範囲を限定した権限。

VaultIDは、IDと適格性、権限のレイヤーです。呼び出し元――個人、機関、アプリケーション、エージェントのいずれであっても――は、認証情報を保持するIDを通じて行動します。アプリケーションは認証情報を確認するだけで、その背後にある文書自体を受け取ることはありません。

IDの種類

  • 個人:オンボーディング時に発行される適格性の認証情報を保持する個人。
  • 機関:サブアカウント、役割、二者承認の規則を備えた組織。
  • アプリケーション:開発者によって登録され、自ら宣言した権限のみを保持するサービス。
  • エージェント:Cortexポリシーに紐づけられ、保有者が取り消せるAIエージェントまたはボット。

範囲を限定したキー

APIキーは、どのサービス、どの市場、どの操作、どの期間かという範囲とともにIDに対して発行されます。環境ごと、アプリケーションごとに別のキーを使用し、不要になったキーは取り消してください。

機能を有効化する前に認証情報を確認

import { NexusClient } from '@orbitra/nexus-sdk';

const nexus = NexusClient.fromEnv();

export async function canTradeOptions(subjectId: string): Promise<boolean> {
  // Returns whether the credential is present and valid, never the data behind it.
  const result = await nexus.vaultid.verify({
    subject: subjectId,
    credential: 'eligibility.options',
  });

  return result.valid;
}

アプリケーション内で適格性確認を再現するために本人確認書類を収集しないでください。代わりに認証情報を要求してください。VaultIDが確認するのは、その認証情報が存在し有効かどうかだけです。

概念

証拠とファイナリティ

レシートに含まれる内容、状態変更がファイナライズされるタイミング、その両方を検証する方法。

状態を変更するすべての呼び出しは、レシートを返します。これは、リクエストに対してネットワークが何を行ったかを示す署名付きの記録であり、受信した時刻、順序付けされた位置、Aegisが下した判断、その結果として何が変化したかが含まれます。

レシートの内容

  • 受信:受付時刻と、リクエストを受け付けたゲートウェイの署名。
  • シーケンス:公正な順序付けによって割り当てられた正規の位置。
  • リスク判定:Aegisの判断。拒否された場合は、超過することになった上限。
  • 結果:状態遷移によって生じた約定、クリアリング差分、コントラクトイベント、または送金。
  • ファイナリティ:状態遷移がファイナライズされた際のQSEクォーラム証明書への参照。

状態遷移は、QSEのクォーラム証明書に含まれた時点でファイナライズされます。待つべき確認の深さは存在しません。証明された時点で、規定された障害モデルの下で状態が再編成されることはありません。

ファイナリティを待ち、証明書を検証

import { NexusClient } from '@orbitra/nexus-sdk';

const nexus = NexusClient.fromEnv();

export async function confirmFinal(transitionId: string): Promise<boolean> {
  // Resolves once a QSE quorum certificate covers the transition.
  const finality = await nexus.finality.wait(transitionId);

  // Checks the certificate signatures locally against the validator set it names.
  const verified = await nexus.finality.verify(finality.certificate);

  return finality.status === 'final' && verified;
}

構築

市場APIとApexMatchの注文

TypeScript、Python、Rustで、クライアント側のポリシーのもとポストオンリーのリミット注文を発注します。

市場APIはApexMatchを直接公開します。注文は署名された意図です。SDKがお使いのキーで署名し、ゲートウェイが署名を検証し、公正な順序付けが位置を割り当て、Aegisの事前リスク確認を経てからオーダーブックに到達します。

クライアント側のポリシーは、第二の防御層を追加します。SDKは署名の前にこれを評価するため、自身が設定した上限を超える注文はプロセスの外に出ることがありません。それでもAegisは、プロトコルのゲートでアカウント単位の上限を適用します。

クライアント側のポリシーのもとでリミット注文を発注

import { NexusClient, definePolicy } from '@orbitra/nexus-sdk';

// fromEnv() reads ORBITRA_API_KEY and ORBITRA_ENDPOINT.
const nexus = NexusClient.fromEnv();

// Evaluated locally before the order is signed.
// Aegis enforces account-level limits again at the protocol gate.
const policy = definePolicy({
  markets: { allow: ['EURUSD'] },
  maxOrderNotional: '50000',
  maxLeverage: 2,
  requirePostOnly: true,
});

const receipt = await nexus.orders.place(
  {
    market: 'EURUSD',
    side: 'buy',
    type: 'limit',
    price: '1.0850',
    size: '10000',
    postOnly: true,
    clientOrderId: 'docs-example-001',
  },
  { policy },
);

console.log(receipt.status, receipt.sequence, receipt.riskVerdict);

注文タイプ

マーケット、リミット、ストップ、ストップリミット、ポストオンリー、リデュースオンリーといった基本タイプはネイティブに対応しています。アドバンスト、アルゴリズム、機関向けの各タイプも同じプリミティブを組み合わせたものです。注文の全体像は約定で説明しています。

これらのサンプルにおける市場の識別子、価格、数量は説明用のものです。APIを通じた市場へのアクセスは、インターフェースと同じ適格性および法域の規則に従います。

構築

リスクとAegisシミュレーション

資本を投入する前に、取引後のポートフォリオとストレスシナリオを試算します。

Aegisは、事前リスクゲートで実行しているものと同じシミュレーションを公開します。想定する注文と、任意のストレスシナリオを送信すると、Aegisは何も発注することなく、予測されるポートフォリオの状態と、その注文が超過することになるポリシーを返します。

発注前にシミュレーション

import { NexusClient } from '@orbitra/nexus-sdk';

const nexus = NexusClient.fromEnv();

// Nothing is submitted: Aegis returns the projected post-trade state.
const simulation = await nexus.risk.simulate({
  orders: [
    { market: 'EURUSD', side: 'buy', type: 'limit', price: '1.0850', size: '10000' },
  ],
  scenarios: ['volatility-shock', 'liquidity-drain'],
});

console.log('margin used', simulation.marginUsed);
console.log('liquidation distance', simulation.liquidationDistance);

for (const breach of simulation.policyBreaches) {
  console.warn(breach.policy, breach.limit, breach.projected);
}

シミュレーションが返す内容

  • 想定する注文後の、証拠金使用額と利用可能な担保の予測。
  • その注文が影響するすべてのポジションについての清算までの余裕。
  • リクエストした各ストレスシナリオの結果。
  • 各ポリシー違反について、その上限と予測値。

シミュレーションは、リクエストの時点におけるポートフォリオの状態を示すものです。市場は変動するため、シミュレーションは同じ値で注文が受け付けられる、または約定することを保証するものではありません。

構築

エージェントとCortexポリシー

エージェントIDを登録し、上限と緊急停止機能を備えた明示的なポリシーに紐づけます。

エージェントは、それ自体が一つのIDです。市場を広く観察することはできますが、行動できるのはCortexポリシーの範囲内に限られます。配分できる資本、負うことのできる損失、利用できるレバレッジ・市場・時間帯、人による確認が必要となる場面、依拠できるデータソースです。

エージェントが提案するすべての意図は、Cortexのループ――観察、推論、提案、試算、承認、実行――を経ます。ポリシーエンジンはそれぞれを承認または拒否し、すべての操作がそのエージェントに帰属するレシートを生成します。

Cortexポリシーの例

{
  "policyVersion": "1",
  "capital": { "maxAllocation": "100000", "asset": "USD" },
  "loss": { "dailyLimit": "2000", "lifetimeLimit": "10000" },
  "leverage": { "ceiling": 3 },
  "markets": { "allow": ["EURUSD", "GBPUSD"], "deny": [] },
  "session": { "hours": "Mon-Fri 07:00-17:00 UTC", "expiresAfter": "P30D" },
  "confirmation": { "requiredAboveNotional": "25000" },
  "dataSources": ["prism:fx-majors", "account:portfolio"],
  "kill": { "onBreach": "revoke-all", "cancelOpenOrders": true }
}

エージェントを登録し、ポリシーを紐づける

import { readFile } from 'node:fs/promises';
import { NexusClient } from '@orbitra/nexus-sdk';

const nexus = NexusClient.fromEnv();

const policy = JSON.parse(await readFile('./policies/fx-hedger.json', 'utf8'));

const agent = await nexus.agents.register({ name: 'fx-hedger', policy });

// At any time, one command revokes every permission the agent holds.
await nexus.agents.kill(agent.id);

エージェントを停止する

緊急停止機能は、一つの命令でエージェントが保持するすべての権限を取り消します。未決済の注文はポリシーの指定に従って取り消され、そのエージェントのキーは以後署名できなくなります。

AI支援による自動化を含め、自動化は失敗したり予期しない挙動をしたりする可能性があります。ポリシーは被害を限定するものであり、リスクそのものを取り除くものではありません。AIと自動取引をご覧ください。

構築

NexusWASMコントラクト

ネイティブな市場プリミティブを呼び出す、ケイパビリティ制約付きのコントラクトをRustで記述します。

NexusWASMのコントラクトはWebAssemblyにコンパイルされ、計測されたサンドボックス内で実行されます。コントラクトは自身のケイパビリティ――呼び出せるプリミティブと、触れられる状態――を宣言し、ランタイムはその宣言の範囲外の呼び出しをすべて拒否します。

ケイパビリティ制約付きのトレジャリーコントラクトの例

use orbitra_nexus_wasm::prelude::*;
use orbitra_nexus_wasm::market::{LimitOrder, MarketId, OrderReceipt, Side};

/// Rebalances a treasury position with post-only limit orders on one market.
/// The capability list is checked at deployment; any other call is rejected at runtime.
#[contract(capabilities = [market::place_order, market::cancel_order, storage::read_write])]
pub struct TreasuryRebalancer {
    market: MarketId,
    max_order_size: Decimal,
}

#[contract_impl]
impl TreasuryRebalancer {
    #[call(owner_only)]
    pub fn rebalance(
        &mut self,
        ctx: &mut Context,
        side: Side,
        price: Decimal,
        size: Decimal,
    ) -> Result<OrderReceipt> {
        ensure!(size <= self.max_order_size, ContractError::SizeAboveLimit);

        let order = LimitOrder::new(self.market.clone(), side, price, size).post_only(true);

        // Native call into ApexMatch. Aegis pre-risk applies to the contract's own account.
        ctx.market().place_order(order)
    }
}

構築

WebAssemblyへコンパイル

rustup target add wasm32-unknown-unknown
cargo build --release --target wasm32-unknown-unknown
  • 計算資源とストレージは明示的に価格付けされているため、コントラクトのコストはその処理内容に応じて決まります。
  • 宣言された状態アクセスにより、独立したコントラクトはVectorLanes上で並列に実行できます。
  • コントラクトからの市場呼び出しは、他の注文と同様に、そのコントラクト自身のアカウントに対するAegisの事前リスク確認を経ます。
  • デプロイ時にはケイパビリティのリストとともにモジュールが送信されます。宣言されていないプリミティブを呼び出すモジュールは拒否されます。

構築

EVM Capsuleへの移行パス

既存のEVMコントラクトを隔離環境で実行し、重要な処理経路をNexusWASMへ移行します。

EVM Capsuleは、Ethereumのバイトコードとツール群のための独立した互換性ドメインです。独自のガスおよびリソース上限を持ち、コア資産へはレート制限されたゲートウェイを通じてのみアクセスし、コアのランタイムに影響を与えることなくサーキットブレーカーで停止できます。

カプセルは互換性の境界であり、コアの実行環境ではありません。ネイティブな市場プリミティブはNexusWASMから呼び出されます。カプセルがコア資産に接続できるのは、管理されたゲートウェイを通じてのみです。

移行の手順

  • 変更せずにデプロイ。既存のコントラクトと使い慣れたツール群が、カプセル内で自身の上限に基づいて計測されながら実行されます。
  • 慎重にブリッジ。エクスポージャーに応じた経路上限を設定したレート制限付きゲートウェイを通じて資産を移動します。
  • 測定。ネイティブな性能や市場アクセスが最も重要となる箇所――通常は注文処理、決済、リスクロジック――を特定します。
  • 移植。ApexMatchとAegisを直接呼び出すNexusWASMコントラクトとしてその処理経路を再実装し、カプセル版は参照用として残します。
  • 検証して廃止。両方のバージョンに同じ入力を再生し、結果が一致した段階で利用者をネイティブなコントラクトへ移行し、カプセル版のデプロイを終了します。

運用

バリデーターとノードツール

リリースを検証し、環境変数からノードを設定し、担当業務を確認します。

運用者はノードクライアントを実行して、ファイナライズされた状態を再生し、アプリケーションに応答し、バリデーターとして認定された後はQSEの下で提案者や委員会の職務を担います。一つのクライアントが各役割に対応し、設定は環境変数から取得され、署名用の鍵はHSMまたはMPCシグナーの中に保持されます。

ノードを検証・設定・確認

# Verify the release before installing it. Release-signing keys are published with operator access.
orbitra-node verify-release ./orbitra-node.tar.gz --signature ./orbitra-node.tar.gz.sig

# Configuration comes from the environment. Keys stay in the HSM or MPC signer.
export ORBITRA_NETWORK="<issued-with-operator-access>"
export ORBITRA_ENDPOINT="<issued-with-operator-access>"
export ORBITRA_SIGNER="hsm"   # or "mpc"

orbitra-node init --network "$ORBITRA_NETWORK" --signer "$ORBITRA_SIGNER"
orbitra-node start

# Inspect assigned duties, quorum participation and service measurements.
orbitra-node status --duties --service

# Rehearse a Q-Switch signature-suite rotation without applying it.
orbitra-node keys rotate --suite next --dry-run

表示されているコマンド名は説明用のものです。運用者向けクライアント、リリース署名鍵、ネットワーク識別子は、運用者権限とともに発行されます。詳しくはバリデーターをご覧ください。

運用の原則

  • インストールまたはアップグレードの前に、すべてのリリース署名を検証してください。
  • 鍵はファイルではなく、シグナーを通じて参照してください。バリデーターの鍵をノードのホスト上に置いてはいけません。
  • 担当業務とサービスの測定値は、独自の監視・アラート体制へエクスポートしてください。
  • 署名スイートのローテーションは、その場限りの鍵の再生成ではなく、Q-Switchのコマンドを通じて行ってください。

運用

変更履歴

リリースノートがどのように公開され、それぞれに何が記録されるか。

リリースノートはNexusSDKの各バージョンに付随し、そのバージョンのドキュメントと並んでこのゲートウェイ内に公開されます。バージョンセレクターには、現在読んでいるエディションが表示されます。

すべてのリリースノートに記録される内容

  • 追加・変更・削除されたインターフェース。新しい形式にはそれぞれ例を示します。
  • 非推奨となった項目、それぞれの代替、移行の手順。
  • Q-Switchを通じて導入される、署名スイートまたは認証情報形式の変更。
  • ノード運用者およびバリデーターに影響するプロトコルパラメーター。
  • 開示調整が完了したセキュリティ修正。

現在お読みのものはプレビュー版です。ここに記載されているインターフェースは設計された仕様として文書化されており、一般提供の開始前に変更される場合があります。変更内容は、それを導入したバージョンのリリースノートに記録されます。