From f84a0782ee5058f7070061ed81b0a8263576ba3a Mon Sep 17 00:00:00 2001 From: pochingchen Date: Sat, 6 Apr 2024 05:20:00 -0700 Subject: [PATCH] Replace poem with axum and impl block API. --- docs/api_v2.md | 916 +++------- explorer/Cargo.toml | 4 + explorer/src/config.toml | 4 +- explorer/src/main.rs | 69 +- explorer/src/service/api.rs | 1926 +++++++++++----------- explorer/src/service/mod.rs | 1 + explorer/src/service/util.rs | 2 +- explorer/src/service/v1/address.rs | 2 +- explorer/src/service/v1/asset.rs | 8 +- explorer/src/service/v1/block.rs | 6 +- explorer/src/service/v1/chain.rs | 6 +- explorer/src/service/v1/price.rs | 12 +- explorer/src/service/v1/staking.rs | 10 +- explorer/src/service/v1/transaction.rs | 19 +- explorer/src/service/v1/validator.rs | 2 +- explorer/src/service/v2/asset.rs | 4 +- explorer/src/service/v2/block.rs | 144 ++ explorer/src/service/v2/claim.rs | 4 +- explorer/src/service/v2/delegation.rs | 4 +- explorer/src/service/v2/error.rs | 73 + explorer/src/service/v2/evm_to_native.rs | 2 +- explorer/src/service/v2/mod.rs | 23 + explorer/src/service/v2/native_to_evm.rs | 6 +- explorer/src/service/v2/other.rs | 6 +- explorer/src/service/v2/transaction.rs | 2 +- explorer/src/service/v2/undelegation.rs | 4 +- 26 files changed, 1494 insertions(+), 1765 deletions(-) create mode 100644 explorer/src/service/v2/block.rs create mode 100644 explorer/src/service/v2/error.rs diff --git a/docs/api_v2.md b/docs/api_v2.md index 7211012..682d535 100644 --- a/docs/api_v2.md +++ b/docs/api_v2.md @@ -1,736 +1,270 @@ # Findora Explorer V2 API Spec -* [1.1 根据地址获取Asset](#1.1) -* [1.2 获取asset集合](#1.2) -* [1.3 获取claim记录](#1.3) -* [1.4 根据交易hash获取claim记录](#1.4) -* [1.5 根据交易hash获取delegate记录](#1.5) -* [1.6 获取delegate记录](#1.6) -* [1.7 获取undelegate记录](#1.7) -* [1.8 根据交易hash获取undelegate记录](#1.8) -* [1.9 获取交易](#1.9) -* [1.10 获取用户发出的prism交易记录](#1.10) +## Block +* [1.1 根据区块号获取区块(Get block by number)](#1.1) +* [1.2 根据区块哈希获取区块(Get block by hash)](#1.2) +* [1.3 获取区块(Get blocks)](#1.3) -

1.1 根据地址查询Asset

+## Transaction +* [2.1 根据交易哈希获取交易(Get transaction by hash)](#2.1) -* `GET /api/v2/asset` +## Staking -* 参数 - -| 参数 | 类型 | 必传 | 说明 | -|-----------|--------|----|----------| -| address | string | Y | asset地址 | -| page | number | N | 页码,默认1 | -| page_size | number | N | 页大小,默认10 | - -* Request: `/api/v2/asset?address=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=&page=1&page_size=2` -* Response: - * 按区块高度降序排列 -```json -{ - "code": 200, - "data": { - "assets": [{ - "asset": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", - "block": "58A7A6E2600B74C238207848B5455CEB31B3DCD53BA61F902EE4ABE0CD2FEF0D", - "height": 1451661, - "issuer": "fra1rkvlrs8j8y7rlud9qh6ndg5nr4ag7ar4640dr8h0ys6zfrwv25as42zptu", - "timestamp": 1639902625, - "tx": "199280b6c417a92e694ea5374b4cbb939914c127d64be0a15408dd446931bde1", - "ty": 0, - "value": { - "DefineAsset": { - "body": { - "asset": { - "asset_rules": { - "decimals": 6, - "max_units": "21000000000001000", - "transfer_multisig_rules": null, - "transferable": true, - "updatable": false - }, - "code": { - "val": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - }, - "issuer": { - "key": "HZnxwPI5PD_xpQX1NqKTHXqPdHXVXtGe7yQ0JI3MVTs=" - }, - "memo": "FRA" - } - }, - "pubkey": { - "key": "HZnxwPI5PD_xpQX1NqKTHXqPdHXVXtGe7yQ0JI3MVTs=" - }, - "signature": "evtO-ogJEv7iVOAJxb6YEisUEXWW2EMVv9E8C_Z9abV2jp-3hwARx2W6OwSLhoUJBrRq1wZLWBnc-Ml5YxXBCQ==" - } - } - }, { - "asset": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", - "block": "58A7A6E2600B74C238207848B5455CEB31B3DCD53BA61F902EE4ABE0CD2FEF0D", - "height": 1451661, - "issuer": "fra1rkvlrs8j8y7rlud9qh6ndg5nr4ag7ar4640dr8h0ys6zfrwv25as42zptu", - "timestamp": 1639902625, - "tx": "199280b6c417a92e694ea5374b4cbb939914c127d64be0a15408dd446931bde1", - "ty": 1, - "value": { - "IssueAsset": { - "body": { - "code": { - "val": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - }, - "num_outputs": 2, - "records": [ - [{ - "id": null, - "record": { - "amount": { - "NonConfidential": "10500000000000000" - }, - "asset_type": { - "NonConfidential": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - }, - "public_key": "HZnxwPI5PD_xpQX1NqKTHXqPdHXVXtGe7yQ0JI3MVTs=" - } - }, null], - [{ - "id": null, - "record": { - "amount": { - "NonConfidential": "10500000000000000" - }, - "asset_type": { - "NonConfidential": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - }, - "public_key": "HZnxwPI5PD_xpQX1NqKTHXqPdHXVXtGe7yQ0JI3MVTs=" - } - }, null] - ], - "seq_num": 0 - }, - "pubkey": { - "key": "HZnxwPI5PD_xpQX1NqKTHXqPdHXVXtGe7yQ0JI3MVTs=" - }, - "signature": "Z6_Dfdkx9CMiao1doiCz6tc8zH4gOCuNSc61etAzKu4xWqlRSzS5NrUtKJ16z8DLqhjm8AKpVfbncfJkQCXwCQ==" - } - } - }], - "page": 1, - "page_size": 2, - "total": 8 - }, - "message": "" -} -``` - - - -

1.2 获取asset集合

- -* `GET /api/v2/asset/list` -* 参数 +

1.1 根据区块号获取区块

-| 参数 | 类型 | 必传 | 说明 | -|-----------|--------|----|----------| -| page | number | N | 页码,默认1 | -| page_size | number | N | 页大小,默认10 | +* `GET /api/v2/block/number` -* Request: `/api/v2/asset/list?page=1&page_size=2` -* Response: - * 按区块高度降序排列 -```json -{ - "code": 200, - "data": { - "assets": [{ - "asset": "bVXSkVh0hFHX_oUYEfC85_gsjbK5ZL_PovE0Umy-siw=", - "block": "4DC1972393E2046725C2787BF63160070DCC290F52988B4E6B303B32882E2246", - "height": 5261130, - "issuer": "fra166dndg5j09deghynastdjam8d0eaqkaqx95mukrscvsm3kecqqws3tfgms", - "timestamp": 1707684612, - "tx": "a666e141715a9d2d1697808ecae45e6b8274df3ee0abb341251ea4e34777cf9c", - "ty": 1, - "value": { - "IssueAsset": { - "body": { - "code": { - "val": [109, 85, 210, 145, 88, 116, 132, 81, 215, 254, 133, 24, 17, 240, 188, 231, 248, 44, 141, 178, 185, 100, 191, 207, 162, 241, 52, 82, 108, 190, 178, 44] - }, - "num_outputs": 1, - "records": [ - [{ - "id": null, - "record": { - "amount": { - "NonConfidential": "50000000000000" - }, - "asset_type": { - "NonConfidential": [109, 85, 210, 145, 88, 116, 132, 81, 215, 254, 133, 24, 17, 240, 188, 231, 248, 44, 141, 178, 185, 100, 191, 207, 162, 241, 52, 82, 108, 190, 178, 44] - }, - "public_key": "1ps2opJ5W5Rck-wW2Xdna_PQW6Axab5YcMMhuNs4AB0=" - } - }, null] - ], - "seq_num": 130486 - }, - "pubkey": { - "key": "1ps2opJ5W5Rck-wW2Xdna_PQW6Axab5YcMMhuNs4AB0=" - }, - "signature": "RjCH51IUklW4Npv0SgV9hkl6ejg3bqNzcYCp1DHrjGX1yt_oai6BpRwTn2PZYa8t9dSHUCBwRKmLgqydlXAKAA==" - } - } - }, { - "asset": "bVXSkVh0hFHX_oUYEfC85_gsjbK5ZL_PovE0Umy-siw=", - "block": "8D5622D4C12ECF7A370457BE156D09C54C6ABAA90F0203B5D24C7DD28B92147B", - "height": 5261099, - "issuer": "fra166dndg5j09deghynastdjam8d0eaqkaqx95mukrscvsm3kecqqws3tfgms", - "timestamp": 1707684053, - "tx": "34d40db1f8d1e3ca202ea8284a5efcaf73a6e212fc145e0d34012e22a4972bc3", - "ty": 1, - "value": { - "IssueAsset": { - "body": { - "code": { - "val": [109, 85, 210, 145, 88, 116, 132, 81, 215, 254, 133, 24, 17, 240, 188, 231, 248, 44, 141, 178, 185, 100, 191, 207, 162, 241, 52, 82, 108, 190, 178, 44] - }, - "num_outputs": 1, - "records": [ - [{ - "id": null, - "record": { - "amount": { - "NonConfidential": "10000000000000" - }, - "asset_type": { - "NonConfidential": [109, 85, 210, 145, 88, 116, 132, 81, 215, 254, 133, 24, 17, 240, 188, 231, 248, 44, 141, 178, 185, 100, 191, 207, 162, 241, 52, 82, 108, 190, 178, 44] - }, - "public_key": "1ps2opJ5W5Rck-wW2Xdna_PQW6Axab5YcMMhuNs4AB0=" - } - }, null] - ], - "seq_num": 130485 - }, - "pubkey": { - "key": "1ps2opJ5W5Rck-wW2Xdna_PQW6Axab5YcMMhuNs4AB0=" - }, - "signature": "9TFPa9ARxGVh8LZhJEqh1ZBL7hVhD0XkNhYoOoU9z2vtjwykRcEu5I_fdrea3fmgWRMFhLpz9BLDGpK9hTT-BQ==" - } - } - }], - "page": 1, - "page_size": 2, - "total": 242 - }, - "message": "" -} -``` - -

1.3 获取claim记录

- -* `GET /api/v2/staking/claims` -* 参数 - -| 参数 | 类型 | 必传 | 说明 | -|-----------|--------|----|----------------------| -| address | string | N | 用户地址,不传则返回所有的claim记录 | -| page | number | N | 页码,默认1 | -| page_size | number | N | 页大小,默认10 | - -* Request: - * e.g. 获取claim记录:`/api/v2/staking/claims?page=1&page_size=10` - * e.g. 获取用户的claim记录:`/api/v2/staking/claims?address=fra1zfqvdavujcjd9eumz8y0vjsr5js8hsxmv0vgldjsu0ddjdm2547qf3f6tg&page=1&page_size=10` -* Response: - * 按区块高度降序排列 -```json -{ - "code": 200, - "data": { - "data": [{ - "amount": 0, - "block_hash": "23D925287A2C08036E3C8D2809CFB73FABA29C7FC95809C0DCAF1A1BB0482E11", - "from": "fra1zfqvdavujcjd9eumz8y0vjsr5js8hsxmv0vgldjsu0ddjdm2547qf3f6tg", - "height": 5468968, - "timestamp": 1711852829, - "tx_hash": "609081d6a52081b82900fffa3a11513d60dc751dc28a9cf01857b9ffb6bc08f0", - "value": { - "Claim": { - "body": { - "amount": null, - "nonce": [ - [51, 68, 235, 174, 85, 98, 153, 128], 133140 - ] - }, - "pubkey": "EkDG9ZyWJNLnmxHI9koDpKB7wNtj2I-2UOPa2TdqpXw=", - "signature": "WXVTtSfckHTm_M8POcE3lfBAkS32pYFPlzrBau_Vr8YOWYS440F7SSnZD9DAmfwCrlbd2py3qTUC60B55TmWCw==", - "td_addr": [253, 140, 101, 99, 74, 157, 136, 153, 250, 20, 32, 1, 119, 175, 25, 210, 79, 110, 28, 55] - } - } - }, { - "amount": 0, - "block_hash": "F6CDAA225C47974B7864075A793C5D17D0E2680C8AF4237A2461C4665FF16F1D", - "from": "fra1zfqvdavujcjd9eumz8y0vjsr5js8hsxmv0vgldjsu0ddjdm2547qf3f6tg", - "height": 5450196, - "timestamp": 1711475308, - "tx_hash": "4dd36fda15ea9162493a5e5c3eaeadd9fd3b663a4495be09c831317e19a84d64", - "value": { - "Claim": { - "body": { - "amount": null, - "nonce": [ - [61, 227, 178, 41, 152, 152, 229, 16], 132890 - ] - }, - "pubkey": "EkDG9ZyWJNLnmxHI9koDpKB7wNtj2I-2UOPa2TdqpXw=", - "signature": "bkvcDCP-9I95xMaciC78Kum60xIdcFdfSdVG3jDT8XqDflmmtp-4Ssjma5bzt8UNDnn2PI6Yw0_er4JuFHCuBA==", - "td_addr": [0, 14, 51, 171, 116, 113, 24, 111, 59, 29, 233, 252, 8, 187, 156, 72, 15, 69, 53, 144] - } - } - }], - "page": 1, - "page_size": 2, - "total": 474 - }, - "message": "" -} -``` - -

1.4 根据交易hash获取claim记录

- -* `GET /api/v2/staking/claim/:tx_hash` * 参数 -| 参数 | 类型 | 必传 | 说明 | -|---------|--------|----|------| -| tx_hash | string | Y | 交易哈希 | - +| 参数(param) | 类型(type) | 必传(required) | 说明 | +|-----------|----------|--------------|-----| +| num | number | Y | 区块号 | -* Request: `/api/v2/staking/claim/4dd36fda15ea9162493a5e5c3eaeadd9fd3b663a4495be09c831317e19a84d64` +* Request: `http://localhost/api/v2/block/number?num=100` * Response: ```json { - "code": 200, - "data": { - "amount": 0, - "block_hash": "F6CDAA225C47974B7864075A793C5D17D0E2680C8AF4237A2461C4665FF16F1D", - "from": "fra1zfqvdavujcjd9eumz8y0vjsr5js8hsxmv0vgldjsu0ddjdm2547qf3f6tg", - "height": 5450196, - "timestamp": 1711475308, - "tx_hash": "4dd36fda15ea9162493a5e5c3eaeadd9fd3b663a4495be09c831317e19a84d64", - "value": { - "Claim": { - "body": { - "amount": null, - "nonce": [ - [61, 227, 178, 41, 152, 152, 229, 16], 132890 - ] - }, - "pubkey": "EkDG9ZyWJNLnmxHI9koDpKB7wNtj2I-2UOPa2TdqpXw=", - "signature": "bkvcDCP-9I95xMaciC78Kum60xIdcFdfSdVG3jDT8XqDflmmtp-4Ssjma5bzt8UNDnn2PI6Yw0_er4JuFHCuBA==", - "td_addr": [0, 14, 51, 171, 116, 113, 24, 111, 59, 29, 233, 252, 8, 187, 156, 72, 15, 69, 53, 144] - } - } - }, - "message": "" + "block_hash": "E8A4A1F0A6AE1EBAC0D8CA84106985DEFA47240A2AD4E045717CD304B8EDD985", + "block_num": 100, + "app_hash": "759AB503F009046D19FC4A1F7B3DE5E1087FE3B59FC6D842FDA5C74264F2ABEE", + "proposer": "FD8C65634A9D8899FA14200177AF19D24F6E1C37", + "num_txs": 0, + "block_size": 2305, + "block_id": { + "hash": "E8A4A1F0A6AE1EBAC0D8CA84106985DEFA47240A2AD4E045717CD304B8EDD985", + "parts": { + "total": "1", + "hash": "4CAD8FEEDF00A02839D94AA2DE53C458C125E88F72A82F5AB414047B2B8864FC" + } + }, + "block_header": { + "version": { + "block": "10", + "app": "0" + }, + "chain_id": "chain-qILMsV", + "height": "100", + "time": "2021-03-30T05:37:46.111298958Z", + "last_block_id": { + "hash": "D823B5C8D961507F6DE316BA0828D494E3EEA603CEA98DAE6AC22C1FDE6C96C8", + "parts": { + "total": "1", + "hash": "61D98ECCDDE383FD33513BB437D83D8F3E3638680AF13ACCD16A02F4B5EC9313" + } + }, + "last_commit_hash": "6E9CD69991A58B52E02BA843692F3AA43A9283C453C672AD8E99F750622562FD", + "data_hash": "", + "validators_hash": "EC4E07BBE9EE84C39699C844D32CA8739FD8145D28F6B4DE7E8DF09326212D76", + "next_validators_hash": "EC4E07BBE9EE84C39699C844D32CA8739FD8145D28F6B4DE7E8DF09326212D76", + "consensus_hash": "048091BC7DDC283F77BFBF91D73C44DA58C3DF8A9CBC867405D8B7F3DAADA22F", + "app_hash": "759AB503F009046D19FC4A1F7B3DE5E1087FE3B59FC6D842FDA5C74264F2ABEE", + "last_results_hash": "", + "evidence_hash": "", + "proposer_address": "FD8C65634A9D8899FA14200177AF19D24F6E1C37" + } } ``` -

