From 3988271cdc77aa0213a8ed2a92d060716200c970 Mon Sep 17 00:00:00 2001 From: Jun Luo <4catcode@gmail.com> Date: Tue, 17 Dec 2024 07:22:04 +0800 Subject: [PATCH] Added `Horizon.Server.root` to obtain information from the Horizon root endpoint. (#1122) --- CHANGELOG.md | 2 + src/horizon/call_builder.ts | 1 + src/horizon/horizon_api.ts | 14 +++ src/horizon/server.ts | 11 +++ test/unit/server/horizon/server_test.js | 126 ++++++++++++++++++++++++ 5 files changed, 154 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b52b699f..7d1d2a392 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ A breaking change will get clearly marked in this log. ### Fixed * When using a friendbot that points to a Horizon instance that has ledger metadata disabled, you can no longer extract the account sequence from the response. Instead, we hit RPC directly ([#1107](https://github.com/stellar/js-stellar-sdk/pull/1107/)). +### Added +* Added `Horizon.Server.root` to obtain information from the Horizon root endpoint. ([#1122](https://github.com/stellar/js-stellar-sdk/pull/1122/)) ## [v13.0.0](https://github.com/stellar/js-stellar-sdk/compare/v12.3.0...v13.0.0) This is a direct re-tag of rc.2 with the only change being an upgrade to the `stellar-base` library to incorporate a patch release. Nonetheless, the entire changelog from the prior major version here is replicated for a comprehensive view on what's broken, added, and fixed. diff --git a/src/horizon/call_builder.ts b/src/horizon/call_builder.ts index bffb3632d..eb6268aca 100644 --- a/src/horizon/call_builder.ts +++ b/src/horizon/call_builder.ts @@ -47,6 +47,7 @@ export class CallBuilder< T extends | HorizonApi.FeeStatsResponse | HorizonApi.BaseResponse + | HorizonApi.RootResponse | ServerApi.CollectionPage > { protected url: URI; diff --git a/src/horizon/horizon_api.ts b/src/horizon/horizon_api.ts index ae0aacf9c..646bf3266 100644 --- a/src/horizon/horizon_api.ts +++ b/src/horizon/horizon_api.ts @@ -707,4 +707,18 @@ export namespace HorizonApi { }; result_xdr: string; } + + export interface RootResponse { + horizon_version: string; + core_version: string; + ingest_latest_ledger: number; + history_latest_ledger: number; + history_latest_ledger_closed_at: string; + history_elder_ledger: number; + core_latest_ledger: number; + network_passphrase: string; + current_protocol_version: number; + supported_protocol_version: number; + core_supported_protocol_version: number; + } } diff --git a/src/horizon/server.ts b/src/horizon/server.ts index e509862d5..3d490e7d4 100644 --- a/src/horizon/server.ts +++ b/src/horizon/server.ts @@ -199,6 +199,17 @@ export class HorizonServer { return cb.call(); } + /** + * Fetch the Horizon server's root endpoint. + * @returns {Promise} Promise that resolves to the root endpoint returned by Horizon. + */ + public async root(): Promise { + const cb = new CallBuilder( + URI(this.serverURL as any), + ); + return cb.call(); + } + /** * Submits a transaction to the network. * diff --git a/test/unit/server/horizon/server_test.js b/test/unit/server/horizon/server_test.js index 6d1e7f190..4c4306e7b 100644 --- a/test/unit/server/horizon/server_test.js +++ b/test/unit/server/horizon/server_test.js @@ -37,6 +37,132 @@ describe("server.js non-transaction tests", function () { }); }); + describe("Server.root", function () { + let response = { + _links: { + account: { + href: "https://horizon.stellar.org/accounts/{account_id}", + templated: true, + }, + accounts: { + href: "https://horizon.stellar.org/accounts{?signer,sponsor,asset,liquidity_pool,cursor,limit,order}", + templated: true, + }, + account_transactions: { + href: "https://horizon.stellar.org/accounts/{account_id}/transactions{?cursor,limit,order}", + templated: true, + }, + claimable_balances: { + href: "https://horizon.stellar.org/claimable_balances{?asset,sponsor,claimant,cursor,limit,order}", + templated: true, + }, + assets: { + href: "https://horizon.stellar.org/assets{?asset_code,asset_issuer,cursor,limit,order}", + templated: true, + }, + effects: { + href: "https://horizon.stellar.org/effects{?cursor,limit,order}", + templated: true, + }, + fee_stats: { + href: "https://horizon.stellar.org/fee_stats", + }, + ledger: { + href: "https://horizon.stellar.org/ledgers/{sequence}", + templated: true, + }, + ledgers: { + href: "https://horizon.stellar.org/ledgers{?cursor,limit,order}", + templated: true, + }, + liquidity_pools: { + href: "https://horizon.stellar.org/liquidity_pools{?reserves,account,cursor,limit,order}", + templated: true, + }, + offer: { + href: "https://horizon.stellar.org/offers/{offer_id}", + templated: true, + }, + offers: { + href: "https://horizon.stellar.org/offers{?selling,buying,seller,sponsor,cursor,limit,order}", + templated: true, + }, + operation: { + href: "https://horizon.stellar.org/operations/{id}", + templated: true, + }, + operations: { + href: "https://horizon.stellar.org/operations{?cursor,limit,order,include_failed}", + templated: true, + }, + order_book: { + href: "https://horizon.stellar.org/order_book{?selling_asset_type,selling_asset_code,selling_asset_issuer,buying_asset_type,buying_asset_code,buying_asset_issuer,limit}", + templated: true, + }, + payments: { + href: "https://horizon.stellar.org/payments{?cursor,limit,order,include_failed}", + templated: true, + }, + self: { + href: "https://horizon.stellar.org/", + }, + strict_receive_paths: { + href: "https://horizon.stellar.org/paths/strict-receive{?source_assets,source_account,destination_account,destination_asset_type,destination_asset_issuer,destination_asset_code,destination_amount}", + templated: true, + }, + strict_send_paths: { + href: "https://horizon.stellar.org/paths/strict-send{?destination_account,destination_assets,source_asset_type,source_asset_issuer,source_asset_code,source_amount}", + templated: true, + }, + trade_aggregations: { + href: "https://horizon.stellar.org/trade_aggregations?base_asset_type={base_asset_type}\u0026base_asset_code={base_asset_code}\u0026base_asset_issuer={base_asset_issuer}\u0026counter_asset_type={counter_asset_type}\u0026counter_asset_code={counter_asset_code}\u0026counter_asset_issuer={counter_asset_issuer}", + templated: true, + }, + trades: { + href: "https://horizon.stellar.org/trades?base_asset_type={base_asset_type}\u0026base_asset_code={base_asset_code}\u0026base_asset_issuer={base_asset_issuer}\u0026counter_asset_type={counter_asset_type}\u0026counter_asset_code={counter_asset_code}\u0026counter_asset_issuer={counter_asset_issuer}", + templated: true, + }, + transaction: { + href: "https://horizon.stellar.org/transactions/{hash}", + templated: true, + }, + transactions: { + href: "https://horizon.stellar.org/transactions{?cursor,limit,order}", + templated: true, + }, + }, + horizon_version: "22.0.1-dd8a9b473a303cfcdd383d1db45dace93ea0861c", + core_version: + "stellar-core 22.1.0.rc1 (fdd833d57c86cfe0c5057da5b2319953ab841de0)", + ingest_latest_ledger: 54837706, + history_latest_ledger: 54837706, + history_latest_ledger_closed_at: "2024-12-15T11:39:19Z", + history_elder_ledger: 48530161, + core_latest_ledger: 54837706, + network_passphrase: "Public Global Stellar Network ; September 2015", + current_protocol_version: 22, + supported_protocol_version: 22, + core_supported_protocol_version: 22, + }; + + it("returns the root endpoint", function (done) { + this.axiosMock + .expects("get") + .withArgs(sinon.match("https://horizon-live.stellar.org:1337/")) + .returns(Promise.resolve({ data: response })); + + this.server + .root() + .then((root) => { + expect(root).to.be.equal(response); + done(); + }) + .catch(function (err) { + done(err); + }); + }); + }); + describe("Server.fetchTimebounds", function () { let clock;