LogoLogo
ston-fi/docs
ston-fi/docs
  • User section
    • About
    • STON.fi Protocol
    • Fees
    • Glossary
    • Procedure for Adding Tokens to the Default List
    • Whitepaper
  • Developer section
    • Architecture
    • SDK
      • DEX v1 guide
        • reference
        • swap
        • provide liquidity
        • refund liquidity
        • burn liquidity tokens
      • DEX v2 guide
        • swap
        • provide liquidity
        • refund liquidity
        • burn liquidity tokens
        • withdraw fee from vault
      • Farm guide
        • stake in farm
        • claim farm rewards
        • unstake from farm
        • destroy farm NFT
      • Transaction sending guide
        • via ton
        • via tonweb
        • via tonconnect
      • v0.5 > v1.0.0 migration guide
      • v0.5 (deprecated)
        • DEX guide
          • swap
          • provide liquidity
          • refund liquidity
          • burn liquidity tokens
        • Farm guide
          • stake in farm
          • claim farm rewards
          • unstake from farm
          • destroy farm NFT
        • Transaction sending guide
          • via ton
          • via tonweb
          • via tonconnect
      • v0.4 > v0.5 migration guide
      • v0.4 (deprecated)
        • perform a swap operation
        • provide liquidity
        • refund liquidity
        • burn liquidity tokens
        • using get methods
        • create a custom router revision
    • API reference v1
      • Router
      • Pool
      • LpAccount
      • LpWallet
    • API reference v2
      • Router
      • Pool
      • LpAccount
      • LpWallet
      • Vault
      • Swap examples
      • LpProvide examples
      • Vault examples
      • Op Codes
    • DEX API
    • OMNISTON
      • Resolvers (How to become a resolver)
      • Swap overview
      • Swap extra
      • Swap grpc
      • React
      • Nodejs
      • Referral fees
    • Quickstart Guides
      • Swap Guide
      • Omniston Guide
  • Help
    • Contact Us
Powered by GitBook
On this page
  • Overview
  • Registration Process
  • Step 1: Generate Keys
  • Step 2: Prepare Metadata
  • Step 3: Submit Registration
  • Connecting to the API
  • Authentication
  • Message Flow
  • 1. Incoming Events
  • 2. Outgoing Requests
  • Quote Flow
  • 1. Receiving Quote Requests
  • 2. Providing Quotes
  • 3. Quote Lifecycle
  • Best Practices
  • API Endpoints
  • See Also
Export as PDF
  1. Developer section
  2. OMNISTON

Resolvers (How to become a resolver)

PreviousOMNISTONNextSwap overview

Last updated 1 month ago

This guide explains how to become a resolver (Market Maker) in the Omniston protocol and integrate with its gRPC API.

Overview

A resolver is a service that provides token exchange rates and executes trades. To become a resolver, you need to:

  1. Register by obtaining a Soul-Bound Token (SBT)

  2. Connect to the gRPC API

  3. Handle quote requests and trades

Registration Process

Step 1: Generate Keys

First, generate one or more Ed25519 key pairs that will be used for authentication:

For other languages, you can use any standard Ed25519 implementation library available in your preferred programming language

Step 2: Prepare Metadata

Create a JSON document containing:

  • Your resolver name

  • Your public key(s)

Example:

{
  "name": "MyResolver",
  "publicKeys": [
    "b951254b184fae6906a61ab01e37296fbb28961494cacf7befac9f638fcfe40c",
    "9397ddd52a0d6033da4a32e654b4afbddcc5d832575e396c0a6f5b213faa199f"
  ]
}

Step 3: Submit Registration

  1. Your metadata will be stored in an SBT NFT collection

  2. You'll receive your SBT stake address for API authentication

Connecting to the API

Authentication

  1. Create a connection payload:

message ConnectPayload {
  uint64 connect_timestamp = 1;  // Current timestamp in milliseconds
  string stake_address = 2;      // Your SBT stake address
}
  1. Sign the payload:

  • Serialize the ConnectPayload to bytes

  • Sign using your Ed25519 private key

  • Base64 encode the signature

  1. Send a ConnectRequest:

message ConnectRequest {
  bytes payload = 1;    // Serialized ConnectPayload
  bytes public_key = 2; // Your Ed25519 public key
  bytes signature = 3;  // Signature of the payload
}

Example connection request:

{
  "connect": {
    "payload": "CPKnlt2xYxIwRVFDWFNzMnhaMmRoazlUQXh6R3pYcmEyRWJHX1MyU3F5TjhUZmk2Zko4MkVZaVZq",
    "public_key": "TAPsnPvWhlOvxEK19rONv4sueMeQzOzlrrIFUOKsi34=",
    "signature": "us7nMd9wmUOkuPk0otg6dvUojZwj8VcyXU6HD13BDQhVrzV8sKgyXtKze+9+j9FC1Ghxkx7Jo5FIDeE8ljbADQjyp5bdsWMSMEVRQ1hTczJ4WjJkaGs5VEF4ekd6WHJhMkViR19TMlNxeU44VGZpNmZKODJFWWlWag=="
  },
  "seqno": 1
}