1.5 根据交易hash获取delegate记录

- -* `GET /api/v2/staking/delegation/:tx_hash` -* 参数 - -| 参数 | 类型 | 必传 | 说明 | -|---------|--------|----|------| -| tx_hash | string | Y | 交易哈希 | - -* Request: `/api/v2/staking/delegation/e2cd3ec8c29d1ad45307739785b8dc2e776e8032393c57b828d43d7db8fe3b62` -* Response: -```json -{ - "code": 200, - "data": { - "amount": 408000000, - "block_hash": "1BCCEE75342A238AC3836668D83A2A48E158A570B5644C4E046E07DF97B89A93", - "from": "fra1vrvnc9kfnnl02rhafvdn4yssll4rz0flfc73xkj3w9tlsggy38rskgv35t", - "height": 5467159, - "new_validator": "", - "timestamp": 1711816770, - "tx_hash": "e2cd3ec8c29d1ad45307739785b8dc2e776e8032393c57b828d43d7db8fe3b62", - "validator": "000e33ab7471186f3b1de9fc08bb9c480f453590", - "value": { - "Delegation": { - "body": { - "amount": 408000000, - "new_validator": null, - "nonce": [ - [224, 41, 94, 168, 98, 48, 85, 14], 133117 - ], - "validator": "000e33ab7471186f3b1de9fc08bb9c480f453590" - }, - "pubkey": "YNk8Fsmc_vUO_UsbOpIQ_-oxPT9OPRNaUXFX-CEEicc=", - "signature": "wpofVSep2i1ygaxpMDx4Zbl0Um6odO8g1hSpdkjfbA7E3y6UwPth0m-wu03sS_JM0hdrnL4cik5hVvPbWFdRBg==", - "v_signature": null - } - } - }, - "message": "" -} -``` +

1.2 根据区块哈希获取区块

-

1.6 获取delegate记录

+* `GET /api/v2/block/hash` -* `GET /api/v2/staking/delegations` * 参数 -| 参数 | 类型 | 必传 | 说明 | -|-----------|--------|----|----------------------| -| address | string | Y | 用户地址,不传则返回所有的claim记录 | -| page | number | N | 页码,默认1 | -| page_size | number | N | 页大小,默认10 | +| 参数(param) | 类型(type) | 必传(required) | 说明 | +|-----------|----------|--------------|------| +| hash | string | Y | 区块哈希 | -* Request: - * 获取delegate记录: `/api/v2/staking/delegations?page=1&page_size=2` - * 获取用户的delegate记录: `/api/v2/staking/delegations?address=fra1vrvnc9kfnnl02rhafvdn4yssll4rz0flfc73xkj3w9tlsggy38rskgv35t&page=1&page_size=2` +* Request: `http://localhost/api/v2/block/hash?hash=E8A4A1F0A6AE1EBAC0D8CA84106985DEFA47240A2AD4E045717CD304B8EDD985` * Response: ```json { - "code": 200, - "data": { - "items": [{ - "amount": 408000000, - "block_hash": "1BCCEE75342A238AC3836668D83A2A48E158A570B5644C4E046E07DF97B89A93", - "from": "fra1vrvnc9kfnnl02rhafvdn4yssll4rz0flfc73xkj3w9tlsggy38rskgv35t", - "height": 5467159, - "new_validator": "", - "timestamp": 1711816770, - "tx_hash": "e2cd3ec8c29d1ad45307739785b8dc2e776e8032393c57b828d43d7db8fe3b62", - "validator": "000e33ab7471186f3b1de9fc08bb9c480f453590", - "value": { - "Delegation": { - "body": { - "amount": 408000000, - "new_validator": null, - "nonce": [ - [224, 41, 94, 168, 98, 48, 85, 14], 133117 - ], - "validator": "000e33ab7471186f3b1de9fc08bb9c480f453590" - }, - "pubkey": "YNk8Fsmc_vUO_UsbOpIQ_-oxPT9OPRNaUXFX-CEEicc=", - "signature": "wpofVSep2i1ygaxpMDx4Zbl0Um6odO8g1hSpdkjfbA7E3y6UwPth0m-wu03sS_JM0hdrnL4cik5hVvPbWFdRBg==", - "v_signature": null - } - } - }, { - "amount": 2010000000, - "block_hash": "AA2114E42F636679B8C67476725010ED846A690CE31C241F7830C6E2CD85141C", - "from": "fra1vrvnc9kfnnl02rhafvdn4yssll4rz0flfc73xkj3w9tlsggy38rskgv35t", - "height": 5464300, - "new_validator": "", - "timestamp": 1711758769, - "tx_hash": "08933e65ecf6a7c4c7f1b617f4823177a28e5b6c0ab028f1d889e8af0012e8e5", - "validator": "000e33ab7471186f3b1de9fc08bb9c480f453590", - "value": { - "Delegation": { - "body": { - "amount": 2010000000, - "new_validator": null, - "nonce": [ - [6, 244, 169, 33, 144, 151, 53, 186], 133073 - ], - "validator": "000e33ab7471186f3b1de9fc08bb9c480f453590" - }, - "pubkey": "YNk8Fsmc_vUO_UsbOpIQ_-oxPT9OPRNaUXFX-CEEicc=", - "signature": "swLH39i-eeWhx5KhccNNHA71443WBwni1pG-u1UP3Olme8jaxjrcI1eca6krH14fuSP1x3iBhhsayBDwBZyPDw==", - "v_signature": null - } - } - }], - "page": 1, - "page_size": 2, - "total": 272 - }, - "message": "" + "block_hash": "E8A4A1F0A6AE1EBAC0D8CA84106985DEFA47240A2AD4E045717CD304B8EDD985", + "block_num": 100, + "app_hash": "759AB503F009046D19FC4A1F7B3DE5E1087FE3B59FC6D842FDA5C74264F2ABEE", + "proposer": "FD8C65634A9D8899FA14200177AF19D24F6E1C37", + "num_txs": 0, + "block_size": 2305, + "block_id": { + "hash": "E8A4A1F0A6AE1EBAC0D8CA84106985DEFA47240A2AD4E045717CD304B8EDD985", + "parts": { + "total": "1", + "hash": "4CAD8FEEDF00A02839D94AA2DE53C458C125E88F72A82F5AB414047B2B8864FC" + } + }, + "block_header": { + "version": { + "block": "10", + "app": "0" + }, + "chain_id": "chain-qILMsV", + "height": "100", + "time": "2021-03-30T05:37:46.111298958Z", + "last_block_id": { + "hash": "D823B5C8D961507F6DE316BA0828D494E3EEA603CEA98DAE6AC22C1FDE6C96C8", + "parts": { + "total": "1", + "hash": "61D98ECCDDE383FD33513BB437D83D8F3E3638680AF13ACCD16A02F4B5EC9313" + } + }, + "last_commit_hash": "6E9CD69991A58B52E02BA843692F3AA43A9283C453C672AD8E99F750622562FD", + "data_hash": "", + "validators_hash": "EC4E07BBE9EE84C39699C844D32CA8739FD8145D28F6B4DE7E8DF09326212D76", + "next_validators_hash": "EC4E07BBE9EE84C39699C844D32CA8739FD8145D28F6B4DE7E8DF09326212D76", + "consensus_hash": "048091BC7DDC283F77BFBF91D73C44DA58C3DF8A9CBC867405D8B7F3DAADA22F", + "app_hash": "759AB503F009046D19FC4A1F7B3DE5E1087FE3B59FC6D842FDA5C74264F2ABEE", + "last_results_hash": "", + "evidence_hash": "", + "proposer_address": "FD8C65634A9D8899FA14200177AF19D24F6E1C37" + } } ``` -

1.7 获取undelegate记录

-* `GET /api/v2/staking/undelegations` -* 参数 +

1.3 获取区块

-| 参数 | 类型 | 必传 | 说明 | -|-----------|--------|----|----------------------| -| address | string | Y | 用户地址,不传则返回所有的claim记录 | -| page | number | N | 页码,默认1 | -| page_size | number | N | 页大小,默认10 | +* `GET /api/v2/blocks` -* Request: - * 获取undelegate记录: `/api/v2/staking/undelegations?page=1&page_size=2` - * 获取用户的undelegate记录:`/api/v2/staking/undelegations?address=fra1vrvnc9kfnnl02rhafvdn4yssll4rz0flfc73xkj3w9tlsggy38rskgv35t&page=1&page_size=2` -* Response: - * 按区块高度降序排列 -```json -{ - "code": 200, - "data": { - "items": [{ - "amount": 949417158152, - "block_hash": "B93EA7CF643F6A26904F8A9429E12C013E90980EF6C24D0158E5D945FF2C3F8D", - "from": "fra1mmcy767sy0shh72jla0pluhfhfydk5w73gq0m3j2j06kd4ssergqrpa57g", - "height": 5471746, - "new_delegator": "0vGE7s9Z8OpPoS6RiAbLN3qZUGfBSL6PRxXMKT-lhMA=", - "target_validator": "7C77CF71CF6CBD04885E32FC49EDA367F7BC3C65", - "timestamp": 1711908142, - "tx_hash": "e223ce6af861769a440f0e5599fce7ef4d09d1048f5f51fd4347ca909de87d95", - "value": { - "UnDelegation": { - "body": { - "nonce": [ - [38, 244, 218, 29, 71, 253, 67, 151], 133195 - ], - "pu": { - "am": 949417158152, - "new_delegator_id": "0vGE7s9Z8OpPoS6RiAbLN3qZUGfBSL6PRxXMKT-lhMA=", - "target_validator": [124, 119, 207, 113, 207, 108, 189, 4, 136, 94, 50, 252, 73, 237, 163, 103, 247, 188, 60, 101] - } - }, - "pubkey": "3vBPa9Aj4Xv5Uv9eH_LpukjbUd6KAP3GSpP1ZtYQyNA=", - "signature": "x3GM0eOp_FljztQ3wXNk7DD50p9-3cLFUXBUqRAu-gGaf9ZUBaG547yhHb-sUdbUZXaFjCcb9TsT0m2g5ZR1Dw==" - } - } - }, { - "amount": 3744640540, - "block_hash": "71E7FC9770810F482850F1487F538C129327B1A02F44EF35714046A19E9630C4", - "from": "fra1zfqvdavujcjd9eumz8y0vjsr5js8hsxmv0vgldjsu0ddjdm2547qf3f6tg", - "height": 5468906, - "new_delegator": "RD8SLnaxZAs-UnLwH7_zDx1k5QRgpzJymMbslzN28PA=", - "target_validator": "000E33AB7471186F3B1DE9FC08BB9C480F453590", - "timestamp": 1711851641, - "tx_hash": "62e6263a7016b1b9f4d5fc7f251bdf996aeb5fb5f9f866c48658a4c8439b61da", - "value": { - "UnDelegation": { - "body": { - "nonce": [ - [148, 137, 12, 225, 62, 224, 133, 33], 133138 - ], - "pu": { - "am": 3744640540, - "new_delegator_id": "RD8SLnaxZAs-UnLwH7_zDx1k5QRgpzJymMbslzN28PA=", - "target_validator": [0, 14, 51, 171, 116, 113, 24, 111, 59, 29, 233, 252, 8, 187, 156, 72, 15, 69, 53, 144] - } - }, - "pubkey": "EkDG9ZyWJNLnmxHI9koDpKB7wNtj2I-2UOPa2TdqpXw=", - "signature": "Q6WBodsrwo1BkYOi0sTS-qTRYUZo9APKG4qGzv1-5OyZ-9sVKotKi5I9jtF9wvnG_mgqN2HryCkKG57slo6PCA==" - } - } - }], - "page": 1, - "page_size": 2, - "total": 6182 - }, - "message": "" -} -``` - -

1.8 根据交易hash获取undelegate记录

