GithubHelp home page GithubHelp logo

standard-relayer-api's Introduction

Standard Relayer API

0x Protocol is an open standard. Because of this, we expect many independent applications to be built that will want to use the protocol. In order to make it easier for anyone to source liquidity that conforms to the 0x order format, relayers can opt-in to implementing a set of standard relayer API endpoints. In doing so, they allow clients of the standard relayer API to access the orders on their orderbook.

Specification Versions

SRA v3

Made to match 0x Protocol v3. See changes from v2.

SRA v2

Made to match 0x Protocol v2

SRA v1

Skipped for naming convention and convenience reasons.

SRA v0

Made to match 0x Protocol v1

General Info

Versioning

The URL that specifies the SRA API endpoint should end in the version. Here are some examples:

HTTP: https://api.relayer.com/sra/v0/, https://api.relayer.com/sra/v2/

Websocket: wss://api.relayer.com/sra/v0/, wss://api.relayer.com/sra/v2/

Schemas

The JSON schemas for the API payloads and responses can be found in @0xproject/json-schemas. Examples of each payload and response can be found in the library's test suite.

npm install @0xproject/json-schemas --save

You can easily validate your API's payloads and responses using the @0xproject/json-schemas package:

import {SchemaValidator, ValidatorResult, schemas} from '@0xproject/json-schemas';

const {relayerApiTokenPairsResponseSchema} = schemas;
const validator = new SchemaValidator();

const tokenPairsResponse = {
    ...
};
const validatorResult: ValidatorResult = validator.validate(tokenPairsResponse, relayerApiTokenPairsResponseSchema);

Asset Data Encoding

As we now support multiple token transfer proxies, the identifier of which proxy to use for the token transfer must be encoded, along with the token information. Each proxy in 0x v2 has a unique identifier. If you're using 0x.js there will be helper methods for this encoding and decoding.

The identifier for the Proxy uses a similar scheme to ABI function selectors.

// ERC20 Proxy ID  0xf47261b0
bytes4(keccak256("ERC20Token(address)"))
// ERC721 Proxy ID 0x02571792
bytes4(keccak256("ERC721Token(address,uint256)"))

Asset data is encoded using ABI encoding.

For example, encoding the ERC20 token contract (address: 0x1dc4c1cefef38a777b15aa20260a54e584b16c48) using the ERC20 Transfer Proxy (id: 0xf47261b0) would be:

0xf47261b00000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48

Encoding the ERC721 token contract (address: 0x371b13d97f4bf77d724e78c16b7dc74099f40e84), token id (id: 99, which hex encoded is 0x63) and the ERC721 Transfer Proxy (id: 0x02571792) would be:

0x02571792000000000000000000000000371b13d97f4bf77d724e78c16b7dc74099f40e840000000000000000000000000000000000000000000000000000000000000063

For more information see the Asset Proxy section of the v2 spec and the Ethereum ABI Spec.

Meta Data in Order Responses

In v2 of the standard relayer API we added the metaData field. It is meant to provide a standard place for relayers to put optional, custom or non-standard fields that may of interest to the consumer of the API.

A good example of such a field is remainingTakerAssetAmount, which is a convenience field that communicates how much of a 0x order is potentially left to be filled. Unlike the other fields in a 0x order, it is not guaranteed to be correct as it is derived from whatever mechanism the implementer (ie. the relayer) is using. While convenient for prototyping and low stakes situations, we recommend validating the value of the field by checking the state of the blockchain yourself, such as by using Order Watcher.

standard-relayer-api's People

Contributors

abandeali1 avatar albrow avatar amaurer avatar bmillman19 avatar dekz avatar fabioberger avatar fragosti avatar liamzebedee avatar logvinovleon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

standard-relayer-api's Issues

How does the update websocket protocol ideally behave?

How does the update websocket protocol ideally behave? And what are a relayer's responsibilities for updates? The documentation is a bit vague at the moment.

Will it send you an update when an order:

is canceled?
is partially filled?
is fully filled?
expires?

I'm assuming all of the above. And how should this scheme be formatted for all of the above scenarios?

{
    "type": "update",
    "channel": "orderbook",
    "requestId": 1,
    "payload": {.....}
}

If it were me, I'd do something like the below to handle the above cases. But the docs only show the type "updated"

"type": "filled",   // Fully filled orders that are no longer available at all

"type": "updated",   // Partially filled or canceled orders

"type": "expired",   // Expired orders that are no longer available

Discussion: SRA for 0x v2