Message Flow

The resolver API uses a bidirectional gRPC stream. After connecting:

1. Incoming Events

You'll receive these events from the server:

message ResolverEvent {
  oneof mux {
    uint64 seqno = 1;    // Server-generated event ID
    uint64 reply_to = 2;  // References your request seqno
  }

  oneof event {
    QuoteRequestedEvent quote_requested = 10;
    QuoteRequestCancelledEvent quote_request_cancelled = 11;
    QuoteAcceptedEvent quote_accepted = 20;
    QuoteRejectedEvent quote_rejected = 21;
    QuoteInvalidatedEvent quote_invalidated = 22;
    KeepAlive keep_alive = 100;
  }
}

Key events:

  • QuoteRequestedEvent: New quote request from a trader

  • QuoteRequestCancelledEvent: Trader cancelled their request

  • QuoteAcceptedEvent: Your quote was accepted

  • QuoteRejectedEvent: Your quote was rejected

  • QuoteInvalidatedEvent: Confirmation of quote invalidation

2. Outgoing Requests

You can send these requests to the server:

message ResolverRequest {
  oneof mux {
    uint64 seqno = 1;    // Your request ID
    uint64 reply_to = 2;  // References server event seqno
  }

  oneof request {
    ConnectRequest connect = 10;
    UpdateQuoteRequest update_quote = 11;
    InvalidateQuoteRequest invalidate_quote = 12;
  }
}

Key requests:

  • UpdateQuoteRequest: Provide or update a quote

  • InvalidateQuoteRequest: Cancel a previously provided quote

Quote Flow

1. Receiving Quote Requests

When you receive a QuoteRequestedEvent:

message QuoteRequestedEvent {
  string rfq_id = 1;                      // Quote request ID
  QuoteRequest quote_request = 2;         // The actual request
  uint32 protocol_fee_bps = 3;           // Protocol fee in basis points
  sint64 request_timestamp = 4;          // When request was made
  sint64 quote_validity_timeout = 5;     // How long quote should be valid
  sint64 deposit_settling_delay = 6;     // Min delay before settlement
  sint64 resolve_timeout = 7;            // Max time to complete trade
}

2. Providing Quotes

Respond with an UpdateQuoteRequest:

message UpdateQuoteRequest {
  string rfq_id = 1;                    // From QuoteRequestedEvent
  string offer_units = 2;               // Amount trader pays
  string ask_units = 3;                 // Amount trader receives
  uint64 trade_start_deadline = 4;      // Quote expiration time

  oneof params {
    ResolverSwapParams swap = 20;       // For swap settlement
    ResolverEscrowParams escrow = 21;   // For escrow settlement
    ResolverHtlcParams htlc = 22;       // For HTLC settlement
  }
}

For swap settlement, include route information:

message ResolverSwapParams {
  repeated SwapRoute routes = 1;  // Possible swap paths
}

Important: When specifying the protocol in a SwapChunk, the gRPC API expects it as one of the strings "StonFiV1", "StonFiV2", or "DeDust". Currently, only extra_version = 1 is supported.

3. Quote Lifecycle

  1. You receive QuoteRequestedEvent

  2. You send UpdateQuoteRequest

  3. The server validates your quote and responds with:

    • QuoteAcceptedEvent: Your quote was validated and accepted, includes quote_id.

    • QuoteRejectedEvent: Your quote was rejected. The event includes a code field from the QuoteRejectedCode enum. Possible reasons include:

      • UNDEFINED (0) - Uncategorized error

      • INVALID_PARAMETERS (1) - Invalid value of a parameter

      • INVALID_AMOUNTS (2) - Asset amount restrictions don't pass RFQ requirements

      • ROUTE_PROHIBITED (3) - Route uses a prohibited intermediate asset

      • POOL_PROHIBITED (4) - Route uses a unverified or prohibited liquidity pool

      • EMULATION_RESULT_MISMATCH (5) - Transaction emulation produced a result different from the quote

      • INTERNAL_ERROR (101) - Server errors

  4. At any time, you can:

    • Send new UpdateQuoteRequest to update the quote

    • Send InvalidateQuoteRequest to cancel the quote

Best Practices

  1. Sequence Numbers

    • Use monotonically increasing seqno for your requests

    • Match reply_to with event seqno when responding

    • Track request/response correlation using seqno

  2. Quote Management

    • Honor your quotes until trade_start_deadline

    • Invalidate quotes you can't fulfill

    • Include all fees in your quoted amounts

  3. Error Handling

    • Reconnect on connection loss

    • Handle all event types

    • Log rejected quotes for monitoring

  4. Performance

    • Maintain a single gRPC connection

    • Process events asynchronously

    • Buffer outgoing requests

API Endpoints

Production:

  • gRPC: https://omni-grpc.ston.fi

Sandbox:

  • Demo site: https://omniston-sandbox.ston.fi/

  • WS API: wss://omni-ws-sandbox.ston.fi

  • gRPC API: https://omni-grpc-sandbox.ston.fi

See Also

JavaScript implementation
Rust implementation
Link to google form
Swap Protocol Documentation