Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge custom headers with defaults rather than existing headers #1089

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/horizon/account_call_builder.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Asset } from "@stellar/stellar-base";
import { CallBuilder } from "./call_builder";
import { ServerApi } from "./server_api";
import { HttpClient } from "../http-client";

/**
* Creates a new {@link AccountCallBuilder} pointed to server defined by `serverUrl`.
Expand All @@ -17,8 +18,8 @@ import { ServerApi } from "./server_api";
export class AccountCallBuilder extends CallBuilder<
ServerApi.CollectionPage<ServerApi.AccountRecord>
> {
constructor(serverUrl: URI) {
super(serverUrl);
constructor(serverUrl: URI, client: HttpClient) {
super(serverUrl, client);
this.url.segment("accounts");
}

Expand All @@ -31,7 +32,7 @@ export class AccountCallBuilder extends CallBuilder<
* @returns {CallBuilder} a new CallBuilder instance for the /accounts/:id endpoint
*/
public accountId(id: string): CallBuilder<ServerApi.AccountRecord> {
const builder = new CallBuilder<ServerApi.AccountRecord>(this.url.clone());
const builder = new CallBuilder<ServerApi.AccountRecord>(this.url.clone(), this.httpClient);
builder.filter.push([id]);
return builder;
}
Expand Down
5 changes: 3 additions & 2 deletions src/horizon/assets_call_builder.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { HttpClient } from "../http-client";
import { CallBuilder } from "./call_builder";
import { ServerApi } from "./server_api";