- -* `GET /api/v2/staking/undelegation/:tx_hash` * 参数 -| 参数 | 类型 | 必传 | 说明 | -|---------|--------|----|------| -| tx_hash | string | Y | 交易哈希 | +| 参数(param) | 类型(type) | 必传(required) | 说明 | +|-----------|----------|--------------|------| +| page | number | N | 默认1 | +| page_size | number | N | 默认10 | -* Request: `/api/v2/staking/undelegation/583d9071df8299978e227d4b62d122225e4d2bc7fce0f581b4396b5c35f63dbd` +* Request: `http://localhost/api/v2/blocks?page=1&page_size=3` * Response: + * 按区块号降序排列(order by block num desc) ```json { - "code": 200, - "data": { - "amount": 96442598104, - "block_hash": "53E86050C1B6519B8A6B6A09086810A92B97DC2905F6C14BF319B5D694CF74EF", - "from": "fra1vrvnc9kfnnl02rhafvdn4yssll4rz0flfc73xkj3w9tlsggy38rskgv35t", - "height": 5162087, - "new_delegator": "5ax5Bb8xQ4Ag7eV_cA8PGAAJ2_M-BPZhrF3R5uzd17o=", - "target_validator": "E012AA66C83999E3862C8AA534B9CE66FC14A37A", - "timestamp": 1705780393, - "tx_hash": "583d9071df8299978e227d4b62d122225e4d2bc7fce0f581b4396b5c35f63dbd", - "value": { - "UnDelegation": { - "body": { - "nonce": [ - [90, 0, 11, 166, 133, 201, 223, 219], 129078 - ], - "pu": { - "am": 96442598104, - "new_delegator_id": "5ax5Bb8xQ4Ag7eV_cA8PGAAJ2_M-BPZhrF3R5uzd17o=", - "target_validator": [224, 18, 170, 102, 200, 57, 153, 227, 134, 44, 138, 165, 52, 185, 206, 102, 252, 20, 163, 122] - } - }, - "pubkey": "YNk8Fsmc_vUO_UsbOpIQ_-oxPT9OPRNaUXFX-CEEicc=", - "signature": "0bwIKjNsCqfDMPp6iAtOM81nMHw4voGwyl_YjNazfx2A6Wt-BWWR0B-bruWANPMNncGRbBuYs2Brjigd566LAw==" - } - } - }, - "message": "" + "total": 250689, + "page": 1, + "page_size": 3, + "data": [{ + "block_hash": "2621F0BC18118219C345669FD254993C0AA50DBBCAF735E800D85F41077E9A53", + "block_num": 250689, + "app_hash": "7973F6BFDEDD343D5D62487D52C8D455C813EF4C95D4087B42FFE3C6DE398E89", + "proposer": "9ED0D8D661C99A58F78F80816968E61AAE8DC649", + "num_txs": 1, + "block_size": 27329, + "block_id": { + "hash": "2621F0BC18118219C345669FD254993C0AA50DBBCAF735E800D85F41077E9A53", + "parts": { + "total": "1", + "hash": "02B417177063ABE02573919038033A0CE8C9412959F4B2A6A8A579CFF22F3E04" + } + }, + "block_header": { + "version": { + "block": "10", + "app": "0" + }, + "chain_id": "chain-qILMsV", + "height": "250689", + "time": "2023-08-16T00:03:29.377015421Z", + "last_block_id": { + "hash": "040BBDC5494443DCE1D018C6AB7F23C6EABAB0DFC0CF4292D094306C4800044D", + "parts": { + "total": "1", + "hash": "8F22B438D22E4A45C38AE31736A1BFD33A092BD653A23081C4B69EC23FEEDD57" + } + }, + "last_commit_hash": "A8A28345ED16CD478AF22715E3CA577DA15E0E1DAE4155DD0478165A4723822A", + "data_hash": "339281320D9F759E2FF6B95257A912B0D7343D76E413D66A66BDCFA642536479", + "validators_hash": "4507ECDC1FCB92A824F0DC3082D0A528379051D78F682DE0ECD3BAE185654FE2", + "next_validators_hash": "4507ECDC1FCB92A824F0DC3082D0A528379051D78F682DE0ECD3BAE185654FE2", + "consensus_hash": "048091BC7DDC283F77BFBF91D73C44DA58C3DF8A9CBC867405D8B7F3DAADA22F", + "app_hash": "7973F6BFDEDD343D5D62487D52C8D455C813EF4C95D4087B42FFE3C6DE398E89", + "last_results_hash": "", + "evidence_hash": "", + "proposer_address": "9ED0D8D661C99A58F78F80816968E61AAE8DC649" + } + }, + { + "block_hash": "81660C94CCD8C5F6E7D764DC6BDFFB86600A14BB07A97674CDAA9ECE7C763D62", + "block_num": 250689, + "app_hash": "CA3D39B3D00A6C869FB4B6D8728752711C306069FC2200D88A863AFC38D926DB", + "proposer": "8CB713C8EA32223FCAC66B966FCFA9BAEE257946", + "num_txs": 0, + "block_size": 2506, + "block_id": { + "hash": "81660C94CCD8C5F6E7D764DC6BDFFB86600A14BB07A97674CDAA9ECE7C763D62", + "parts": { + "total": "1", + "hash": "187164D9E4A8354D44C84D12E076EE6F5A49C442638260E938C72FD020784BBC" + } + }, + "block_header": { + "version": { + "block": "10", + "app": "0" + }, + "chain_id": "chain-qILMsV", + "height": "250689", + "time": "2021-05-14T15:19:39.860658429Z", + "last_block_id": { + "hash": "D0CEE991CC9546D80AD916D642C33356EE86E19598CB68F9CAE32ABA2C16F354", + "parts": { + "total": "1", + "hash": "4F656F2E9FA2200E888C597A72C1D5537FE943B4E7EA17172C4851FB12EF9335" + } + }, + "last_commit_hash": "8DD8A37D6ACED561F10BAC7D17232F73992F86F528AC6FE2554F734FE244479E", + "data_hash": "", + "validators_hash": "EC4E07BBE9EE84C39699C844D32CA8739FD8145D28F6B4DE7E8DF09326212D76", + "next_validators_hash": "EC4E07BBE9EE84C39699C844D32CA8739FD8145D28F6B4DE7E8DF09326212D76", + "consensus_hash": "048091BC7DDC283F77BFBF91D73C44DA58C3DF8A9CBC867405D8B7F3DAADA22F", + "app_hash": "CA3D39B3D00A6C869FB4B6D8728752711C306069FC2200D88A863AFC38D926DB", + "last_results_hash": "", + "evidence_hash": "", + "proposer_address": "8CB713C8EA32223FCAC66B966FCFA9BAEE257946" + } + }, { + "block_hash": "A56EF951D6886B61B459564FAA7535AC307A056837E30B10F85415DEF506CB79", + "block_num": 245136, + "app_hash": "679BCBCFCB71F63E92BBCFE558C51BDD5BC4374163C2D228DFEAB3900B1F2030", + "proposer": "510082967DFA7DEBA11267B26A6318D07A457B48", + "num_txs": 1, + "block_size": 3060, + "block_id": { + "hash": "A56EF951D6886B61B459564FAA7535AC307A056837E30B10F85415DEF506CB79", + "parts": { + "total": "1", + "hash": "99F8154239ADAD37789D56611BC964C753AA23FD2FDDE94DE22B5521EBC1FBBA" + } + }, + "block_header": { + "version": { + "block": "10", + "app": "0" + }, + "chain_id": "chain-qILMsV", + "height": "245136", + "time": "2023-08-15T07:32:23.666042021Z", + "last_block_id": { + "hash": "803E22897FCC4A8147C6E2F3BC21DA3383FD5FD7CDD2B8AA4377300428F530FC", + "parts": { + "total": "1", + "hash": "D8C9EC1C2C661AC8C256498C29875FBE99055A29E6684907A9FB03B6757F49EC" + } + }, + "last_commit_hash": "7DBAA7155E53AA9C36DC7B7C44763BCA3397BB5E98FC6F0B346AAEAE2D0F9A0C", + "data_hash": "E41848E603B37A0527759A10372C9B97DCA45B1EBCFCB3C9ABCC06AAC82FD254", + "validators_hash": "4507ECDC1FCB92A824F0DC3082D0A528379051D78F682DE0ECD3BAE185654FE2", + "next_validators_hash": "4507ECDC1FCB92A824F0DC3082D0A528379051D78F682DE0ECD3BAE185654FE2", + "consensus_hash": "048091BC7DDC283F77BFBF91D73C44DA58C3DF8A9CBC867405D8B7F3DAADA22F", + "app_hash": "679BCBCFCB71F63E92BBCFE558C51BDD5BC4374163C2D228DFEAB3900B1F2030", + "last_results_hash": "", + "evidence_hash": "", + "proposer_address": "510082967DFA7DEBA11267B26A6318D07A457B48" + } + }] } ``` -

1.9 获取交易

-* `GET /api/v2/txs` -* 参数 - -| 参数 | 类型 | 必传 | 说明 | -|--------------|--------|----|-------| -| block_hash | string | N | 区块哈希 | -| block_height | number | N | 区块高度 | -| from | string | N | 发送者地址 | -| to | string | N | 接收者地址 | -| ty | number | N | 交易类型 | -| start_time | number | N | 开始时间戳 | -| end_time | number | N | 截止时间戳 | -| page | number | N | 页码 | -| page_size | number | N | 页大小 | - -* Request: `/api/v2/txs?page=1&page_size=2` -* Response: - * 按timestamp降序排列 -```json -{ - "code": 200, - "data": { - "page": 1, - "page_size": 2, - "total": 2460630, - "txs": [{ - "block_hash": "B92B8B1AB4BB145AA66E4EA245706A8F833AD7FBED02D2603CA9003CD0324E9D", - "code": 0, - "evm_tx_hash": "", - "height": 5478292, - "log": "", - "origin": "ZXZtOnsic2lnbmF0dXJlIjpudWxsLCJmdW5jdGlvbiI6eyJFdGhlcmV1bSI6eyJUcmFuc2FjdCI6eyJub25jZSI6IjB4OTBiOTAiLCJnYXNfcHJpY2UiOiIweDI1NDBiZTQwMCIsImdhc19saW1pdCI6IjB4MjQ5ZjAiLCJhY3Rpb24iOnsiQ2FsbCI6IjB4YjUyZWYyOTI2NTFmODY5MjA1M2FjM2QzOTkyMWE0M2ZlMTM1MzNjOCJ9LCJ2YWx1ZSI6IjB4MCIsImlucHV0IjpbMTk4LDY0LDExNyw0NSwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwxNzUsMjUsMTA4LDQ1LDEyMCwxMTIsMTgxLDIwLDExMSwyLDIxMiwxNTUsMSwyOSwyNDksMjUsMTI0LDksNjMsMjU0LDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDE2LDBdLCJzaWduYXR1cmUiOnsidiI6NDM0MCwiciI6IjB4OWUwNmExYjhjYzBmMjFiYzBmMTZiZTk1YzAzNjY5ZDQxMzE1NWE1M2E0ODc4MTJkNTUzNGFlY2JmNDViMjJjYiIsInMiOiIweDJiYmZkNDZjYzQwZDc5OWI2MjhlMjVmMzE4NmNjODZmNmU2YWRiZDE2NTU2ZWFmNDIwMzNmNjA4NTBiOWU4ODgifX19fX0=", - "result": { - "code": 0, - "codespace": "", - "data": "eyJDYWxsIjp7ImV4aXRfcmVhc29uIjp7IlN1Y2NlZWQiOiJTdG9wcGVkIn0sInZhbHVlIjpbXSwidXNlZF9nYXMiOiIweDlkNmIiLCJsb2dzIjpbXX19", - "events": [{ - "attributes": [{ - "key": "c2VuZGVy", - "value": "MHhkM2UwNzViZDAzMTQ5MDk3ZmExMzViMThhODc1NmI1MDI0YTQ1ZTVl" - }, { - "key": "dG8=", - "value": "MHhiNTJlZjI5MjY1MWY4NjkyMDUzYWMzZDM5OTIxYTQzZmUxMzUzM2M4" - }, { - "key": "Y29udHJhY3RfYWRkcmVzcw==", - "value": "MHgwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw" - }, { - "key": "dHJhbnNhY3Rpb25faGFzaA==", - "value": "MHg3MzgxYWEyMTBiMWJjMmU4NmYxMTExN2Q5ZTFlODZjYmYyYmU2ZWE2YjdhZWQwODhiZjk2N2MzNmJjZjA5MGIw" - }, { - "key": "cmVhc29u", - "value": "U3VjY2VlZChTdG9wcGVkKQ==" - }], - "type": "ethereum_TransactionExecuted" - }], - "gasUsed": "40299", - "gasWanted": "150000", - "info": "", - "log": "" - }, - "timestamp": 1712037200, - "tx_hash": "11969300f45e0db1b5a74a1c102a252a2b443cb5cb1346e41d30bed234b4efe3", - "ty": 1, - "value": { - "function": { - "Ethereum": { - "Transact": { - "action": { - "Call": "0xb52ef292651f8692053ac3d39921a43fe13533c8" - }, - "from": "0xd3e075bd03149097fa135b18a8756b5024a45e5e", - "gas_limit": "0x249f0", - "gas_price": "0x2540be400", - "input": [198, 64, 117, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 175, 25, 108, 45, 120, 112, 181, 20, 111, 2, 212, 155, 1, 29, 249, 25, 124, 9, 63, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0], - "nonce": "0x90b90", - "signature": { - "r": "0x9e06a1b8cc0f21bc0f16be95c03669d413155a53a487812d5534aecbf45b22cb", - "s": "0x2bbfd46cc40d799b628e25f3186cc86f6e6adbd16556eaf42033f60850b9e888", - "v": 4340 - }, - "value": "0x0" - } - } - } - } - }, { - "block_hash": "8C4C163BCC93062974D2D5E6165DD0C399EAA1BAF615901610197C9F37509E2E", - "code": 0, - "evm_tx_hash": "", - "height": 5478291, - "log": "", - "origin": "ZXZtOnsic2lnbmF0dXJlIjpudWxsLCJmdW5jdGlvbiI6eyJFdGhlcmV1bSI6eyJUcmFuc2FjdCI6eyJub25jZSI6IjB4OTBiOGYiLCJnYXNfcHJpY2UiOiIweDI1NDBiZTQwMCIsImdhc19saW1pdCI6IjB4MjQ5ZjAiLCJhY3Rpb24iOnsiQ2FsbCI6IjB4YjUyZWYyOTI2NTFmODY5MjA1M2FjM2QzOTkyMWE0M2ZlMTM1MzNjOCJ9LCJ2YWx1ZSI6IjB4MCIsImlucHV0IjpbMTk4LDY0LDExNyw0NSwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwxNiwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDYsNTAsMTg2LDE2Miw5OCwxNTMsMjAxLDE1MSw0NiwyMTIsMjE3LDE3NSwyNTAsNjMsMjA4LDg3LDE2NywzNCw4MiwyNTVdLCJzaWduYXR1cmUiOnsidiI6NDM0MCwiciI6IjB4OTc0ZDBkYjQ1ZTQxMDM2ZmI3YjFmM2Q3ODNkZGE1ZTVlYjM4NTM4YzlmMzNhYzdmNjkxODk2YmY3OGU0MjhlNCIsInMiOiIweDFlOWYxMWVhYjRmMDU2MGFhNDU3ZTQ5OGI0ODg5ZmI0N2JhODRiNjY3MjhkODJkNjMwNjNhMWZjZjM0NzI3MjYifX19fX0=", - "result": { - "code": 0, - "codespace": "", - "data": "eyJDYWxsIjp7ImV4aXRfcmVhc29uIjp7IlN1Y2NlZWQiOiJTdG9wcGVkIn0sInZhbHVlIjpbXSwidXNlZF9nYXMiOiIweDlkNmIiLCJsb2dzIjpbXX19", - "events": [{ - "attributes": [{ - "key": "c2VuZGVy", - "value": "MHhkM2UwNzViZDAzMTQ5MDk3ZmExMzViMThhODc1NmI1MDI0YTQ1ZTVl" - }, { - "key": "dG8=", - "value": "MHhiNTJlZjI5MjY1MWY4NjkyMDUzYWMzZDM5OTIxYTQzZmUxMzUzM2M4" - }, { - "key": "Y29udHJhY3RfYWRkcmVzcw==", - "value": "MHgwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw" - }, { - "key": "dHJhbnNhY3Rpb25faGFzaA==", - "value": "MHgzNGU4NzRjNzAxNDdlZmIxOGE5ODM0ZDkxMTg1YTI3ZTI1YjFjZWY1YTAwOTBjYTBmNzVjMjMyYTAxM2QyMWFi" - }, { - "key": "cmVhc29u", - "value": "U3VjY2VlZChTdG9wcGVkKQ==" - }], - "type": "ethereum_TransactionExecuted" - }], - "gasUsed": "40299", - "gasWanted": "150000", - "info": "", - "log": "" - }, - "timestamp": 1712037185, - "tx_hash": "039a2481e3b7b81dfb344e0627fca9bccb8e249f18b5892fd234833e128995a5", - "ty": 1, - "value": { - "function": { - "Ethereum": { - "Transact": { - "action": { - "Call": "0xb52ef292651f8692053ac3d39921a43fe13533c8" - }, - "from": "0xd3e075bd03149097fa135b18a8756b5024a45e5e", - "gas_limit": "0x249f0", - "gas_price": "0x2540be400", - "input": [198, 64, 117, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 50, 186, 162, 98, 153, 201, 151, 46, 212, 217, 175, 250, 63, 208, 87, 167, 34, 82, 255], - "nonce": "0x90b8f", - "signature": { - "r": "0x974d0db45e41036fb7b1f3d783dda5e5eb38538c9f33ac7f691896bf78e428e4", - "s": "0x1e9f11eab4f0560aa457e498b4889fb47ba84b66728d82d63063a1fcf3472726", - "v": 4340 - }, - "value": "0x0" - } - } - } - } - }] - }, - "message": "" -} -``` -

1.10 获取用户发出的prism交易记录

