unisat-wallet / dev-support

30 stars 19 forks source link

UniSat API - Get tx history by block height - start and total fields missing in response. #43

Open gbdevw opened 3 months ago

gbdevw commented 3 months ago

Summary

The API spec. shows response for "Get tx history by block height" should include two fields named "start" and a "total". However, actual responses do not include these fields. These fields are useful to iterate through pages of transactions. The issue has a low impact however as there are some workarounds available.

Expected behaviour

Response for "Get tx history by block height" should include "total" and "start" fields

Reproduce

Here is how I call the API:

curl -X 'GET' 'https://open-api.unisat.io/v1/indexer/block/847759/txs?cursor=0&size=5' -H 'accept: application/json' -H 'Authorization: Bearer SECRET'

Here is the response body I get:

{
  "code": 0,
  "msg": "ok",
  "data": [
    {
      "txid": "5ef4d1dc35580f7b1871ed5f3a32022e9d76c9b72ed216868bd4a4b4a1a73e21",
      "nIn": 1,
      "nOut": 3,
      "size": 267,
      "witOffset": 0,
      "locktime": 0,
      "inSatoshi": 312500000,
      "outSatoshi": 340750562,
      "nNewInscription": 0,
      "nInInscription": 0,
      "nOutInscription": 0,
      "nLostInscription": 0,
      "timestamp": 0,
      "height": 847759,
      "blkid": "",
      "idx": 0,
      "confirmations": 2
    },
    {
      "txid": "08c7a4775687fe291bad25ff990628933dbaef8609f9780af46ca6ea6c0a6e76",
      "nIn": 2,
      "nOut": 2,
      "size": 419,
      "witOffset": 0,
      "locktime": 0,
      "inSatoshi": 302574190,
      "outSatoshi": 302470990,
      "nNewInscription": 0,
      "nInInscription": 0,
      "nOutInscription": 0,
      "nLostInscription": 0,
      "timestamp": 0,
      "height": 847759,
      "blkid": "",
      "idx": 1,
      "confirmations": 2
    },
    {
      "txid": "38532e49dce3df8fdf7908cbf68c4a04fcd0915910aa364fafa095561d502f16",
      "nIn": 1,
      "nOut": 2,
      "size": 249,
      "witOffset": 0,
      "locktime": 847758,
      "inSatoshi": 531563300,
      "outSatoshi": 531512900,
      "nNewInscription": 0,
      "nInInscription": 0,
      "nOutInscription": 0,
      "nLostInscription": 0,
      "timestamp": 0,
      "height": 847759,
      "blkid": "",
      "idx": 2,
      "confirmations": 2
    },
    {
      "txid": "463103e11c815c2eb1739f5a82d8a5da49ee75cb1b47164ec7555ee0a4cb2024",
      "nIn": 1,
      "nOut": 9,
      "size": 649,
      "witOffset": 0,
      "locktime": 0,
      "inSatoshi": 422931407,
      "outSatoshi": 422797407,
      "nNewInscription": 0,
      "nInInscription": 0,
      "nOutInscription": 0,
      "nLostInscription": 0,
      "timestamp": 0,
      "height": 847759,
      "blkid": "",
      "idx": 3,
      "confirmations": 2
    },
    {
      "txid": "92a0fd090b503e945ff0d6c0c14286dde09bafc69a5ef0ade91fe85ee5ef9c31",
      "nIn": 1,
      "nOut": 1,
      "size": 191,
      "witOffset": 0,
      "locktime": 0,
      "inSatoshi": 60352652,
      "outSatoshi": 60330082,
      "nNewInscription": 0,
      "nInInscription": 0,
      "nOutInscription": 0,
      "nLostInscription": 0,
      "timestamp": 0,
      "height": 847759,
      "blkid": "",
      "idx": 4,
      "confirmations": 2
    }
  ]
}

Impact

User expects some fields to be present to indicate if more data are available (eg. total). As these fields are missing, a workaround must be used to determine if all available data have been fetched. This workaround is not perfect and can lead to errors.

Possible workaround

  1. Extract the idx value of the last transaction in the transactions history (= index)
  2. If index is lesser than (cursor + size - 1), this means more pages of data might be available. Therefore, users should send a new request to get the next page of data.

This workaround can lead to error in case the requested next page of data contains 0 transactions. The following examples show what issues the workaround might cause.

Get all available transactions:

curl -X 'GET' 'https://open-api.unisat.io/v1/indexer/block/847759/txs?cursor=0&size=6139' -H 'accept: application/json' -H 'Authorization: Bearer SECRET'

As the last idx (6138) is not lesser than (cursor=0 + size=6139 - 1), user will send a second request to check if more data are available:

curl -X 'GET' 'https://open-api.unisat.io/v1/indexer/block/847759/txs?cursor=6139&size=6139' -H 'accept: application/json' -H 'Authorization: Bearer SECRET'

The second request will return an error like the following which does not clearly indicate no more data are available:

{"code":-1,"msg":"get block txs failed","data":null}

Conclusion

Please, ensures "total" and "start" fields are present in responses of paginated API operations :)

gbdevw commented 3 months ago

Other related issue: The API specification is inaccurate. The example provided in the specification is quite different from the actual responses (see above)

{
  "code": 0,
  "msg": "OK",
  "data": {
    "detail": [
      {
        "txid": "string",
        "nIn": 0,
        "nOut": 0,
        "inSatoshi": 0,
        "outSatoshi": 0,
        "locktime": 0,
        "size": 0,
        "witOffset": 0,
        "height": 0,
        "idx": 0,
        "blkid": "string",
        "confirmations": 0,
        "timestamp": 0
      }
    ],
    "start": 0,
    "total": 0
  }
}
abangZ commented 3 months ago

@huanniangstudio We need to resolve this issue as soon as possible.