Firstly thanks to all who implement the current SRA endpoints. It's great to have a standard way to discover these off-chain orders for use on-chain. Shared liquidity is something we strongly believe in. It brings new players into the ecosystem like wallets and automated traders.

I want to open the discussion of what features you believe should be added to the new SRA specification. We cannot sit down and accurately predict what is going to happen and how it will be used. So expect to see this SRA specification grow and change over time. We want this to be collaborative rather than descriptive so it's something Relayers want to add, rather than feel forced to add.

I fully expect Relayers to incorporate the SRA endpoint into custom automated trading SDK's for their Relay. The SRA Endpoint will just be one component in a trading SDK.

Some goals for the SRA Endpoint:

  • Allow discovery of orders
  • Allow discovery of token pairs being traded
  • Be efficient in order discovery
  • Satisfy the needs for fee recipients
  • Allow 0x orders to be submitted to the Relayer

Both REST and Websocket specifications are part of the SRA endpoint. Websockets are more efficient than polling.

Some discussion initial points:

  • [1] New order
  • [2] Order Lifecycle updates
  • [3] Partial Order default endpoint
  • [4] Fee recipient list endpoint
  • [5] networkId parameter

New Orders [1]

This is already covered in the current SRA spec in both REST and Websocket. Orders can be fetched via REST and Websocket snapshot. New orders are pushed via the Websocket. The only change here is the new order format schema.

Order Lifecycle updates [2]

This is blockchain state and can be fetched by watching for Contract events. It can also be synced via Order Watcher watching latest block height. This discussion is open for whether the SRA endpoint should support these Lifecycle events (cancel, partial fill, fully filled). These states can only be verified on-chain, if an update is sent through SRA the client will have to trust the relayer in its calculations. We believe this is best solved by watching the block chain or with order watcher, but feel free to voice your opinion.

Partial Order default endpoint [3]

This replaces the fee endpoint, where one would previously pass in the partial order and receive the fees and feeRecipient for this order. There is additional custom parameters a relayer may want to add (such as sender address). This endpoint would accept a partial order and the return result would represent an order with sender, feeRecipientAddress, makerFee and takerFee. This is then verified, signed and submitted to the Relayer.

Fee Recipient List endpoint [4]

When using multiple fee recipients it is useful for reporting and discovery to find out which relayer that belonged to. A relayer can return a list of all fee recipients they use. This is currently unverifiable and only useful after a transaction has occured.

networkId parameter [5]

We've seen usage of both networkId and subdomains to represent kovan rather than mainnet. We believe it would be best to standardise this into a networkId parameter which accepts an id representing the network (1 mainnet, 42 kovan etc). Default is mainnet.

Let me know if there are any other items you would like to discuss as well and I will summarise and add to this discussion.

RequestIds should support 128-bit values

The requestId detailed in the WebSocket API Specification v0 is not scalable as an Integer.

For clients with high numbers of users, assigning a random number has a higher probability of a collision than a String of say, 128 bits. If clients opted away from randomising the Integer, they would need to maintain state on their server instead, which is unnecessary overhead.

I suggest String support so that clients can send through 128-bit values as requestIds, allowing them not to need to maintain state and decreasing the chance of collisions with their subscribers.

More on this here: https://en.wikipedia.org/wiki/Universally_unique_identifier#Collisions

Snapshot in V2 websocket orderbook subscribe?