Expand All @@ -14,8 +15,8 @@ import { ServerApi } from "./server_api";
export class AssetsCallBuilder extends CallBuilder<
ServerApi.CollectionPage<ServerApi.AssetRecord>
> {
constructor(serverUrl: URI) {
super(serverUrl);
constructor(serverUrl: URI, client: HttpClient) {
super(serverUrl, client);
this.url.segment("assets");
}

Expand Down
9 changes: 6 additions & 3 deletions src/horizon/call_builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import URITemplate from "urijs/src/URITemplate";
import { BadRequestError, NetworkError, NotFoundError } from "../errors";

import { HorizonApi } from "./horizon_api";
import { AxiosClient, version } from "./horizon_axios_client";
import { version } from "./horizon_axios_client";
import { ServerApi } from "./server_api";
import type { Server } from "../federation";
import { HttpClient } from "../http-client";

// Resources which can be included in the Horizon response via the `join`
// query-param.
Expand Down Expand Up @@ -56,12 +57,14 @@ export class CallBuilder<
protected originalSegments: string[];

protected neighborRoot: string;
protected httpClient: HttpClient;

constructor(serverUrl: URI, neighborRoot: string = "") {
constructor(serverUrl: URI, client: HttpClient, neighborRoot: string = "") {
this.url = serverUrl.clone();
this.filter = [];
this.originalSegments = this.url.segment() || [];
this.neighborRoot = neighborRoot;
this.httpClient = client;
}

/**
Expand Down Expand Up @@ -367,7 +370,7 @@ export class CallBuilder<
url = url.protocol(this.url.protocol());
}

return AxiosClient.get(url.toString())
return this.httpClient.get(url.toString())
.then((response) => response.data)
.catch(this._handleNetworkError);
}
Expand Down
6 changes: 4 additions & 2 deletions src/horizon/claimable_balances_call_builder.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Asset } from "@stellar/stellar-base";
import { CallBuilder } from "./call_builder";
import { ServerApi } from "./server_api";
import { HttpClient } from "../http-client";

/**
* Creates a new {@link ClaimableBalanceCallBuilder} pointed to server defined by serverUrl.
Expand All @@ -17,8 +18,8 @@ import { ServerApi } from "./server_api";
export class ClaimableBalanceCallBuilder extends CallBuilder<
ServerApi.CollectionPage<ServerApi.ClaimableBalanceRecord>
> {
constructor(serverUrl: URI) {
super(serverUrl);
constructor(serverUrl: URI, client: HttpClient) {
super(serverUrl, client);
this.url.segment("claimable_balances");
}

Expand All @@ -34,6 +35,7 @@ export class ClaimableBalanceCallBuilder extends CallBuilder<
): CallBuilder<ServerApi.ClaimableBalanceRecord> {
const builder = new CallBuilder<ServerApi.ClaimableBalanceRecord>(
this.url.clone(),
this.httpClient
);
builder.filter.push([claimableBalanceId]);
return builder;
Expand Down
5 changes: 3 additions & 2 deletions src/horizon/effect_call_builder.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { HttpClient } from "../http-client";
import { CallBuilder } from "./call_builder";
import { ServerApi } from "./server_api";

Expand All @@ -15,8 +16,8 @@ import { ServerApi } from "./server_api";
export class EffectCallBuilder extends CallBuilder<
ServerApi.CollectionPage<ServerApi.EffectRecord>
> {
constructor(serverUrl: URI) {
super(serverUrl, "effects");
constructor(serverUrl: URI, client: HttpClient) {
super(serverUrl, client, "effects");
this.url.segment("effects");
}

Expand Down
5 changes: 3 additions & 2 deletions src/horizon/friendbot_builder.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { HttpClient } from "../http-client";
import { CallBuilder } from "./call_builder";

export class FriendbotBuilder extends CallBuilder<any> {
constructor(serverUrl: URI, address: string) {
super(serverUrl);
constructor(serverUrl: URI, client: HttpClient, address: string) {
super(serverUrl, client);
this.url.segment("friendbot");
this.url.setQuery("addr", address);
}
Expand Down
69 changes: 36 additions & 33 deletions src/horizon/horizon_axios_client.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable global-require */
import URI from "urijs";
import { create, HttpResponseHeaders } from "../http-client";
import { create, HttpClient, HttpResponseHeaders } from "../http-client";

// eslint-disable-next-line prefer-import/prefer-import-over-require , @typescript-eslint/naming-convention
declare const __PACKAGE_VERSION__: string;
Expand Down Expand Up @@ -29,46 +29,49 @@ export interface ServerTime {
* @memberof module:Horizon
*/
export const SERVER_TIME_MAP: Record<string, ServerTime> = {};

export const AxiosClient = create({
headers: {
"X-Client-Name": "js-stellar-sdk",
"X-Client-Version": version,
},
});
export const DEFAULT_HEADERS: Record<string, string> = {
"X-Client-Name": "js-stellar-sdk",
"X-Client-Version": version,
};

function toSeconds(ms: number): number {
return Math.floor(ms / 1000);
}

AxiosClient.interceptors.response.use(
(response) => {
const hostname = URI(response.config.url!).hostname();
let serverTime = 0;
if (response.headers instanceof Headers) {
const dateHeader = response.headers.get('date');
if (dateHeader) {
serverTime = toSeconds(Date.parse(dateHeader));
}
} else if (typeof response.headers === 'object' && 'date' in response.headers) {
const headers = response.headers as HttpResponseHeaders; // Cast response.headers to the correct type
if (typeof headers.date === 'string') {
serverTime = toSeconds(Date.parse(headers.date));
export function createHttpClient(): HttpClient {
const httpClient = create({
headers: DEFAULT_HEADERS,
});

httpClient.interceptors.response.use(
(response) => {
const hostname = URI(response.config.url!).hostname();
let serverTime = 0;
if (response.headers instanceof Headers) {
const dateHeader = response.headers.get('date');
if (dateHeader) {
serverTime = toSeconds(Date.parse(dateHeader));
}
} else if (typeof response.headers === 'object' && 'date' in response.headers) {
const headers = response.headers as HttpResponseHeaders; // Cast response.headers to the correct type
if (typeof headers.date === 'string') {
serverTime = toSeconds(Date.parse(headers.date));
}
}
}
const localTimeRecorded = toSeconds(new Date().getTime());
const localTimeRecorded = toSeconds(new Date().getTime());

if (!Number.isNaN(serverTime)) {
SERVER_TIME_MAP[hostname] = {
serverTime,
localTimeRecorded,
};
}
return response;
},
);
if (!Number.isNaN(serverTime)) {
SERVER_TIME_MAP[hostname] = {
serverTime,
localTimeRecorded,
};
}
return response;
},
);

export default AxiosClient;
return httpClient;
}

/**
* Given a hostname, get the current time of that server (i.e., use the last-
Expand Down
2 changes: 1 addition & 1 deletion src/horizon/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ export * from "./account_response";

export { HorizonServer as Server } from "./server";
export {
default as AxiosClient,
SERVER_TIME_MAP,
createHttpClient,
getCurrentServerTime
} from "./horizon_axios_client";

Expand Down
5 changes: 3 additions & 2 deletions src/horizon/ledger_call_builder.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { HttpClient } from "../http-client";
import { CallBuilder } from "./call_builder";
import { ServerApi } from "./server_api";

Expand All @@ -16,8 +17,8 @@ import { ServerApi } from "./server_api";
export class LedgerCallBuilder extends CallBuilder<
ServerApi.CollectionPage<ServerApi.LedgerRecord>
> {
constructor(serverUrl: URI) {
super(serverUrl);
constructor(serverUrl: URI, client: HttpClient) {
super(serverUrl, client);
this.url.segment("ledgers");
}

Expand Down
6 changes: 4 additions & 2 deletions src/horizon/liquidity_pool_call_builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Asset } from "@stellar/stellar-base";

import { CallBuilder } from "./call_builder";
import { ServerApi } from "./server_api";
import { HttpClient } from "../http-client";

/**
* Creates a new {@link LiquidityPoolCallBuilder} pointed to server defined by serverUrl.
Expand All @@ -16,8 +17,8 @@ import { ServerApi } from "./server_api";
export class LiquidityPoolCallBuilder extends CallBuilder<
ServerApi.CollectionPage<ServerApi.LiquidityPoolRecord>
> {
constructor(serverUrl: URI) {
super(serverUrl);
constructor(serverUrl: URI, client: HttpClient) {
super(serverUrl, client);
this.url.segment("liquidity_pools");
}

Expand Down Expand Up @@ -61,6 +62,7 @@ export class LiquidityPoolCallBuilder extends CallBuilder<

const builder = new CallBuilder<ServerApi.LiquidityPoolRecord>(
this.url.clone(),
this.httpClient
);
builder.filter.push([id.toLowerCase()]);
return builder;
Expand Down
7 changes: 4 additions & 3 deletions src/horizon/offer_call_builder.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Asset } from "@stellar/stellar-base";
import { CallBuilder } from "./call_builder";
import { ServerApi } from "./server_api";
import { HttpClient } from "../http-client";

/**
* Creates a new {@link OfferCallBuilder} pointed to server defined by serverUrl.
Expand All @@ -17,8 +18,8 @@ import { ServerApi } from "./server_api";
export class OfferCallBuilder extends CallBuilder<
ServerApi.CollectionPage<ServerApi.OfferRecord>
> {
constructor(serverUrl: URI) {
super(serverUrl, "offers");
constructor(serverUrl: URI, client: HttpClient) {
super(serverUrl, client, "offers");
this.url.segment("offers");
}

Expand All @@ -30,7 +31,7 @@ export class OfferCallBuilder extends CallBuilder<
* @returns {CallBuilder<ServerApi.OfferRecord>} CallBuilder<ServerApi.OfferRecord> OperationCallBuilder instance
*/
public offer(offerId: string): CallBuilder<ServerApi.OfferRecord> {
const builder = new CallBuilder<ServerApi.OfferRecord>(this.url.clone());
const builder = new CallBuilder<ServerApi.OfferRecord>(this.url.clone(), this.httpClient);
builder.filter.push([offerId]);
return builder;
}
Expand Down
6 changes: 4 additions & 2 deletions src/horizon/operation_call_builder.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { HttpClient } from "../http-client";
import { CallBuilder } from "./call_builder";
import { ServerApi } from "./server_api";

Expand All @@ -16,8 +17,8 @@ import { ServerApi } from "./server_api";
export class OperationCallBuilder extends CallBuilder<
ServerApi.CollectionPage<ServerApi.OperationRecord>
> {
constructor(serverUrl: URI) {
super(serverUrl, "operations");
constructor(serverUrl: URI, client: HttpClient) {
super(serverUrl, client, "operations");
this.url.segment("operations");
}

Expand All @@ -33,6 +34,7 @@ export class OperationCallBuilder extends CallBuilder<
): CallBuilder<ServerApi.OperationRecord> {
const builder = new CallBuilder<ServerApi.OperationRecord>(
this.url.clone(),
this.httpClient
);
builder.filter.push([operationId]);
return builder;
Expand Down
5 changes: 3 additions & 2 deletions src/horizon/orderbook_call_builder.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Asset } from "@stellar/stellar-base";
import { CallBuilder } from "./call_builder";
import { ServerApi } from "./server_api";
import { HttpClient } from "../http-client";

/**
* Creates a new {@link OrderbookCallBuilder} pointed to server defined by serverUrl.
Expand All @@ -17,8 +18,8 @@ import { ServerApi } from "./server_api";
* @param {Asset} buying Asset being bought
*/
export class OrderbookCallBuilder extends CallBuilder<ServerApi.OrderbookRecord> {
constructor(serverUrl: URI, selling: Asset, buying: Asset) {
super(serverUrl);
constructor(serverUrl: URI, client: HttpClient, selling: Asset, buying: Asset) {
super(serverUrl, client);
this.url.segment("order_book");
if (!selling.isNative()) {
this.url.setQuery("selling_asset_type", selling.getAssetType());
Expand Down
4 changes: 3 additions & 1 deletion src/horizon/path_call_builder.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Asset } from "@stellar/stellar-base";
import { CallBuilder } from "./call_builder";
import { ServerApi } from "./server_api";
import { HttpClient } from "../http-client";

/**
* The Stellar Network allows payments to be made across assets through path payments. A path payment specifies a
Expand Down Expand Up @@ -36,12 +37,13 @@ export class PathCallBuilder extends CallBuilder<
> {
constructor(
serverUrl: URI,
client: HttpClient,
source: string,
destination: string,
destinationAsset: Asset,
destinationAmount: string
) {
super(serverUrl);
super(serverUrl, client);
this.url.segment("paths");
this.url.setQuery("destination_account", destination);
this.url.setQuery("source_account", source);
Expand Down
5 changes: 3 additions & 2 deletions src/horizon/payment_call_builder.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { HttpClient } from "../http-client";
import { CallBuilder } from "./call_builder";
import { ServerApi } from "./server_api";

Expand All @@ -24,8 +25,8 @@ export class PaymentCallBuilder extends CallBuilder<
| ServerApi.InvokeHostFunctionOperationRecord
>
> {
constructor(serverUrl: URI) {
super(serverUrl, "payments");
constructor(serverUrl: URI, client: HttpClient) {
super(serverUrl, client, "payments");
this.url.segment("payments");
}

Expand Down
Loading
Loading