-* `GET /v2/tx/prism/send` diff --git a/explorer/Cargo.toml b/explorer/Cargo.toml index 5884ddd..ab1c937 100644 --- a/explorer/Cargo.toml +++ b/explorer/Cargo.toml @@ -24,8 +24,12 @@ ethereum-types = "0.14.1" ethereum = { version = "0.15.0", default-features = false, features = ["with-serde"] } sha3 = { version = "0.10.4", default-features = false } hex = "0.4.3" +axum = "0.7.5" +tower-http = { version = "0.5.2", features = ["cors"] } +rustc-hex = "2.1.0" zei = { git = "https://github.com/FindoraNetwork/zei", branch = "stable-main" } module = { path = "../module" } scanner = {path = "../scanner"} +url = "2.5.0" diff --git a/explorer/src/config.toml b/explorer/src/config.toml index 257bcc5..039ec7c 100644 --- a/explorer/src/config.toml +++ b/explorer/src/config.toml @@ -4,9 +4,9 @@ [postgres] account = "postgres" - password = "123456" + password = "csq2400306" addr = "localhost" - database = "test" + database = "postgres" [rpc] tendermint = "https://prod-mainnet.prod.findora.org:26657/" diff --git a/explorer/src/main.rs b/explorer/src/main.rs index f9c4af6..7798a18 100644 --- a/explorer/src/main.rs +++ b/explorer/src/main.rs @@ -1,15 +1,19 @@ mod service; use crate::service::api::Api; +use crate::service::v2::block::{get_block_by_hash, get_block_by_num, get_blocks}; use anyhow::Result; +use axum::http::Method; +use axum::routing::get; +use axum::Router; use log::info; -use poem::middleware::Cors; -use poem::{listener::TcpListener, EndpointExt, Route, Server}; -use poem_openapi::OpenApiService; -use scanner::rpc::TendermintRPC; use sqlx::pool::PoolOptions; -use sqlx::{Pool, Postgres}; -use std::time::Duration; -use tokio::sync::Mutex; +use sqlx::{PgPool, Pool, Postgres}; +use std::sync::Arc; +use tower_http::cors::{Any, CorsLayer}; + +struct AppState { + pub pool: PgPool, +} #[tokio::main] async fn main() -> Result<()> { @@ -25,48 +29,29 @@ async fn main() -> Result<()> { ); let pool: Pool = PoolOptions::new() - .max_connections(10) + .max_connections(50) .connect(&postgres_config) .await .unwrap(); info!("Connecting DB...ok"); - // tendermint rpc - let tendermint_rpc_client = TendermintRPC::new( - Duration::from_secs(60), - config.rpc.tendermint.to_string().parse().unwrap(), - ); - let platform_rpc_client = TendermintRPC::new( - Duration::from_secs(60), - config.rpc.platform.to_string().parse().unwrap(), - ); - let platform_server_rpc_client = TendermintRPC::new( - Duration::from_secs(60), - config.rpc.platform_server.to_string().parse().unwrap(), - ); - - let api = Api { - platform: platform_rpc_client, - platform_server: platform_server_rpc_client, - tendermint: tendermint_rpc_client, - storage: Mutex::new(pool), - }; - - let server_config = format!("http://{}:{}/api", config.server.addr, config.server.port); - let api_service = OpenApiService::new(api, "explorer", "1.0").server(server_config); - let ui = api_service.swagger_ui(); + let app_state = Arc::new(AppState { pool }); + let cors = CorsLayer::new() + .allow_methods([Method::GET, Method::POST, Method::OPTIONS]) + .allow_origin(Any) + .allow_headers(Any); + let addr = format!("{}:{}", config.server.addr, config.server.port); + let app = Router::new() + .route("/api/v2/block/number", get(get_block_by_num)) + .route("/api/v2/block/hash", get(get_block_by_hash)) + .route("/api/v2/blocks", get(get_blocks)) + .layer(cors) + .with_state(app_state); + let listener = tokio::net::TcpListener::bind(&addr).await.unwrap(); - let server_addr = format!("{}:{}", config.server.addr, config.server.port); - let cors = Cors::new(); + info!("Listening at: {}", addr); info!("Starting server...ok"); - Server::new(TcpListener::bind(server_addr)) - .run( - Route::new() - .nest("/api", api_service) - .nest("/", ui) - .with(cors), - ) - .await?; + axum::serve(listener, app).await.unwrap(); Ok(()) } diff --git a/explorer/src/service/api.rs b/explorer/src/service/api.rs index 8e5274c..7b1df10 100644 --- a/explorer/src/service/api.rs +++ b/explorer/src/service/api.rs @@ -1,43 +1,3 @@ -use crate::service; -use crate::service::util::handle_fetch_one_err; -use crate::service::v1::address::AddressResponse; -use crate::service::v1::asset::{ - AssetListResponse, AssetResponse, IssueAssetResponse, SingleIssueAssetResponse, -}; -use crate::service::v1::block::{BlocksResponse, FullBlockResponse, SimpleBlockResponse}; -use crate::service::v1::chain::{ - AddressCountResponse, ChainStatisticsResponse, DistributeResponse, -}; -use crate::service::v1::price::{MarketChartResponse, SimplePriceResponse}; -use crate::service::v1::staking::{ - ClaimResponse, DelegationResponse, SimpleDelegationResponse, UnDelegationResponse, - UndelegationResponse, -}; -use crate::service::v1::transaction::{ - PmtxsResponse, TxResponse, TxsResponse, V2PrismRecordResponse, -}; -use crate::service::v1::validator::CirculatingSupplyResponse; -use crate::service::v2::asset::{v2_get_asset, v2_get_asset_list, V2AssetTxResponse}; -use crate::service::v2::claim::{v2_get_claim, v2_get_claims, V2ClaimResponse, V2ClaimsResponse}; -use crate::service::v2::delegation::{ - v2_get_delegation, v2_get_delegations, V2DelegationResponse, V2DelegationsResponse, -}; - -use crate::service::v2::evm_to_native::V2EvmToNativeTxsResponse; -use crate::service::v2::native_to_evm::V2NativeToEvmTxsResponse; -use crate::service::v2::native_to_evm::{ - v2_get_n2e_tx, v2_get_prism_records_send, V2NativeToEvmTxResponse, -}; -use crate::service::v2::other::{ - v2_address_count, v2_distribute, v2_statistics, V2ChainStatisticsResponse, V2DistributeResponse, -}; -use crate::service::v2::transaction::v2_get_txs; -use crate::service::v2::undelegation::{ - v2_get_undelegation, v2_get_undelegations, V2UndelegationResponse, V2UndelegationsResponse, -}; -use crate::service::ApiTags; -use poem_openapi::param::{Path, Query}; -use poem_openapi::OpenApi; use scanner::rpc::TendermintRPC; use sqlx::{Pool, Postgres}; use tokio::sync::Mutex; @@ -50,946 +10,946 @@ pub struct Api { pub(crate) storage: Mutex>, } -#[OpenApi] -impl Api { - #[oai(path = "/tx/:tx_hash", method = "get", tag = "ApiTags::Transaction")] - async fn get_tx( - &self, - /// tx hash, e.g. c19fc22beb61030607367b42d4898a26ede1e6aa6b400330804c95b241f29bd0 - tx_hash: Path, - ) -> poem::Result { - service::v1::transaction::get_tx(self, tx_hash) - .await - .map_err(handle_fetch_one_err) - } - - #[oai( - path = "/tx/evm/:tx_hash", - method = "get", - tag = "ApiTags::Transaction" - )] - async fn get_evm_tx( - &self, - /// evm tx hash, e.g. 0x697c0492b64b8e786061818c12af46e9b62b9ee20e573d7549e7a82e94ef13cf - tx_hash: Path, - ) -> poem::Result { - service::v1::transaction::get_evm_tx(self, tx_hash) - .await - .map_err(handle_fetch_one_err) - } - - // #[oai(path = "/txs/to", method = "get", tag = "ApiTags::Transaction")] - // async fn get_txs_send_to( - // &self, - // /// bech32 address, e.g. fra1p4vy5n9mlkdys7xczegj398xtyvw2nawz00nnfh4yr7fpjh297cqsxfv7v - // address: Query, - // /// page index, the default is 1. - // page: Query>, - // /// page size, the default is 10. - // page_size: Query>, - // ) -> poem::Result { - // service::v1::transaction::get_txs_send_to(self, address, page, page_size) - // .await - // .map_err(handle_fetch_one_err) - // } - - // #[oai(path = "/txs/from", method = "get", tag = "ApiTags::Transaction")] - // async fn get_txs_receive_from( - // &self, - // /// bech32 address, e.g. fra1p4vy5n9mlkdys7xczegj398xtyvw2nawz00nnfh4yr7fpjh297cqsxfv7v - // address: Query, - // /// page index, the default is 1. - // page: Query>, - // /// page size, the default is 10. - // page_size: Query>, - // ) -> poem::Result { - // service::v1::transaction::get_txs_receive_from(self, address, page, page_size) - // .await - // .map_err(handle_fetch_one_err) - // } - - #[allow(clippy::too_many_arguments)] - #[oai(path = "/txs", method = "get", tag = "ApiTags::Transaction")] - async fn get_txs( - &self, - /// block hash, e.g. 4B7C22FA8FC6913E091DC324830181BBA1F01EBFF53049F958EA5AA65327BFE0 - block_id: Query>, - /// block height. - height: Query>, - /// bech32 address, e.g. fra1p4vy5n9mlkdys7xczegj398xtyvw2nawz00nnfh4yr7fpjh297cqsxfv7v - from: Query>, - /// bech32 address, e.g. fra1p4vy5n9mlkdys7xczegj398xtyvw2nawz00nnfh4yr7fpjh297cqsxfv7v - to: Query>, - /// transaction type. - /// 0 - Findora native tx. - /// 1 - EVM tx. - ty: Query>, - /// starting timestamp. - start_time: Query>, - /// ending timestamp. - end_time: Query>, - /// page index, the default is 1. - page: Query>, - /// page size, the default is 10. - page_size: Query>, - ) -> poem::Result { - service::v1::transaction::get_txs( - self, block_id, height, from, to, ty, start_time, end_time, page, page_size, - ) - .await - .map_err(handle_fetch_one_err) - } - - // #[allow(clippy::too_many_arguments)] - // #[oai(path = "/txs/raw", method = "get", tag = "ApiTags::Transaction")] - // async fn get_txs_no_wrap( - // &self, - // /// block hash, e.g. 4B7C22FA8FC6913E091DC324830181BBA1F01EBFF53049F958EA5AA65327BFE0 - // block_id: Query>, - // /// block height. - // height: Query>, - // /// bech32 address, e.g. fra1p4vy5n9mlkdys7xczegj398xtyvw2nawz00nnfh4yr7fpjh297cqsxfv7v - // address: Query>, - // /// bech32 address, e.g. fra1p4vy5n9mlkdys7xczegj398xtyvw2nawz00nnfh4yr7fpjh297cqsxfv7v - // from: Query>, - // /// bech32 address, e.g. fra1p4vy5n9mlkdys7xczegj398xtyvw2nawz00nnfh4yr7fpjh297cqsxfv7v - // to: Query>, - // /// transaction type. - // /// 0 - Findora native tx. - // /// 1 - EVM tx. - // ty: Query>, - // /// starting timestamp. - // start_time: Query>, - // /// ending timestamp. - // end_time: Query>, - // /// page index, the default is 1. - // page: Query>, - // /// page size, the default is 10. - // page_size: Query>, - // ) -> poem::Result { - // service::v1::transaction::get_txs_raw( - // self, block_id, height, address, from, to, ty, start_time, end_time, page, page_size, - // ) - // .await - // .map_err(handle_fetch_one_err) - // } - - #[allow(clippy::too_many_arguments)] - #[oai( - path = "/txs/triple_masking", - method = "get", - tag = "ApiTags::Transaction" - )] - async fn get_triple_masking_txs( - &self, - /// block hash, e.g. 4B7C22FA8FC6913E091DC324830181BBA1F01EBFF53049F958EA5AA65327BFE0 - block_id: Query>, - /// public key, e.g. b2fdE7jKfQg_XL2CT7jdw84XkTdpX3uiRgpgW-h6k6o=. - pub_key: Query>, - /// 0 - default, querying both AbarToBar and BarToAbar. - /// 1 - AbarToBar. - /// 2 - BarToAbar. - bar: Query>, - /// starting timestamp. - start_time: Query>, - /// ending timestamp. - end_time: Query>, - /// page index, the default is 1. - page: Query>, - /// page size, the default is 10. - page_size: Query>, - ) -> poem::Result { - service::v1::transaction::get_triple_masking_txs( - self, block_id, pub_key, bar, start_time, end_time, page, page_size, - ) - .await - .map_err(handle_fetch_one_err) - } - - #[oai(path = "/txs/claim", method = "get", tag = "ApiTags::Transaction")] - async fn get_claim_txs( - &self, - /// block hash. - block_id: Query>, - /// public key. - pub_key: Query>, - /// starting timestamp. - start_time: Query>, - /// ending timestamp. - end_time: Query>, - /// page index, the default is 1. - page: Query>, - /// page size, the default is 10. - page_size: Query>, - ) -> poem::Result { - service::v1::transaction::get_claim_txs( - self, block_id, pub_key, start_time, end_time, page, page_size, - ) - .await - .map_err(handle_fetch_one_err) - } - - #[allow(clippy::too_many_arguments)] - #[oai( - path = "/txs/prism/:address", - method = "get", - tag = "ApiTags::Transaction" - )] - async fn get_prism_tx( - &self, - /// Bridge Contract deploy address, e.g. 0x2B7835AE05C9Cb5EF086e3BFe249e2658b450E8d - address: Path, - /// starting timestamp. - start_time: Query>, - /// ending timestamp. - end_time: Query>, - /// page index, the default is 1. - page: Query>, - /// page size, the default is 10. - page_size: Query>, - ) -> poem::Result { - service::v1::transaction::get_prism_tx(self, address, start_time, end_time, page, page_size) - .await - .map_err(handle_fetch_one_err) - } - - #[oai(path = "/block/height/:height", method = "get", tag = "ApiTags::Block")] - async fn get_block_by_height( - &self, - /// block height. - height: Path, - ) -> poem::Result { - service::v1::block::get_simple_block_by_height(self, height) - .await - .map_err(handle_fetch_one_err) - } - - #[oai( - path = "/block/full/height/:height", - method = "get", - tag = "ApiTags::Block" - )] - async fn get_full_block_by_height( - &self, - /// block height. - height: Path, - ) -> poem::Result { - service::v1::block::get_full_block_by_height(self, height) - .await - .map_err(handle_fetch_one_err) - } - - #[oai(path = "/block/hash/:hash", method = "get", tag = "ApiTags::Block")] - async fn get_block_by_hash( - &self, - /// block hash. - hash: Path, - ) -> poem::Result { - service::v1::block::get_simple_block_by_hash(self, hash) - .await - .map_err(handle_fetch_one_err) - } - - #[oai( - path = "/block/full/hash/:hash", - method = "get", - tag = "ApiTags::Block" - )] - async fn get_full_block_by_hash( - &self, - /// block hash. - hash: Path, - ) -> poem::Result { - service::v1::block::get_full_block_by_hash(self, hash) - .await - .map_err(handle_fetch_one_err) - } - - #[oai(path = "/blocks", method = "get", tag = "ApiTags::Block")] - async fn get_blocks( - &self, - /// starting height. - start_height: Query>, - /// ending height. - end_height: Query>, - /// starting timestamp. - start_time: Query>, - /// ending timestamp. - end_time: Query>, - /// page index, the default is 1. - page: Query>, - /// page size, the default is 10. - page_size: Query>, - ) -> poem::Result { - service::v1::block::get_blocks( - self, - start_height, - end_height, - start_time, - end_time, - page, - page_size, - ) - .await - .map_err(handle_fetch_one_err) - } - - #[oai(path = "/address/:address", method = "get", tag = "ApiTags::Address")] - async fn get_address( - &self, - /// bech32 address, e.g. fra1p4vy5n9mlkdys7xczegj398xtyvw2nawz00nnfh4yr7fpjh297cqsxfv7v - address: Path, - /// page index, the default is 1. - page: Query>, - /// page size, the default is 10. - page_size: Query>, - ) -> poem::Result { - service::v1::address::get_address(self, address, page, page_size) - .await - .map_err(handle_fetch_one_err) - } - - #[oai(path = "/asset/:code", method = "get", tag = "ApiTags::Asset")] - async fn get_asset( - &self, - /// base64 asset code, e.g. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= - code: Path, - ) -> poem::Result { - service::v1::asset::get_asset(self, code) - .await - .map_err(handle_fetch_one_err) - } - - #[oai(path = "/asset/list", method = "get", tag = "ApiTags::Asset")] - async fn get_asset_list( - &self, - page: Query>, - page_size: Query>, - ) -> poem::Result { - service::v1::asset::get_asset_list(self, page, page_size) - .await - .map_err(handle_fetch_one_err) - } - - #[oai(path = "/asset/issued/list", method = "get", tag = "ApiTags::Asset")] - async fn get_issued_asset_list( - &self, - page: Query>, - page_size: Query>, - ) -> poem::Result { - service::v1::asset::get_issued_asset_list(self, page, page_size) - .await - .map_err(handle_fetch_one_err) - } - - #[oai(path = "/asset/issued/:code", method = "get", tag = "ApiTags::Asset")] - async fn get_issued_asset( - &self, - /// base64 asset code, e.g. dPJSy9DnxJgUiMheXphWloPfnvKQDCl7LoNfhHjaimM= - code: Path, - ) -> poem::Result { - service::v1::asset::get_issued_asset(self, code) - .await - .map_err(handle_fetch_one_err) - } - - #[oai( - path = "/chain/statistics", - method = "get", - tag = "ApiTags::BlockChain" - )] - async fn statistics( - &self, - /// tx type, 0 - Findora native tx, 1 - EVM tx. - ty: Query>, - ) -> poem::Result { - service::v1::chain::statistics(self, ty) - .await - .map_err(handle_fetch_one_err) - } - - // #[oai( - // path = "/chain/validator_list", - // method = "get", - // tag = "ApiTags::BlockChain" - // )] - // async fn validator_list(&self) -> poem::Result { - // service::v1::validator::validator_list(self) - // .await - // .map_err(handle_fetch_one_err) - // } - - // #[oai( - // path = "/chain/validator_detail/:address", - // method = "get", - // tag = "ApiTags::BlockChain" - // )] - // async fn validator_detail( - // &self, - // /// validator address, e.g. 917454FB61CFBDB1995BC57C7A821E41FFB1AF43 - // address: Path, - // ) -> poem::Result { - // service::v1::validator::validator_detail(self, address) - // .await - // .map_err(handle_fetch_one_err) - // } - - #[oai( - path = "/chain/circulating_supply", - method = "get", - tag = "ApiTags::BlockChain" - )] - async fn circulating_supply(&self) -> poem::Result { - service::v1::validator::circulating_supply(self) - .await - .map_err(handle_fetch_one_err) - } - - // #[oai( - // path = "/chain/validator/signed_count", - // method = "get", - // tag = "ApiTags::BlockChain" - // )] - // async fn validator_signed_count( - // &self, - // /// validator address, e.g. 917454FB61CFBDB1995BC57C7A821E41FFB1AF43 - // address: Query, - // /// page index, the default is 1. - // page: Query>, - // /// page size, the default is 10. - // page_size: Query>, - // ) -> poem::Result { - // service::v1::validator::validator_signed_count(self, address, page, page_size) - // .await - // .map_err(handle_fetch_one_err) - // } - - // #[oai( - // path = "/chain/delegator_list/:address", - // method = "get", - // tag = "ApiTags::BlockChain" - // )] - // async fn delegator_list( - // &self, - // /// delegator address, e.g. 000E33AB7471186F3B1DE9FC08BB9C480F453590 - // address: Path, - // ) -> poem::Result { - // service::v1::validator::delegator_list(self, address) - // .await - // .map_err(handle_fetch_one_err) - // } - - #[oai(path = "/simple/price", method = "get", tag = "ApiTags::Price")] - async fn simple_price( - &self, - ids: Query, - vs_currencies: Query, - ) -> poem::Result { - service::v1::price::simple_price(self, ids, vs_currencies) - .await - .map_err(handle_fetch_one_err) - } - - #[oai( - path = "/coins/:id/market_chart", - method = "get", - tag = "ApiTags::Price" - )] - async fn market_chart( - &self, - id: Path, - vs_currency: Query, - interval: Query>, - days: Query, - ) -> poem::Result { - service::v1::price::market_chart(self, id, vs_currency, interval, days) - .await - .map_err(handle_fetch_one_err) - } - - #[oai(path = "/address/count", method = "get", tag = "ApiTags::Address")] - async fn address_count( - &self, - /// staring timestamp. - start_time: Query, - /// ending timestamp. - end_time: Query, - ) -> poem::Result { - service::v1::chain::address_count(self, start_time, end_time) - .await - .map_err(handle_fetch_one_err) - } - - #[oai(path = "/txs/distribute", method = "get", tag = "ApiTags::Transaction")] - async fn distribute(&self) -> poem::Result { - service::v1::chain::distribute(self) - .await - .map_err(handle_fetch_one_err) - } - - // #[oai( - // path = "/chain/validator_delegation", - // method = "get", - // tag = "ApiTags::BlockChain" - // )] - // async fn validator_delegation( - // &self, - // /// validator address, e.g. 000E33AB7471186F3B1DE9FC08BB9C480F453590 - // address: Query, - // ) -> poem::Result { - // service::v1::validator::validator_delegation(self, address) - // .await - // .map_err(handle_fetch_one_err) - // } - - #[oai( - path = "/v2/txs/prism/e2n", - method = "get", - tag = "ApiTags::Transaction" - )] - async fn get_prism_e2n_txs( - &self, - page: Query>, - page_size: Query>, - ) -> poem::Result { - service::v2::evm_to_native::v2_get_e2n_txs(self, page, page_size) - .await - .map_err(handle_fetch_one_err) - } - - #[oai( - path = "/v2/txs/prism/n2e", - method = "get", - tag = "ApiTags::Transaction" - )] - async fn get_prism_n2e_txs( - &self, - page: Query>, - page_size: Query>, - ) -> poem::Result { - service::v2::native_to_evm::v2_get_n2e_txs(self, page, page_size) - .await - .map_err(handle_fetch_one_err) - } - - #[oai( - path = "/tx/prism/records/receive", - method = "get", - tag = "ApiTags::Transaction" - )] - async fn get_prism_records_receive( - &self, - /// query evm to native txs received at the address, e.g. fra1rkvlrs8j8y7rlud9qh6ndg5nr4ag7ar4640dr8h0ys6zfrwv25as42zptu - address: Query, - /// page index, the default is 1. - page: Query>, - /// page size, the default is 10. - page_size: Query>, - ) -> poem::Result { - service::v1::transaction::get_prism_received(self, address, page, page_size) - .await - .map_err(handle_fetch_one_err) - } - - #[oai( - path = "/tx/prism/records/send", - method = "get", - tag = "ApiTags::Transaction" - )] - async fn get_prism_records_send( - &self, - /// query native to evm txs sent from the address, e.g. fra18fnyetvs2kc035xz78kyfcygmej8pk5h2kwczy03w6uewdphzfxsk74dym - address: Query, - /// page index, the default is 1. - page: Query>, - /// page size, the default is 10. - page_size: Query>, - ) -> poem::Result { - service::v1::transaction::get_prism_records_send(self, address, page, page_size) - .await - .map_err(handle_fetch_one_err) - } - - #[oai(path = "/tx/delegation", method = "get", tag = "ApiTags::Transaction")] - async fn get_delegation_tx( - &self, - /// bech32 address, e.g. fra18fnyetvs2kc035xz78kyfcygmej8pk5h2kwczy03w6uewdphzfxsk74dym - address: Query, - /// page index, the default is 1. - page: Query>, - /// page size, the default is 10. - page_size: Query>, - ) -> poem::Result { - service::v1::staking::get_tx_delegation(self, address, page, page_size) - .await - .map_err(handle_fetch_one_err) - } - - #[oai( - path = "/tx/undelegation", - method = "get", - tag = "ApiTags::Transaction" - )] - async fn get_undelegation( - &self, - /// bech32 address, e.g. fra18fnyetvs2kc035xz78kyfcygmej8pk5h2kwczy03w6uewdphzfxsk74dym - address: Query, - /// page index, the default is 1. - page: Query>, - /// page size, the default is 10. - page_size: Query>, - ) -> poem::Result { - service::v1::staking::get_tx_undelegation(self, address, page, page_size) - .await - .map_err(handle_fetch_one_err) - } - - #[oai(path = "/staking/claim", method = "get", tag = "ApiTags::Staking")] - async fn get_claim( - &self, - /// bech32 address, e.g. fra1xczgryuz65as77gf8d5f07xd0wetd8qpm5hvgqkfgc60gxdjpmkshnq9ys - address: Query, - /// page index, the default is 1. - page: Query>, - /// page size, the default is 10. - page_size: Query>, - ) -> poem::Result { - service::v1::staking::get_claim(self, address, page, page_size) - .await - .map_err(handle_fetch_one_err) - } - - // #[oai( - // path = "/chain/validator/history", - // method = "get", - // tag = "ApiTags::BlockChain" - // )] - // async fn get_validator_history( - // &self, - // /// validator address, e.g. 9E6717392EFDCFA101E33449A7C2A238251315B1 - // address: Query, - // /// page index, the default is 1. - // page: Query>, - // /// page size, the default is 10. - // page_size: Query>, - // ) -> poem::Result { - // service::v1::validator::validator_history(self, address, page, page_size) - // .await - // .map_err(handle_fetch_one_err) - // } - - // #[oai( - // path = "/chain/claim/:address", - // method = "get", - // tag = "ApiTags::BlockChain" - // )] - // async fn get_claim_amount(&self, address: Path) -> poem::Result { - // service::v1::transaction::get_claims_amount(self, address) - // .await - // .map_err(handle_fetch_one_err) - // } - - // #[oai( - // path = "/staking/delegation_info/:address", - // method = "get", - // tag = "ApiTags::Staking" - // )] - // async fn get_delegation(&self, address: Path) -> poem::Result { - // service::v1::staking::delegation(self, address) - // .await - // .map_err(handle_fetch_one_err) - // } - - #[oai( - path = "/staking/undelegation", - method = "get", - tag = "ApiTags::Staking" - )] - async fn get_undelegation_info( - &self, - /// base64 pubkey, e.g. OmZMrZBVsPjQwvHsROCI3mRw2pdVnYER8Xa5lzQ3Ek0= - pubkey: Query>, - /// staring timestamp. - start: Query>, - /// ending timestamp. - end: Query>, - /// page index, the default is 1. - page: Query>, - /// page size, the default is 10. - page_size: Query>, - ) -> poem::Result { - service::v1::staking::get_undelegation_info(self, pubkey, start, end, page, page_size) - .await - .map_err(handle_fetch_one_err) - } - - #[oai(path = "/staking/delegation", method = "get", tag = "ApiTags::Staking")] - async fn get_delegation_info( - &self, - /// base64 pubkey, e.g. OmZMrZBVsPjQwvHsROCI3mRw2pdVnYER8Xa5lzQ3Ek0= - pubkey: Query>, - /// starting timestamp. - start: Query>, - /// ending timestamp. - end: Query>, - /// page index, the default is 1. - page: Query>, - /// page size, the default is 10. - page_size: Query>, - ) -> poem::Result { - service::v1::staking::get_delegation_info(self, pubkey, start, end, page, page_size) - .await - .map_err(handle_fetch_one_err) - } - - // #[oai( - // path = "/staking/delegation/amount", - // method = "get", - // tag = "ApiTags::Staking" - // )] - // async fn get_delegation_amount( - // &self, - // /// base64 pubkey, e.g. OmZMrZBVsPjQwvHsROCI3mRw2pdVnYER8Xa5lzQ3Ek0= - // pubkey: Query>, - // /// starting timestamp. - // start: Query>, - // /// ending timestamp. - // end: Query>, - // ) -> poem::Result { - // service::v1::staking::get_delegation_amount(self, pubkey, start, end) - // .await - // .map_err(handle_fetch_one_err) - // } - - // #[oai( - // path = "/staking/undelegation/amount", - // method = "get", - // tag = "ApiTags::Staking" - // )] - // async fn get_undelegation_amount( - // &self, - // /// base64 pubkey, e.g. OmZMrZBVsPjQwvHsROCI3mRw2pdVnYER8Xa5lzQ3Ek0= - // pubkey: Query>, - // /// starting timestamp. - // start: Query>, - // /// ending timestamp. - // end: Query>, - // ) -> poem::Result { - // service::v1::staking::get_undelegation_amount(self, pubkey, start, end) - // .await - // .map_err(handle_fetch_one_err) - // } - - // #[oai( - // path = "/chain/prism/sync", - // method = "get", - // tag = "ApiTags::BlockChain" - // )] - // async fn prism_sync_info(&self) -> poem::Result { - // service::v1::chain::prism_sync_info(self) - // .await - // .map_err(handle_fetch_one_err) - // } - - // #[oai( - // path = "/chain/delegation/address/num", - // method = "get", - // tag = "ApiTags::BlockChain" - // )] - // async fn delegation_address_num(&self) -> poem::Result { - // service::v1::chain::delegation_address_num(self) - // .await - // .map_err(handle_fetch_one_err) - // } - - /////////////////////////////////////////////////////////////////////////////////////////////// - // V2 - /////////////////////////////////////////////////////////////////////////////////////////////// - #[oai( - path = "/v2/staking/delegation/:tx_hash", - method = "get", - tag = "ApiTags::Staking" - )] - async fn v2_get_delegation(&self, tx_hash: Path) -> poem::Result { - v2_get_delegation(self, tx_hash) - .await - .map_err(handle_fetch_one_err) - } - #[oai( - path = "/v2/staking/delegations", - method = "get", - tag = "ApiTags::Staking" - )] - async fn v2_get_delegations( - &self, - address: Query>, - page: Query>, - page_size: Query>, - ) -> poem::Result { - v2_get_delegations(self, address, page, page_size) - .await - .map_err(handle_fetch_one_err) - } - #[oai( - path = "/v2/staking/undelegation/:tx_hash", - method = "get", - tag = "ApiTags::Staking" - )] - async fn v2_get_undelegation( - &self, - tx_hash: Path, - ) -> poem::Result { - v2_get_undelegation(self, tx_hash) - .await - .map_err(handle_fetch_one_err) - } - - #[oai( - path = "/v2/staking/undelegations", - method = "get", - tag = "ApiTags::Staking" - )] - async fn v2_get_undelegations( - &self, - address: Query>, - page: Query>, - page_size: Query>, - ) -> poem::Result { - v2_get_undelegations(self, address, page, page_size) - .await - .map_err(handle_fetch_one_err) - } - - #[oai( - path = "/v2/staking/claim/:tx_hash", - method = "get", - tag = "ApiTags::Staking" - )] - async fn v2_get_claim(&self, tx_hash: Path) -> poem::Result { - v2_get_claim(self, tx_hash) - .await - .map_err(handle_fetch_one_err) - } - - #[oai(path = "/v2/staking/claims", method = "get", tag = "ApiTags::Staking")] - async fn v2_get_claims( - &self, - address: Query>, - page: Query>, - page_size: Query>, - ) -> poem::Result { - v2_get_claims(self, address, page, page_size) - .await - .map_err(handle_fetch_one_err) - } - - #[oai( - path = "/v2/tx/n2e/:tx_hash", - method = "get", - tag = "ApiTags::Transaction" - )] - async fn v2_get_n2e_tx(&self, tx_hash: Path) -> poem::Result { - v2_get_n2e_tx(self, tx_hash) - .await - .map_err(handle_fetch_one_err) - } - - /////////////////////////////////////////////////////////////////////////////////////////////// - // Asset - /////////////////////////////////////////////////////////////////////////////////////////////// - #[oai(path = "/v2/asset", method = "get", tag = "ApiTags::Asset")] - async fn v2_get_asset( - &self, - address: Query, - page: Query>, - page_size: Query>, - ) -> poem::Result { - v2_get_asset(self, address, page, page_size) - .await - .map_err(handle_fetch_one_err) - } - - #[oai(path = "/v2/asset/list", method = "get", tag = "ApiTags::Asset")] - async fn v2_get_asset_list( - &self, - page: Query>, - page_size: Query>, - ) -> poem::Result { - v2_get_asset_list(self, page, page_size) - .await - .map_err(handle_fetch_one_err) - } - /////////////////////////////////////////////////////////////////////////////////////////////// - // Statistics - /////////////////////////////////////////////////////////////////////////////////////////////// - #[oai( - path = "/v2/chain/statistics", - method = "get", - tag = "ApiTags::BlockChain" - )] - async fn v2_statistics( - &self, - ty: Query>, - ) -> poem::Result { - v2_statistics(self, ty).await.map_err(handle_fetch_one_err) - } - /////////////////////////////////////////////////////////////////////////////////////////////// - // Distribution - /////////////////////////////////////////////////////////////////////////////////////////////// - #[oai( - path = "/v2/txs/distribute", - method = "get", - tag = "ApiTags::Transaction" - )] - async fn v2_distribute(&self) -> poem::Result { - v2_distribute(self).await.map_err(handle_fetch_one_err) - } - - #[oai( - path = "/v2/tx/prism/send", - method = "get", - tag = "ApiTags::Transaction" - )] - async fn v2_get_prism_records_send( - &self, - address: Query, - page: Query>, - page_size: Query>, - ) -> poem::Result { - v2_get_prism_records_send(self, address, page, page_size) - .await - .map_err(handle_fetch_one_err) - } - - #[oai(path = "/v2/address/count", method = "get", tag = "ApiTags::Address")] - async fn v2_address_count( - &self, - start_time: Query>, - end_time: Query>, - ) -> poem::Result { - v2_address_count(self, start_time, end_time) - .await - .map_err(handle_fetch_one_err) - } - - #[allow(clippy::too_many_arguments)] - #[oai(path = "/v2/txs", method = "get", tag = "ApiTags::Transaction")] - async fn v2_get_txs( - &self, - block_id: Query>, - height: Query>, - from: Query>, - to: Query>, - ty: Query>, - start_time: Query>, - end_time: Query>, - page: Query>, - page_size: Query>, - ) -> poem::Result { - v2_get_txs( - self, block_id, height, from, to, ty, start_time, end_time, page, page_size, - ) - .await - .map_err(handle_fetch_one_err) - } -} +// #[OpenApi] +// impl Api { +// #[oai(path = "/tx/:tx_hash", method = "get", tag = "ApiTags::Transaction")] +// async fn get_tx( +// &self, +// /// tx hash, e.g. c19fc22beb61030607367b42d4898a26ede1e6aa6b400330804c95b241f29bd0 +// tx_hash: Path, +// ) -> poem::Result { +// service::v1::transaction::get_tx(self, tx_hash) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[oai( +// path = "/tx/evm/:tx_hash", +// method = "get", +// tag = "ApiTags::Transaction" +// )] +// async fn get_evm_tx( +// &self, +// /// evm tx hash, e.g. 0x697c0492b64b8e786061818c12af46e9b62b9ee20e573d7549e7a82e94ef13cf +// tx_hash: Path, +// ) -> poem::Result { +// service::v1::transaction::get_evm_tx(self, tx_hash) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// // #[oai(path = "/txs/to", method = "get", tag = "ApiTags::Transaction")] +// // async fn get_txs_send_to( +// // &self, +// // /// bech32 address, e.g. fra1p4vy5n9mlkdys7xczegj398xtyvw2nawz00nnfh4yr7fpjh297cqsxfv7v +// // address: Query, +// // /// page index, the default is 1. +// // page: Query>, +// // /// page size, the default is 10. +// // page_size: Query>, +// // ) -> poem::Result { +// // service::v1::transaction::get_txs_send_to(self, address, page, page_size) +// // .await +// // .map_err(handle_fetch_one_err) +// // } +// +// // #[oai(path = "/txs/from", method = "get", tag = "ApiTags::Transaction")] +// // async fn get_txs_receive_from( +// // &self, +// // /// bech32 address, e.g. fra1p4vy5n9mlkdys7xczegj398xtyvw2nawz00nnfh4yr7fpjh297cqsxfv7v +// // address: Query, +// // /// page index, the default is 1. +// // page: Query>, +// // /// page size, the default is 10. +// // page_size: Query>, +// // ) -> poem::Result { +// // service::v1::transaction::get_txs_receive_from(self, address, page, page_size) +// // .await +// // .map_err(handle_fetch_one_err) +// // } +// +// #[allow(clippy::too_many_arguments)] +// #[oai(path = "/txs", method = "get", tag = "ApiTags::Transaction")] +// async fn get_txs( +// &self, +// /// block hash, e.g. 4B7C22FA8FC6913E091DC324830181BBA1F01EBFF53049F958EA5AA65327BFE0 +// block_id: Query>, +// /// block height. +// height: Query>, +// /// bech32 address, e.g. fra1p4vy5n9mlkdys7xczegj398xtyvw2nawz00nnfh4yr7fpjh297cqsxfv7v +// from: Query>, +// /// bech32 address, e.g. fra1p4vy5n9mlkdys7xczegj398xtyvw2nawz00nnfh4yr7fpjh297cqsxfv7v +// to: Query>, +// /// transaction type. +// /// 0 - Findora native tx. +// /// 1 - EVM tx. +// ty: Query>, +// /// starting timestamp. +// start_time: Query>, +// /// ending timestamp. +// end_time: Query>, +// /// page index, the default is 1. +// page: Query>, +// /// page size, the default is 10. +// page_size: Query>, +// ) -> poem::Result { +// service::v1::transaction::get_txs( +// self, block_id, height, from, to, ty, start_time, end_time, page, page_size, +// ) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// // #[allow(clippy::too_many_arguments)] +// // #[oai(path = "/txs/raw", method = "get", tag = "ApiTags::Transaction")] +// // async fn get_txs_no_wrap( +// // &self, +// // /// block hash, e.g. 4B7C22FA8FC6913E091DC324830181BBA1F01EBFF53049F958EA5AA65327BFE0 +// // block_id: Query>, +// // /// block height. +// // height: Query>, +// // /// bech32 address, e.g. fra1p4vy5n9mlkdys7xczegj398xtyvw2nawz00nnfh4yr7fpjh297cqsxfv7v +// // address: Query>, +// // /// bech32 address, e.g. fra1p4vy5n9mlkdys7xczegj398xtyvw2nawz00nnfh4yr7fpjh297cqsxfv7v +// // from: Query>, +// // /// bech32 address, e.g. fra1p4vy5n9mlkdys7xczegj398xtyvw2nawz00nnfh4yr7fpjh297cqsxfv7v +// // to: Query>, +// // /// transaction type. +// // /// 0 - Findora native tx. +// // /// 1 - EVM tx. +// // ty: Query>, +// // /// starting timestamp. +// // start_time: Query>, +// // /// ending timestamp. +// // end_time: Query>, +// // /// page index, the default is 1. +// // page: Query>, +// // /// page size, the default is 10. +// // page_size: Query>, +// // ) -> poem::Result { +// // service::v1::transaction::get_txs_raw( +// // self, block_id, height, address, from, to, ty, start_time, end_time, page, page_size, +// // ) +// // .await +// // .map_err(handle_fetch_one_err) +// // } +// +// #[allow(clippy::too_many_arguments)] +// #[oai( +// path = "/txs/triple_masking", +// method = "get", +// tag = "ApiTags::Transaction" +// )] +// async fn get_triple_masking_txs( +// &self, +// /// block hash, e.g. 4B7C22FA8FC6913E091DC324830181BBA1F01EBFF53049F958EA5AA65327BFE0 +// block_id: Query>, +// /// public key, e.g. b2fdE7jKfQg_XL2CT7jdw84XkTdpX3uiRgpgW-h6k6o=. +// pub_key: Query>, +// /// 0 - default, querying both AbarToBar and BarToAbar. +// /// 1 - AbarToBar. +// /// 2 - BarToAbar. +// bar: Query>, +// /// starting timestamp. +// start_time: Query>, +// /// ending timestamp. +// end_time: Query>, +// /// page index, the default is 1. +// page: Query>, +// /// page size, the default is 10. +// page_size: Query>, +// ) -> poem::Result { +// service::v1::transaction::get_triple_masking_txs( +// self, block_id, pub_key, bar, start_time, end_time, page, page_size, +// ) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[oai(path = "/txs/claim", method = "get", tag = "ApiTags::Transaction")] +// async fn get_claim_txs( +// &self, +// /// block hash. +// block_id: Query>, +// /// public key. +// pub_key: Query>, +// /// starting timestamp. +// start_time: Query>, +// /// ending timestamp. +// end_time: Query>, +// /// page index, the default is 1. +// page: Query>, +// /// page size, the default is 10. +// page_size: Query>, +// ) -> poem::Result { +// service::v1::transaction::get_claim_txs( +// self, block_id, pub_key, start_time, end_time, page, page_size, +// ) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[allow(clippy::too_many_arguments)] +// #[oai( +// path = "/txs/prism/:address", +// method = "get", +// tag = "ApiTags::Transaction" +// )] +// async fn get_prism_tx( +// &self, +// /// Bridge Contract deploy address, e.g. 0x2B7835AE05C9Cb5EF086e3BFe249e2658b450E8d +// address: Path, +// /// starting timestamp. +// start_time: Query>, +// /// ending timestamp. +// end_time: Query>, +// /// page index, the default is 1. +// page: Query>, +// /// page size, the default is 10. +// page_size: Query>, +// ) -> poem::Result { +// service::v1::transaction::get_prism_tx(self, address, start_time, end_time, page, page_size) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[oai(path = "/block/height/:height", method = "get", tag = "ApiTags::Block")] +// async fn get_block_by_height( +// &self, +// /// block height. +// height: Path, +// ) -> poem::Result { +// service::v1::block::get_simple_block_by_height(self, height) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[oai( +// path = "/block/full/height/:height", +// method = "get", +// tag = "ApiTags::Block" +// )] +// async fn get_full_block_by_height( +// &self, +// /// block height. +// height: Path, +// ) -> poem::Result { +// service::v1::block::get_full_block_by_height(self, height) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[oai(path = "/block/hash/:hash", method = "get", tag = "ApiTags::Block")] +// async fn get_block_by_hash( +// &self, +// /// block hash. +// hash: Path, +// ) -> poem::Result { +// service::v1::block::get_simple_block_by_hash(self, hash) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[oai( +// path = "/block/full/hash/:hash", +// method = "get", +// tag = "ApiTags::Block" +// )] +// async fn get_full_block_by_hash( +// &self, +// /// block hash. +// hash: Path, +// ) -> poem::Result { +// service::v1::block::get_full_block_by_hash(self, hash) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[oai(path = "/blocks", method = "get", tag = "ApiTags::Block")] +// async fn get_blocks( +// &self, +// /// starting height. +// start_height: Query>, +// /// ending height. +// end_height: Query>, +// /// starting timestamp. +// start_time: Query>, +// /// ending timestamp. +// end_time: Query>, +// /// page index, the default is 1. +// page: Query>, +// /// page size, the default is 10. +// page_size: Query>, +// ) -> poem::Result { +// service::v1::block::get_blocks( +// self, +// start_height, +// end_height, +// start_time, +// end_time, +// page, +// page_size, +// ) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[oai(path = "/address/:address", method = "get", tag = "ApiTags::Address")] +// async fn get_address( +// &self, +// /// bech32 address, e.g. fra1p4vy5n9mlkdys7xczegj398xtyvw2nawz00nnfh4yr7fpjh297cqsxfv7v +// address: Path, +// /// page index, the default is 1. +// page: Query>, +// /// page size, the default is 10. +// page_size: Query>, +// ) -> poem::Result { +// service::v1::address::get_address(self, address, page, page_size) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[oai(path = "/asset/:code", method = "get", tag = "ApiTags::Asset")] +// async fn get_asset( +// &self, +// /// base64 asset code, e.g. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= +// code: Path, +// ) -> poem::Result { +// service::v1::asset::get_asset(self, code) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[oai(path = "/asset/list", method = "get", tag = "ApiTags::Asset")] +// async fn get_asset_list( +// &self, +// page: Query>, +// page_size: Query>, +// ) -> poem::Result { +// service::v1::asset::get_asset_list(self, page, page_size) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[oai(path = "/asset/issued/list", method = "get", tag = "ApiTags::Asset")] +// async fn get_issued_asset_list( +// &self, +// page: Query>, +// page_size: Query>, +// ) -> poem::Result { +// service::v1::asset::get_issued_asset_list(self, page, page_size) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[oai(path = "/asset/issued/:code", method = "get", tag = "ApiTags::Asset")] +// async fn get_issued_asset( +// &self, +// /// base64 asset code, e.g. dPJSy9DnxJgUiMheXphWloPfnvKQDCl7LoNfhHjaimM= +// code: Path, +// ) -> poem::Result { +// service::v1::asset::get_issued_asset(self, code) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[oai( +// path = "/chain/statistics", +// method = "get", +// tag = "ApiTags::BlockChain" +// )] +// async fn statistics( +// &self, +// /// tx type, 0 - Findora native tx, 1 - EVM tx. +// ty: Query>, +// ) -> poem::Result { +// service::v1::chain::statistics(self, ty) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// // #[oai( +// // path = "/chain/validator_list", +// // method = "get", +// // tag = "ApiTags::BlockChain" +// // )] +// // async fn validator_list(&self) -> poem::Result { +// // service::v1::validator::validator_list(self) +// // .await +// // .map_err(handle_fetch_one_err) +// // } +// +// // #[oai( +// // path = "/chain/validator_detail/:address", +// // method = "get", +// // tag = "ApiTags::BlockChain" +// // )] +// // async fn validator_detail( +// // &self, +// // /// validator address, e.g. 917454FB61CFBDB1995BC57C7A821E41FFB1AF43 +// // address: Path, +// // ) -> poem::Result { +// // service::v1::validator::validator_detail(self, address) +// // .await +// // .map_err(handle_fetch_one_err) +// // } +// +// #[oai( +// path = "/chain/circulating_supply", +// method = "get", +// tag = "ApiTags::BlockChain" +// )] +// async fn circulating_supply(&self) -> poem::Result { +// service::v1::validator::circulating_supply(self) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// // #[oai( +// // path = "/chain/validator/signed_count", +// // method = "get", +// // tag = "ApiTags::BlockChain" +// // )] +// // async fn validator_signed_count( +// // &self, +// // /// validator address, e.g. 917454FB61CFBDB1995BC57C7A821E41FFB1AF43 +// // address: Query, +// // /// page index, the default is 1. +// // page: Query>, +// // /// page size, the default is 10. +// // page_size: Query>, +// // ) -> poem::Result { +// // service::v1::validator::validator_signed_count(self, address, page, page_size) +// // .await +// // .map_err(handle_fetch_one_err) +// // } +// +// // #[oai( +// // path = "/chain/delegator_list/:address", +// // method = "get", +// // tag = "ApiTags::BlockChain" +// // )] +// // async fn delegator_list( +// // &self, +// // /// delegator address, e.g. 000E33AB7471186F3B1DE9FC08BB9C480F453590 +// // address: Path, +// // ) -> poem::Result { +// // service::v1::validator::delegator_list(self, address) +// // .await +// // .map_err(handle_fetch_one_err) +// // } +// +// #[oai(path = "/simple/price", method = "get", tag = "ApiTags::Price")] +// async fn simple_price( +// &self, +// ids: Query, +// vs_currencies: Query, +// ) -> poem::Result { +// service::v1::price::simple_price(self, ids, vs_currencies) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[oai( +// path = "/coins/:id/market_chart", +// method = "get", +// tag = "ApiTags::Price" +// )] +// async fn market_chart( +// &self, +// id: Path, +// vs_currency: Query, +// interval: Query>, +// days: Query, +// ) -> poem::Result { +// service::v1::price::market_chart(self, id, vs_currency, interval, days) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[oai(path = "/address/count", method = "get", tag = "ApiTags::Address")] +// async fn address_count( +// &self, +// /// staring timestamp. +// start_time: Query, +// /// ending timestamp. +// end_time: Query, +// ) -> poem::Result { +// service::v1::chain::address_count(self, start_time, end_time) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[oai(path = "/txs/distribute", method = "get", tag = "ApiTags::Transaction")] +// async fn distribute(&self) -> poem::Result { +// service::v1::chain::distribute(self) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// // #[oai( +// // path = "/chain/validator_delegation", +// // method = "get", +// // tag = "ApiTags::BlockChain" +// // )] +// // async fn validator_delegation( +// // &self, +// // /// validator address, e.g. 000E33AB7471186F3B1DE9FC08BB9C480F453590 +// // address: Query, +// // ) -> poem::Result { +// // service::v1::validator::validator_delegation(self, address) +// // .await +// // .map_err(handle_fetch_one_err) +// // } +// +// #[oai( +// path = "/v2/txs/prism/e2n", +// method = "get", +// tag = "ApiTags::Transaction" +// )] +// async fn get_prism_e2n_txs( +// &self, +// page: Query>, +// page_size: Query>, +// ) -> poem::Result { +// service::v2::evm_to_native::v2_get_e2n_txs(self, page, page_size) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[oai( +// path = "/v2/txs/prism/n2e", +// method = "get", +// tag = "ApiTags::Transaction" +// )] +// async fn get_prism_n2e_txs( +// &self, +// page: Query>, +// page_size: Query>, +// ) -> poem::Result { +// service::v2::native_to_evm::v2_get_n2e_txs(self, page, page_size) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[oai( +// path = "/tx/prism/records/receive", +// method = "get", +// tag = "ApiTags::Transaction" +// )] +// async fn get_prism_records_receive( +// &self, +// /// query evm to native txs received at the address, e.g. fra1rkvlrs8j8y7rlud9qh6ndg5nr4ag7ar4640dr8h0ys6zfrwv25as42zptu +// address: Query, +// /// page index, the default is 1. +// page: Query>, +// /// page size, the default is 10. +// page_size: Query>, +// ) -> poem::Result { +// service::v1::transaction::get_prism_received(self, address, page, page_size) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[oai( +// path = "/tx/prism/records/send", +// method = "get", +// tag = "ApiTags::Transaction" +// )] +// async fn get_prism_records_send( +// &self, +// /// query native to evm txs sent from the address, e.g. fra18fnyetvs2kc035xz78kyfcygmej8pk5h2kwczy03w6uewdphzfxsk74dym +// address: Query, +// /// page index, the default is 1. +// page: Query>, +// /// page size, the default is 10. +// page_size: Query>, +// ) -> poem::Result { +// service::v1::transaction::get_prism_records_send(self, address, page, page_size) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[oai(path = "/tx/delegation", method = "get", tag = "ApiTags::Transaction")] +// async fn get_delegation_tx( +// &self, +// /// bech32 address, e.g. fra18fnyetvs2kc035xz78kyfcygmej8pk5h2kwczy03w6uewdphzfxsk74dym +// address: Query, +// /// page index, the default is 1. +// page: Query>, +// /// page size, the default is 10. +// page_size: Query>, +// ) -> poem::Result { +// service::v1::staking::get_tx_delegation(self, address, page, page_size) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[oai( +// path = "/tx/undelegation", +// method = "get", +// tag = "ApiTags::Transaction" +// )] +// async fn get_undelegation( +// &self, +// /// bech32 address, e.g. fra18fnyetvs2kc035xz78kyfcygmej8pk5h2kwczy03w6uewdphzfxsk74dym +// address: Query, +// /// page index, the default is 1. +// page: Query>, +// /// page size, the default is 10. +// page_size: Query>, +// ) -> poem::Result { +// service::v1::staking::get_tx_undelegation(self, address, page, page_size) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[oai(path = "/staking/claim", method = "get", tag = "ApiTags::Staking")] +// async fn get_claim( +// &self, +// /// bech32 address, e.g. fra1xczgryuz65as77gf8d5f07xd0wetd8qpm5hvgqkfgc60gxdjpmkshnq9ys +// address: Query, +// /// page index, the default is 1. +// page: Query>, +// /// page size, the default is 10. +// page_size: Query>, +// ) -> poem::Result { +// service::v1::staking::get_claim(self, address, page, page_size) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// // #[oai( +// // path = "/chain/validator/history", +// // method = "get", +// // tag = "ApiTags::BlockChain" +// // )] +// // async fn get_validator_history( +// // &self, +// // /// validator address, e.g. 9E6717392EFDCFA101E33449A7C2A238251315B1 +// // address: Query, +// // /// page index, the default is 1. +// // page: Query>, +// // /// page size, the default is 10. +// // page_size: Query>, +// // ) -> poem::Result { +// // service::v1::validator::validator_history(self, address, page, page_size) +// // .await +// // .map_err(handle_fetch_one_err) +// // } +// +// // #[oai( +// // path = "/chain/claim/:address", +// // method = "get", +// // tag = "ApiTags::BlockChain" +// // )] +// // async fn get_claim_amount(&self, address: Path) -> poem::Result { +// // service::v1::transaction::get_claims_amount(self, address) +// // .await +// // .map_err(handle_fetch_one_err) +// // } +// +// // #[oai( +// // path = "/staking/delegation_info/:address", +// // method = "get", +// // tag = "ApiTags::Staking" +// // )] +// // async fn get_delegation(&self, address: Path) -> poem::Result { +// // service::v1::staking::delegation(self, address) +// // .await +// // .map_err(handle_fetch_one_err) +// // } +// +// #[oai( +// path = "/staking/undelegation", +// method = "get", +// tag = "ApiTags::Staking" +// )] +// async fn get_undelegation_info( +// &self, +// /// base64 pubkey, e.g. OmZMrZBVsPjQwvHsROCI3mRw2pdVnYER8Xa5lzQ3Ek0= +// pubkey: Query>, +// /// staring timestamp. +// start: Query>, +// /// ending timestamp. +// end: Query>, +// /// page index, the default is 1. +// page: Query>, +// /// page size, the default is 10. +// page_size: Query>, +// ) -> poem::Result { +// service::v1::staking::get_undelegation_info(self, pubkey, start, end, page, page_size) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[oai(path = "/staking/delegation", method = "get", tag = "ApiTags::Staking")] +// async fn get_delegation_info( +// &self, +// /// base64 pubkey, e.g. OmZMrZBVsPjQwvHsROCI3mRw2pdVnYER8Xa5lzQ3Ek0= +// pubkey: Query>, +// /// starting timestamp. +// start: Query>, +// /// ending timestamp. +// end: Query>, +// /// page index, the default is 1. +// page: Query>, +// /// page size, the default is 10. +// page_size: Query>, +// ) -> poem::Result { +// service::v1::staking::get_delegation_info(self, pubkey, start, end, page, page_size) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// // #[oai( +// // path = "/staking/delegation/amount", +// // method = "get", +// // tag = "ApiTags::Staking" +// // )] +// // async fn get_delegation_amount( +// // &self, +// // /// base64 pubkey, e.g. OmZMrZBVsPjQwvHsROCI3mRw2pdVnYER8Xa5lzQ3Ek0= +// // pubkey: Query>, +// // /// starting timestamp. +// // start: Query>, +// // /// ending timestamp. +// // end: Query>, +// // ) -> poem::Result { +// // service::v1::staking::get_delegation_amount(self, pubkey, start, end) +// // .await +// // .map_err(handle_fetch_one_err) +// // } +// +// // #[oai( +// // path = "/staking/undelegation/amount", +// // method = "get", +// // tag = "ApiTags::Staking" +// // )] +// // async fn get_undelegation_amount( +// // &self, +// // /// base64 pubkey, e.g. OmZMrZBVsPjQwvHsROCI3mRw2pdVnYER8Xa5lzQ3Ek0= +// // pubkey: Query>, +// // /// starting timestamp. +// // start: Query>, +// // /// ending timestamp. +// // end: Query>, +// // ) -> poem::Result { +// // service::v1::staking::get_undelegation_amount(self, pubkey, start, end) +// // .await +// // .map_err(handle_fetch_one_err) +// // } +// +// // #[oai( +// // path = "/chain/prism/sync", +// // method = "get", +// // tag = "ApiTags::BlockChain" +// // )] +// // async fn prism_sync_info(&self) -> poem::Result { +// // service::v1::chain::prism_sync_info(self) +// // .await +// // .map_err(handle_fetch_one_err) +// // } +// +// // #[oai( +// // path = "/chain/delegation/address/num", +// // method = "get", +// // tag = "ApiTags::BlockChain" +// // )] +// // async fn delegation_address_num(&self) -> poem::Result { +// // service::v1::chain::delegation_address_num(self) +// // .await +// // .map_err(handle_fetch_one_err) +// // } +// +// /////////////////////////////////////////////////////////////////////////////////////////////// +// // V2 +// /////////////////////////////////////////////////////////////////////////////////////////////// +// #[oai( +// path = "/v2/staking/delegation/:tx_hash", +// method = "get", +// tag = "ApiTags::Staking" +// )] +// async fn v2_get_delegation(&self, tx_hash: Path) -> poem::Result { +// v2_get_delegation(self, tx_hash) +// .await +// .map_err(handle_fetch_one_err) +// } +// #[oai( +// path = "/v2/staking/delegations", +// method = "get", +// tag = "ApiTags::Staking" +// )] +// async fn v2_get_delegations( +// &self, +// address: Query>, +// page: Query>, +// page_size: Query>, +// ) -> poem::Result { +// v2_get_delegations(self, address, page, page_size) +// .await +// .map_err(handle_fetch_one_err) +// } +// #[oai( +// path = "/v2/staking/undelegation/:tx_hash", +// method = "get", +// tag = "ApiTags::Staking" +// )] +// async fn v2_get_undelegation( +// &self, +// tx_hash: Path, +// ) -> poem::Result { +// v2_get_undelegation(self, tx_hash) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[oai( +// path = "/v2/staking/undelegations", +// method = "get", +// tag = "ApiTags::Staking" +// )] +// async fn v2_get_undelegations( +// &self, +// address: Query>, +// page: Query>, +// page_size: Query>, +// ) -> poem::Result { +// v2_get_undelegations(self, address, page, page_size) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[oai( +// path = "/v2/staking/claim/:tx_hash", +// method = "get", +// tag = "ApiTags::Staking" +// )] +// async fn v2_get_claim(&self, tx_hash: Path) -> poem::Result { +// v2_get_claim(self, tx_hash) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[oai(path = "/v2/staking/claims", method = "get", tag = "ApiTags::Staking")] +// async fn v2_get_claims( +// &self, +// address: Query>, +// page: Query>, +// page_size: Query>, +// ) -> poem::Result { +// v2_get_claims(self, address, page, page_size) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[oai( +// path = "/v2/tx/n2e/:tx_hash", +// method = "get", +// tag = "ApiTags::Transaction" +// )] +// async fn v2_get_n2e_tx(&self, tx_hash: Path) -> poem::Result { +// v2_get_n2e_tx(self, tx_hash) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// /////////////////////////////////////////////////////////////////////////////////////////////// +// // Asset +// /////////////////////////////////////////////////////////////////////////////////////////////// +// #[oai(path = "/v2/asset", method = "get", tag = "ApiTags::Asset")] +// async fn v2_get_asset( +// &self, +// address: Query, +// page: Query>, +// page_size: Query>, +// ) -> poem::Result { +// v2_get_asset(self, address, page, page_size) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[oai(path = "/v2/asset/list", method = "get", tag = "ApiTags::Asset")] +// async fn v2_get_asset_list( +// &self, +// page: Query>, +// page_size: Query>, +// ) -> poem::Result { +// v2_get_asset_list(self, page, page_size) +// .await +// .map_err(handle_fetch_one_err) +// } +// /////////////////////////////////////////////////////////////////////////////////////////////// +// // Statistics +// /////////////////////////////////////////////////////////////////////////////////////////////// +// #[oai( +// path = "/v2/chain/statistics", +// method = "get", +// tag = "ApiTags::BlockChain" +// )] +// async fn v2_statistics( +// &self, +// ty: Query>, +// ) -> poem::Result { +// v2_statistics(self, ty).await.map_err(handle_fetch_one_err) +// } +// /////////////////////////////////////////////////////////////////////////////////////////////// +// // Distribution +// /////////////////////////////////////////////////////////////////////////////////////////////// +// #[oai( +// path = "/v2/txs/distribute", +// method = "get", +// tag = "ApiTags::Transaction" +// )] +// async fn v2_distribute(&self) -> poem::Result { +// v2_distribute(self).await.map_err(handle_fetch_one_err) +// } +// +// #[oai( +// path = "/v2/tx/prism/send", +// method = "get", +// tag = "ApiTags::Transaction" +// )] +// async fn v2_get_prism_records_send( +// &self, +// address: Query, +// page: Query>, +// page_size: Query>, +// ) -> poem::Result { +// v2_get_prism_records_send(self, address, page, page_size) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[oai(path = "/v2/address/count", method = "get", tag = "ApiTags::Address")] +// async fn v2_address_count( +// &self, +// start_time: Query>, +// end_time: Query>, +// ) -> poem::Result { +// v2_address_count(self, start_time, end_time) +// .await +// .map_err(handle_fetch_one_err) +// } +// +// #[allow(clippy::too_many_arguments)] +// #[oai(path = "/v2/txs", method = "get", tag = "ApiTags::Transaction")] +// async fn v2_get_txs( +// &self, +// block_id: Query>, +// height: Query>, +// from: Query>, +// to: Query>, +// ty: Query>, +// start_time: Query>, +// end_time: Query>, +// page: Query>, +// page_size: Query>, +// ) -> poem::Result { +// v2_get_txs( +// self, block_id, height, from, to, ty, start_time, end_time, page, page_size, +// ) +// .await +// .map_err(handle_fetch_one_err) +// } +// } diff --git a/explorer/src/service/mod.rs b/explorer/src/service/mod.rs index 0ed6d2e..645e38c 100644 --- a/explorer/src/service/mod.rs +++ b/explorer/src/service/mod.rs @@ -5,6 +5,7 @@ pub mod util; pub mod v1; pub mod v2; +#[allow(dead_code)] #[derive(Tags)] enum ApiTags { /// Operations about Transaction diff --git a/explorer/src/service/util.rs b/explorer/src/service/util.rs index f515ad6..f904356 100644 --- a/explorer/src/service/util.rs +++ b/explorer/src/service/util.rs @@ -49,7 +49,7 @@ pub fn public_key_from_bech32(addr: &str) -> Result { .c(d!()) .and_then(|bytes| XfrPublicKey::zei_from_bytes(&bytes).c(d!())) } - +#[allow(dead_code)] #[allow(non_snake_case)] #[allow(unreachable_patterns)] #[allow(unused_variables)] diff --git a/explorer/src/service/v1/address.rs b/explorer/src/service/v1/address.rs index a5766f7..5147164 100644 --- a/explorer/src/service/v1/address.rs +++ b/explorer/src/service/v1/address.rs @@ -47,7 +47,7 @@ pub struct AddressData { pub total: i64, pub txs: Vec, } - +#[allow(dead_code)] pub async fn get_address( api: &Api, address: Path, diff --git a/explorer/src/service/v1/asset.rs b/explorer/src/service/v1/asset.rs index bb69a4a..dfe57d5 100644 --- a/explorer/src/service/v1/asset.rs +++ b/explorer/src/service/v1/asset.rs @@ -81,7 +81,7 @@ pub struct AssetRPCResult { pub units: u32, pub confidential_units: [u8; 32], } - +#[allow(dead_code)] pub async fn get_asset(api: &Api, address: Path) -> Result { let mut conn = api.storage.lock().await.acquire().await?; let code_res = engine::general_purpose::URL_SAFE.decode(&address.0); @@ -197,7 +197,7 @@ pub struct AssetListData { pub total: i64, pub assets: Vec, } - +#[allow(dead_code)] pub async fn get_asset_list( api: &Api, page: Query>, @@ -314,7 +314,7 @@ pub struct IssueAssetBody { pub seq_num: u64, pub records: Value, } - +#[allow(dead_code)] pub async fn get_issued_asset_list( api: &Api, page: Query>, @@ -395,7 +395,7 @@ pub struct SingleIssueAssetResult { pub message: String, pub data: Option, } - +#[allow(dead_code)] pub async fn get_issued_asset( api: &Api, address: Path, diff --git a/explorer/src/service/v1/block.rs b/explorer/src/service/v1/block.rs index f0b6c58..d1b03cd 100644 --- a/explorer/src/service/v1/block.rs +++ b/explorer/src/service/v1/block.rs @@ -76,6 +76,7 @@ pub struct BlocksData { } /// return full block by given height. +#[allow(dead_code)] pub async fn get_full_block_by_height(api: &Api, height: Path) -> Result { let mut conn = api.storage.lock().await.acquire().await?; @@ -114,6 +115,7 @@ pub async fn get_full_block_by_height(api: &Api, height: Path) -> Result, @@ -166,6 +168,7 @@ pub async fn get_simple_block_by_height( } /// return full block by given block hash. +#[allow(dead_code)] pub async fn get_full_block_by_hash(api: &Api, hash: Path) -> Result { let mut conn = api.storage.lock().await.acquire().await?; @@ -188,7 +191,7 @@ pub async fn get_full_block_by_hash(api: &Api, hash: Path) -> Result>, diff --git a/explorer/src/service/v1/chain.rs b/explorer/src/service/v1/chain.rs index 6e947b1..27604bd 100644 --- a/explorer/src/service/v1/chain.rs +++ b/explorer/src/service/v1/chain.rs @@ -53,7 +53,7 @@ pub struct TxsDistribute { pub prism: i64, pub evm_compatible: i64, } - +#[allow(dead_code)] #[allow(clippy::let_unit_value)] pub async fn distribute(api: &Api) -> Result { let mut conn = api.storage.lock().await.acquire().await?; @@ -133,7 +133,7 @@ pub struct AddressCountResult { pub struct AddressCount { pub address_count: i64, } - +#[allow(dead_code)] pub async fn address_count( api: &Api, start_time: Query, @@ -163,7 +163,7 @@ pub async fn address_count( }), }))) } - +#[allow(dead_code)] #[allow(clippy::let_unit_value)] pub async fn statistics(api: &Api, ty: Query>) -> Result { let mut conn = api.storage.lock().await.acquire().await?; diff --git a/explorer/src/service/v1/price.rs b/explorer/src/service/v1/price.rs index 83f3b9e..f4aff01 100644 --- a/explorer/src/service/v1/price.rs +++ b/explorer/src/service/v1/price.rs @@ -54,7 +54,7 @@ pub struct MarketChartResult { pub message: String, pub data: Option, } - +#[allow(dead_code)] pub async fn get_fra_price(api: &Api) -> Result { let mut conn = api.storage.lock().await.acquire().await?; let row = sqlx::query("SELECT price FROM prices") @@ -64,7 +64,7 @@ pub async fn get_fra_price(api: &Api) -> Result { let fra_price = FraPrice { usd: p.parse()? }; Ok(fra_price) } - +#[allow(dead_code)] pub async fn upsert_fra_price(api: &Api, price: &str) -> Result<()> { let mut conn = api.storage.lock().await.acquire().await?; sqlx::query("INSERT INTO prices VALUES($1,$2) ON CONFLICT(name) DO UPDATE SET price=$2") @@ -75,7 +75,7 @@ pub async fn upsert_fra_price(api: &Api, price: &str) -> Result<()> { Ok(()) } - +#[allow(dead_code)] pub async fn get_fra_market(api: &Api) -> Result { let mut conn = api.storage.lock().await.acquire().await?; let row = sqlx::query("SELECT val FROM market") @@ -86,7 +86,7 @@ pub async fn get_fra_market(api: &Api) -> Result { Ok(fmc) } - +#[allow(dead_code)] pub async fn upsert_fra_market(api: &Api, val: Value) -> Result<()> { let mut conn = api.storage.lock().await.acquire().await?; sqlx::query("INSERT INTO market VALUES($1,$2) ON CONFLICT(name) DO UPDATE SET val=$2") @@ -97,7 +97,7 @@ pub async fn upsert_fra_market(api: &Api, val: Value) -> Result<()> { Ok(()) } - +#[allow(dead_code)] #[allow(clippy::let_unit_value)] pub async fn simple_price( api: &Api, @@ -148,7 +148,7 @@ pub struct FraMarketChart { pub prices: Value, pub total_volumes: Value, } - +#[allow(dead_code)] #[allow(clippy::let_unit_value)] pub async fn market_chart( api: &Api, diff --git a/explorer/src/service/v1/staking.rs b/explorer/src/service/v1/staking.rs index 6d91abf..89965a2 100644 --- a/explorer/src/service/v1/staking.rs +++ b/explorer/src/service/v1/staking.rs @@ -46,7 +46,7 @@ pub struct DelegationItem { pub amount: i64, pub timestamp: i64, } - +#[allow(dead_code)] pub async fn get_tx_delegation( api: &Api, address: Query, @@ -159,7 +159,7 @@ pub struct UnDelegationItem { pub timestamp: i64, pub expected_arrival_time: i64, } - +#[allow(dead_code)] pub async fn get_tx_undelegation( api: &Api, address: Query, @@ -276,7 +276,7 @@ pub struct ClaimItem { pub amount: u64, pub timestamp: i64, } - +#[allow(dead_code)] pub async fn get_claim( api: &Api, address: Query, @@ -408,7 +408,7 @@ pub struct UndelegationInfo { pub amount: u64, pub validator: String, } - +#[allow(dead_code)] pub async fn get_undelegation_info( api: &Api, pubkey: Query>, @@ -526,7 +526,7 @@ pub struct DelegationInfo { pub amount: u64, pub validator: String, } - +#[allow(dead_code)] pub async fn get_delegation_info( api: &Api, pubkey: Query>, diff --git a/explorer/src/service/v1/transaction.rs b/explorer/src/service/v1/transaction.rs index 7ac0b0a..af1a6ad 100644 --- a/explorer/src/service/v1/transaction.rs +++ b/explorer/src/service/v1/transaction.rs @@ -194,7 +194,7 @@ pub struct CallData { #[serde(rename = "Call")] pub call: Value, } - +#[allow(dead_code)] pub async fn get_prism_received( api: &Api, address: Query, @@ -297,7 +297,7 @@ pub struct NonConfidentialTransfer { pub input_value: u64, pub outputs: Vec, } - +#[allow(dead_code)] pub async fn get_prism_records_send( api: &Api, address: Query, @@ -382,7 +382,7 @@ pub async fn get_prism_records_send( }), }))) } - +#[allow(dead_code)] pub async fn get_evm_tx(api: &Api, tx_hash: Path) -> Result { let mut conn = api.storage.lock().await.acquire().await?; let sql_query = "SELECT * FROM transaction WHERE value @? '$.function.Ethereum'"; @@ -433,7 +433,7 @@ pub async fn get_evm_tx(api: &Api, tx_hash: Path) -> Result data: None, }))) } - +#[allow(dead_code)] pub async fn get_tx(api: &Api, tx_hash: Path) -> Result { let mut conn = api.storage.lock().await.acquire().await?; let str = format!( @@ -628,7 +628,7 @@ pub async fn get_txs_send_to( }), }))) } - +#[allow(dead_code)] #[allow(clippy::too_many_arguments)] pub async fn get_txs( api: &Api, @@ -912,7 +912,7 @@ pub async fn get_txs_raw( }), }))) } - +#[allow(dead_code)] #[allow(clippy::too_many_arguments)] pub async fn get_triple_masking_txs( api: &Api, @@ -1026,7 +1026,7 @@ pub async fn get_triple_masking_txs( }), }))) } - +#[allow(dead_code)] pub async fn get_claim_txs( api: &Api, block_hash: Query>, @@ -1139,6 +1139,7 @@ pub struct ClaimAmountResult { pub struct ClaimAmount { pub amount: u64, } + #[allow(dead_code)] pub async fn get_claims_amount(api: &Api, address: Path) -> Result { let mut conn = api.storage.lock().await.acquire().await?; @@ -1170,7 +1171,7 @@ pub async fn get_claims_amount(api: &Api, address: Path) -> Result, @@ -1345,7 +1346,7 @@ struct Output { pub asset_type: Value, pub public_key: Value, } - +#[allow(dead_code)] fn wrap_evm_tx(tx: &mut TransactionResponse) -> Result<()> { let tx_str: String = serde_json::to_string(&tx.value).unwrap(); diff --git a/explorer/src/service/v1/validator.rs b/explorer/src/service/v1/validator.rs index aa12ab9..2ca52db 100644 --- a/explorer/src/service/v1/validator.rs +++ b/explorer/src/service/v1/validator.rs @@ -273,7 +273,7 @@ pub async fn delegator_list(api: &Api, address: Path) -> Result Result { let circulating_supply_url = api.platform.rpc.join("circulating_supply").unwrap(); diff --git a/explorer/src/service/v2/asset.rs b/explorer/src/service/v2/asset.rs index 5998bde..ad509cd 100644 --- a/explorer/src/service/v2/asset.rs +++ b/explorer/src/service/v2/asset.rs @@ -43,7 +43,7 @@ pub struct V2AssetOp { pub ty: i32, pub value: Value, } - +#[allow(dead_code)] pub async fn v2_get_asset( api: &Api, address: Query, @@ -104,7 +104,7 @@ pub async fn v2_get_asset( }), }))) } - +#[allow(dead_code)] pub async fn v2_get_asset_list( api: &Api, page: Query>, diff --git a/explorer/src/service/v2/block.rs b/explorer/src/service/v2/block.rs new file mode 100644 index 0000000..037e235 --- /dev/null +++ b/explorer/src/service/v2/block.rs @@ -0,0 +1,144 @@ +use crate::AppState; +use axum::extract::{Query, State}; +use axum::Json; + +use module::rpc::block::BlockRPC; +use serde::{Deserialize, Serialize}; +use serde_json::Value; +use sqlx::Row; +use std::sync::Arc; + +use crate::service::v2::error::Result; +use crate::service::v2::{BlockResponse, QueryResult}; + +#[derive(Serialize, Deserialize, Debug)] +pub struct GetBlockByHeightParams { + pub num: i64, +} + +pub async fn get_block_by_num( + State(state): State>, + Query(params): Query, +) -> Result> { + let mut pool = state.pool.acquire().await?; + + let sql_query = "SELECT block_hash,height,size,tx_count,time,app_hash,proposer,block_data FROM block WHERE height=$1"; + let row = sqlx::query(sql_query) + .bind(params.num) + .fetch_one(&mut *pool) + .await?; + + let block_hash: String = row.try_get("block_hash")?; + let block_num: i64 = row.try_get("height")?; + let app_hash: String = row.try_get("app_hash")?; + let proposer: String = row.try_get("proposer")?; + let block_size: i64 = row.try_get("size")?; + let num_txs: i64 = row.try_get("tx_count")?; + let block_data: Value = row.try_get("block_data")?; + let block_rpc: BlockRPC = serde_json::from_value(block_data)?; + + Ok(Json(BlockResponse { + block_hash, + block_num, + app_hash, + proposer, + num_txs, + block_size, + block_id: block_rpc.block_id, + block_header: block_rpc.block.header, + })) +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct GetBlockByHashParams { + pub hash: String, +} + +pub async fn get_block_by_hash( + State(state): State>, + Query(params): Query, +) -> Result> { + let mut pool = state.pool.acquire().await?; + + let sql_query = "SELECT block_hash,height,size,tx_count,time,app_hash,proposer,block_data FROM block WHERE block_hash=$1"; + let row = sqlx::query(sql_query) + .bind(params.hash.to_uppercase()) + .fetch_one(&mut *pool) + .await?; + + let block_hash: String = row.try_get("block_hash")?; + let block_num: i64 = row.try_get("height")?; + let app_hash: String = row.try_get("app_hash")?; + let proposer: String = row.try_get("proposer")?; + let block_size: i64 = row.try_get("size")?; + let num_txs: i64 = row.try_get("tx_count")?; + let block_data: Value = row.try_get("block_data")?; + let block_rpc: BlockRPC = serde_json::from_value(block_data)?; + + Ok(Json(BlockResponse { + block_hash, + block_num, + app_hash, + proposer, + num_txs, + block_size, + block_id: block_rpc.block_id, + block_header: block_rpc.block.header, + })) +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct GetBlocksParams { + pub page: Option, + pub page_size: Option, +} + +pub async fn get_blocks( + State(state): State>, + Query(params): Query, +) -> Result>>> { + let mut pool = state.pool.acquire().await?; + let page = params.page.unwrap_or(1); + let page_size = params.page_size.unwrap_or(10); + + let sql_total = "SELECT max(height) FROM block"; + let row = sqlx::query(sql_total).fetch_one(&mut *pool).await?; + let total = row.try_get("max")?; + + let sql_query = "SELECT block_hash,height,size,tx_count,time,app_hash,proposer,block_data FROM block ORDER BY height DESC LIMIT $1 OFFSET $2"; + let rows = sqlx::query(sql_query) + .bind(page_size) + .bind((page - 1) * page_size) + .fetch_all(&mut *pool) + .await?; + + let mut blocks: Vec = vec![]; + for row in rows { + let block_hash: String = row.try_get("block_hash")?; + let block_num: i64 = row.try_get("height")?; + let app_hash: String = row.try_get("app_hash")?; + let proposer: String = row.try_get("proposer")?; + let block_size: i64 = row.try_get("size")?; + let num_txs: i64 = row.try_get("tx_count")?; + let block_data: Value = row.try_get("block_data")?; + let block_rpc: BlockRPC = serde_json::from_value(block_data)?; + + blocks.push(BlockResponse { + block_hash, + block_num, + app_hash, + proposer, + num_txs, + block_size, + block_id: block_rpc.block_id, + block_header: block_rpc.block.header, + }) + } + + Ok(Json(QueryResult { + total, + page, + page_size, + data: blocks, + })) +} diff --git a/explorer/src/service/v2/claim.rs b/explorer/src/service/v2/claim.rs index 53e777b..6f292d6 100644 --- a/explorer/src/service/v2/claim.rs +++ b/explorer/src/service/v2/claim.rs @@ -34,7 +34,7 @@ pub struct V2Claim { pub timestamp: i64, pub value: Value, } - +#[allow(dead_code)] pub async fn v2_get_claim(api: &Api, tx_hash: Path) -> Result { let mut conn = api.storage.lock().await.acquire().await?; let sql_query = format!( @@ -95,7 +95,7 @@ pub struct V2ClaimsData { pub total: i64, pub data: Option>, } - +#[allow(dead_code)] pub async fn v2_get_claims( api: &Api, address: Query>, diff --git a/explorer/src/service/v2/delegation.rs b/explorer/src/service/v2/delegation.rs index dfee787..cecf276 100644 --- a/explorer/src/service/v2/delegation.rs +++ b/explorer/src/service/v2/delegation.rs @@ -36,7 +36,7 @@ pub struct V2Delegation { pub timestamp: i64, pub value: Value, } - +#[allow(dead_code)] pub async fn v2_get_delegation(api: &Api, tx_hash: Path) -> Result { let mut conn = api.storage.lock().await.acquire().await?; let sql_query = format!( @@ -101,7 +101,7 @@ pub struct V2DelegationTxsData { pub total: i64, pub items: Vec, } - +#[allow(dead_code)] pub async fn v2_get_delegations( api: &Api, address: Query>, diff --git a/explorer/src/service/v2/error.rs b/explorer/src/service/v2/error.rs new file mode 100644 index 0000000..eccaa06 --- /dev/null +++ b/explorer/src/service/v2/error.rs @@ -0,0 +1,73 @@ +use axum::http::StatusCode; +use axum::response::{IntoResponse, Response}; + +#[derive(Debug)] +pub enum ExplorerError { + Custom(String), + DBError(sqlx::Error), + IOError(std::io::Error), + TomlDeError(toml::de::Error), + HexError(rustc_hex::FromHexError), + ParseUrlError(url::ParseError), + SerdeError(serde_json::Error), +} + +impl From for ExplorerError { + fn from(e: serde_json::Error) -> Self { + ExplorerError::SerdeError(e) + } +} + +impl From for ExplorerError { + fn from(e: String) -> Self { + ExplorerError::Custom(e) + } +} + +impl From for ExplorerError { + fn from(e: url::ParseError) -> Self { + ExplorerError::ParseUrlError(e) + } +} + +impl From for ExplorerError { + fn from(e: rustc_hex::FromHexError) -> Self { + ExplorerError::HexError(e) + } +} + +impl From for ExplorerError { + fn from(e: std::io::Error) -> Self { + ExplorerError::IOError(e) + } +} + +impl From for ExplorerError { + fn from(e: toml::de::Error) -> Self { + ExplorerError::TomlDeError(e) + } +} + +impl From for ExplorerError { + fn from(e: sqlx::Error) -> Self { + ExplorerError::DBError(e) + } +} + +pub type Result = core::result::Result; + +impl IntoResponse for ExplorerError { + fn into_response(self) -> Response { + let err_msg = match self { + ExplorerError::Custom(e) => e, + ExplorerError::DBError(e) => e.to_string(), + ExplorerError::IOError(e) => e.to_string(), + ExplorerError::TomlDeError(e) => e.to_string(), + ExplorerError::HexError(e) => e.to_string(), + ExplorerError::ParseUrlError(e) => e.to_string(), + ExplorerError::SerdeError(e) => e.to_string(), + }; + + (StatusCode::INTERNAL_SERVER_ERROR, err_msg).into_response() + } +} diff --git a/explorer/src/service/v2/evm_to_native.rs b/explorer/src/service/v2/evm_to_native.rs index 9011d4c..a19b3e5 100644 --- a/explorer/src/service/v2/evm_to_native.rs +++ b/explorer/src/service/v2/evm_to_native.rs @@ -44,7 +44,7 @@ pub struct V2EvmToNativeTx { pub timestamp: i64, pub value: Value, } - +#[allow(dead_code)] pub async fn v2_get_e2n_txs( api: &Api, page: Query>, diff --git a/explorer/src/service/v2/mod.rs b/explorer/src/service/v2/mod.rs index 9827990..79d63e0 100644 --- a/explorer/src/service/v2/mod.rs +++ b/explorer/src/service/v2/mod.rs @@ -1,7 +1,11 @@ +use module::rpc::block::{BlockHeader, BlockId}; use serde::{Deserialize, Serialize}; + pub mod asset; +pub mod block; pub mod claim; pub mod delegation; +pub mod error; pub mod evm_to_native; pub mod native_to_evm; pub mod other; @@ -27,3 +31,22 @@ pub enum TransactionType { DefineAsset, IssueAsset, } + +#[derive(Serialize, Deserialize, Debug)] +pub struct QueryResult { + pub total: i64, + pub page: i32, + pub page_size: i32, + pub data: T, +} +#[derive(Serialize, Deserialize, Debug)] +pub struct BlockResponse { + pub block_hash: String, + pub block_num: i64, + pub app_hash: String, + pub proposer: String, + pub num_txs: i64, + pub block_size: i64, + pub block_id: BlockId, + pub block_header: BlockHeader, +} diff --git a/explorer/src/service/v2/native_to_evm.rs b/explorer/src/service/v2/native_to_evm.rs index a1bc507..20a8740 100644 --- a/explorer/src/service/v2/native_to_evm.rs +++ b/explorer/src/service/v2/native_to_evm.rs @@ -35,7 +35,7 @@ pub struct V2NativeToEvmTxsData { pub page_size: i32, pub txs: Vec, } - +#[allow(dead_code)] pub async fn v2_get_n2e_txs( api: &Api, page: Query>, @@ -118,7 +118,7 @@ pub struct V2NativeToEvmTx { pub timestamp: i64, pub value: Value, } - +#[allow(dead_code)] pub async fn v2_get_n2e_tx(api: &Api, tx_hash: Path) -> Result { let mut conn = api.storage.lock().await.acquire().await?; let sql_query = format!("SELECT tx,block,sender,receiver,asset,amount,height,timestamp,content FROM n2e WHERE tx='{}'", tx_hash.0.to_lowercase()); @@ -176,7 +176,7 @@ pub struct ConvertAccountOperation { #[serde(rename = "ConvertAccount")] pub convert_account: ConvertAccount, } - +#[allow(dead_code)] pub async fn v2_get_prism_records_send( api: &Api, address: Query, diff --git a/explorer/src/service/v2/other.rs b/explorer/src/service/v2/other.rs index 41e3a57..b666408 100644 --- a/explorer/src/service/v2/other.rs +++ b/explorer/src/service/v2/other.rs @@ -31,7 +31,7 @@ pub struct V2StatisticsData { pub total_txs: i64, pub daily_txs: i64, } - +#[allow(dead_code)] pub async fn v2_statistics(api: &Api, ty: Query>) -> Result { let mut conn = api.storage.lock().await.acquire().await?; @@ -153,7 +153,7 @@ pub struct V2TxsDistribute { pub prism: i64, pub evm_compatible: i64, } - +#[allow(dead_code)] pub async fn v2_distribute(api: &Api) -> Result { let mut conn = api.storage.lock().await.acquire().await?; @@ -189,7 +189,7 @@ pub async fn v2_distribute(api: &Api) -> Result { }), }))) } - +#[allow(dead_code)] pub async fn v2_address_count( api: &Api, start_time: Query>, diff --git a/explorer/src/service/v2/transaction.rs b/explorer/src/service/v2/transaction.rs index 53cbb43..7715fe2 100644 --- a/explorer/src/service/v2/transaction.rs +++ b/explorer/src/service/v2/transaction.rs @@ -8,7 +8,7 @@ use poem_openapi::payload::Json; use serde_json::Value; use sqlx::Row; use std::ops::Add; - +#[allow(dead_code)] #[allow(clippy::too_many_arguments)] pub async fn v2_get_txs( api: &Api, diff --git a/explorer/src/service/v2/undelegation.rs b/explorer/src/service/v2/undelegation.rs index 5a52164..31639a6 100644 --- a/explorer/src/service/v2/undelegation.rs +++ b/explorer/src/service/v2/undelegation.rs @@ -36,7 +36,7 @@ pub struct V2Undelegation { pub timestamp: i64, pub value: Value, } - +#[allow(dead_code)] pub async fn v2_get_undelegation( api: &Api, tx_hash: Path, @@ -104,7 +104,7 @@ pub struct V2UndelegationsData { pub total: i64, pub items: Option>, } - +#[allow(dead_code)] pub async fn v2_get_undelegations( api: &Api, address: Query>,