v0 had a very handy option to return a limited amount of the orderbook on subscribe before streaming order updates ("snapshot" and "limit" at https://github.com/0xProject/standard-relayer-api/blob/master/ws/v0.md#orderbook-channel).

I was updating some code to use v2, and I can't find this option. Was it removed? If so, why? What is the recommend work-around?

I'm thinking I'll have to use the http api to get the orderbook and then the websocket api to subscribe. My code for v1 currently just uses websockets and adding an http library is a bit more complexity than I was hoping for.

v3 Order Schema - WS vs HTTP

In SRA v3, the order object schema specifieds "chainId" for HTTP, and "domainHash" for WS. I notice that this commit changed domainhash to chainid for HTTP, and I'm wondering if leaving domainhash in WS was just an oversight.

Validations to put on /0x/v0/order POST

Hey,

I am not sure what radarrelay standard API is using to validate POST order/ endpoint.
can you assist me with that, I understood every other endpoints using json-schemas.
But radarrelay is giving you perfect output of what the error is, how to do that ?
Please suggest me.

Thanks

comments/suggestions to GET /v0/token_pairs endpoint

  1. The keys for each token payload (ie. tokenA, tokenB) are not useful or standard if the user is searching for a specific pairing (or token). As the number of possible tokens increases users may not want to traverse the array to find a specific symbol or address.

  2. While Radar is planning to support NxN token pairings it is possible not all Relayers will support low volume pairings. The endpoint as it stands serves well for seeing what tokens are available on the Relayer however is not structured to support strict or limited pairings.

document websocket connection heartbeat interval

I am using python's aiohttp library to handle websockets instead of your typescript library because I am just building a quick prototype and I know python better than javascript/typescript.

I have the subscribe command working and returning a bunch of orders, but 60 seconds after connecting, I get an error about an unclosed client session.

After some tinkering, I realized that I need to enable heartbeats to keep the connection alive. I changed my command to be async with http_session.ws_connect(relay_url, heartbeat=30) as ws:.

Heartbeats being necessary (and their recommended interval) should probably be added to the docs.

Fee API Rigidity

I have a few thoughts about the fee API.

The API seems to assume a greater rigidity of fee structure than I think is appropriate. A relayer might give makers some leeway regarding how much of the fee is paid by the maker, and how much is paid by the taker, leaving it to the market to determine an allocation of fees. The current fee API only allows the relayer to specify a single option for fees, but if the fee API returned a list instead of a single object the relayer could specify several acceptable fees. It may not be feasible to enumerate all possible fees, or to have the API define a set of rules for choosing an acceptable fee, but I at least think it should be possible to return more than a single acceptable fee. If the response type is a list, relayers that want to rigidly define the fee structure can return only one option, while relayers that want to allow flexibility could return several example of acceptable fees.

Is order filling/cancelling part of standard-relayer-api?

Hi @BMillman19 @fabioberger great work on the 0xProject at first! I am trying to build my relayer on top of 0x's standard-relayer-api and I found out that order filling/cancelling is not part of the standard but we do have order filling/cancelling schema tests here https://github.com/0xProject/0x-monorepo/blame/development/packages/json-schemas/test/schema_test.ts#L280.

I am wondering is that going into the standard or it leaves to relayer to implement their customized apis. Thanks!

Orders v Orderbook

Hey, I'm trying to understand the difference between orders and orderbook. Can anyone shed some light?

GET orderbook endpoint default unsorted

Documentation for get orderbook mentions,
Bids will be sorted in descending order by price, and asks will be sorted in ascending order by price. Within the price sorted orders, the orders are further sorted by taker fee price which is defined as the takerFee divided by takerTokenAmount. After taker fee price, orders are to be sorted by expiration in ascending order.
Include By default, orders returned by this endpoint are unsorted.

Outdated Asset Data examples

The assetData examples only have 20 bytes for addresses, when they should have 32 in both the websockets and http specifications.

Example Signatures Not Valid

Aside from not matching the order, the signature 0x012761a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33 is invalid because:

NoteGio/openrelay#127 is an issue raised by an OpenRelay user trying to submit the example order and OpenRelay rejects it because of the signature. Aside from the other reasons OpenRelay would reject that order, the signature in the documentation isn't to spec.

United States Trades

If I build the Relayer on my website, will my US customers be able to trade ERC20 tokens?

How is orderHash derived?

Hi, can someone point me to how to generate an orderHash to implement the /v0/order/[orderHash] endpoint? Thanks

Websockets: Message Type

The Websockets API should clarify that messages should be of "text" type rather than binary. 0x connect expects this, but the specification is ambiguous,

Global relayer requirements

Relayers will have their own requirements for accepting orders. Some examples include:

  • a specific exchangeContractAddress
  • a specific taker
  • a minimum expiration time
  • some specific information provided in an order's salt
  • fee information

In addition, relayers can have different rules for determining how these are valid. They may support a range of parameters, and some parameters may also depend on others.

Expectations for asset_data call on ERC721 assets

What are the expectations for a relayer broadcasting ERC721 orders in the asset_data call https://github.com/0xProject/standard-relayer-api/blob/master/http/v2.md#get-v2asset_pairs?

Because the NFT id is encoded in the asset data, it behaves a little differently than ERC20 assets. Should all active orders be listed, or should the assetData item be encoded with just the smart contract of the NFT, not the actual NFTs? This makes more sense, although the 0x sdk asset utilities class doesn't have an overload to encode an ERC721 item like that, so we weren't sure if the authors wanted all ERC721 assets available in the asset_pair call.

Specify a max page size

Boundless per_page is obviously a bad idea. Decide on a max. 100 seems about right to me.

WebSockets endpoint

Both endpoints for WebSockets don't work. Tryed to connect from python app - 404 error was returned. Tried to connect fgrom another location and some different services, which help to check webscoket connection - everything is the same

Cannot GET /token_pairs

file : http/v3.md

curl https://api.0x.org/token_pairs?page=3&perPage=20

returns

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot GET /token_pairs</pre>
</body>
</html>

Relayers with API on testnet

Hi, do you have any relayers working on testnet that offer API integration. Additionally, is there any direct API to get order details with order hash?

Currency pair standards / price notation

I don't know if this is the appropriate place to discuss this, but I will throw it out there.

At this point the protocol or the relayer API standards state nothing about price and currency pair standardization. This is understandable since it's mainly a UI issue. Nevertheless, I think it might be fruitful to have discussion about this.

The regular forex market has an informal standard in place which makes sure that a currency takes prcedence as the base currency. For example, Euro/Dollar prices are always noted as EUR/USD and never as USD/EUR.

The problem is that reverse prices can be confusing to the users who are used to seeing only one side of the price notation.

I think we should have a standard which makes sure prices are always displayed in a certain format. Maybe something simple and neutral as alphabetical order, for example GNT/REP and never REP/GNT. Maybe add an exception to the rule where WETH takes precedence as base currency, since all centralized exchanges list prices in relation to ETH.

I'm trying to setup a relayer at the moment and this is a pretty annoying issue. And I know the guys from Radar Relay are running into the same problem, so it might be worth standardizing this somehow.

asset_pairs question

Hey, is asset_pairs supposed to give a list of supported asset pairs, or a list of asset_pairs which currently have maker orders

Error code for IP block

Relayers may choose to block certain IP addresses. Would be nice to have a standardized Error flow for this.

When will the draft be finalized?

At OpenRelay we'd really like to target the standard-relayer-api, but we don't want to spin our wheels chasing a specification that's changing every couple of days. Given that the API is versioned anyway, can we get a timeline for locking down a final /v0/ API, and have any subsequent breaking changes go into a /v1/ draft?

token_pairs vs tokens

Hi there, a quick suggestion regarding Standard Relayer API endpoints.

  1. According to the current spec, /v0/token_pairs endpoint returns a list of tokens. However, when we say "token pairs", we understand a list of markets such as ZRX/ETH, GNT/ETH etc., but what we get a list of tokens. So, to make it semantically relevant, I'd suggest we rename /v0/token_pairs to /v0/tokens.
[
    {
        "tokenA": {
            "address": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
            "minAmount": "0",
            "maxAmount": "10000000000000000000",
            "precision": 5
        },
        "tokenB": {
            "address": "0xef7fff64389b814a946f3e92105513705ca6b990",
            "minAmount": "0",
            "maxAmount": "50000000000000000000",
            "precision": 5
        }
    }
]
  1. And for /v0/token_pairs end point we should get a return like below:
[
    {
        "id": "ZRX-WETH",
        "baseTokenAddress": "0xe41d2489571d322189246dafa5ebde1f4699f498",
        "quoteTokenAddress": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
        "baseTokenDecimals": 18,
        "quoteTokenDecimals": 18,
        "quoteIncrement": 1e-8,
        "minOrderSize": 0,
        "maxOrderSize": 1000000,
        "lastTradePrice": 0
    },
    {
        "id": "GNT-WETH",
        "baseTokenAddress": "0xa74476443119A942dE498590Fe1f2454d7D4aC0d",
        "quoteTokenAddress": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
        "baseTokenDecimals": 18,
        "quoteTokenDecimals": 18,
        "quoteIncrement": 1e-8,
        "minOrderSize": 0,
        "maxOrderSize": 1000000,
        "lastTradePrice": 0
    }
]

Add GET endpoint to retrieve possible feeRecipient values

Spoke with this Craig over at 0xtracker about this one and agreed it may belong in the SRA spec or should at least be acknowledged somewhere.

ERC dEX now has multiple possible feeRecipients. We may have dozens/hundreds/enough to require paging through in the future. Craig has implemented something on his side that allows the mapping to take place, but it may be useful for other aggregator type apps to also have access to this same data. As an example, we added this endpoint: https://aqueduct.ercdex.com/rest.html#operation/GetFeeRecipients

So a simple endpoint, e.g. GET /fees/recipients, returns ['address-one', 'address-two'].

Guidance For MultiAssetProxy

With the introduction of the MultiAssetProxy, some things in the current version of the Standard Relayer API are a bit unclear. For example

makerAssetAddress [string] returns orders where the contract address for the maker asset matches the value specified

With the MultiAssetProxy, there's not necessarily a single contract address for the maker asset, so how should this parameter be handled?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.