Create HttpEndpoint interface
This commit is contained in:
parent
244a4d8a84
commit
7d62e8fc0d
21
packages/cli/examples/figment.ts
Normal file
21
packages/cli/examples/figment.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { StargateClient } from "@cosmjs/stargate";
|
||||
|
||||
// Network config
|
||||
const rpcEndpoint = {
|
||||
// Note: we removed the /status patch from the examples because we use the HTTP POST API
|
||||
url: "https://cosmoshub-4--rpc--full.datahub.figment.io/",
|
||||
headers: {
|
||||
"Authorization": "5195ebb0bfb7f0fe5c43409240c8b2c4",
|
||||
}
|
||||
};
|
||||
|
||||
// Setup client
|
||||
const client = await StargateClient.connect(rpcEndpoint);
|
||||
|
||||
// Get some data
|
||||
const chainId = await client.getChainId();
|
||||
console.log("Chain ID:", chainId);
|
||||
const balance = await client.getAllBalances("cosmos1ey69r37gfxvxg62sh4r0ktpuc46pzjrmz29g45");
|
||||
console.log("Balances:", balance);
|
||||
|
||||
client.disconnect();
|
||||
@ -17,3 +17,6 @@ if [ -n "${SIMAPP42_ENABLED:-}" ]; then
|
||||
yarn node ./bin/cosmjs-cli --init examples/stargate.ts --code "process.exit(0)"
|
||||
yarn node ./bin/cosmjs-cli --init examples/simulate.ts --code "process.exit(0)"
|
||||
fi
|
||||
|
||||
# Disabled as this requires internet access
|
||||
# yarn node ./bin/cosmjs-cli --init examples/figment.ts --code "process.exit(0)"
|
||||
|
||||
@ -23,7 +23,7 @@ import {
|
||||
TimeoutError,
|
||||
TxExtension,
|
||||
} from "@cosmjs/stargate";
|
||||
import { Tendermint34Client, toRfc3339WithNanoseconds } from "@cosmjs/tendermint-rpc";
|
||||
import { HttpEndpoint, Tendermint34Client, toRfc3339WithNanoseconds } from "@cosmjs/tendermint-rpc";
|
||||
import { assert, sleep } from "@cosmjs/utils";
|
||||
import {
|
||||
CodeInfoResponse,
|
||||
@ -89,7 +89,7 @@ export class CosmWasmClient {
|
||||
private readonly codesCache = new Map<number, CodeDetails>();
|
||||
private chainId: string | undefined;
|
||||
|
||||
public static async connect(endpoint: string): Promise<CosmWasmClient> {
|
||||
public static async connect(endpoint: string | HttpEndpoint): Promise<CosmWasmClient> {
|
||||
const tmClient = await Tendermint34Client.connect(endpoint);
|
||||
return new CosmWasmClient(tmClient);
|
||||
}
|
||||
|
||||
@ -29,3 +29,6 @@ export {
|
||||
SigningCosmWasmClientOptions,
|
||||
UploadResult,
|
||||
} from "./signingcosmwasmclient";
|
||||
|
||||
// Re-exported because this is part of the CosmWasmClient/SigningCosmWasmClient APIs
|
||||
export { HttpEndpoint } from "@cosmjs/tendermint-rpc";
|
||||
|
||||
@ -30,7 +30,7 @@ import {
|
||||
SignerData,
|
||||
StdFee,
|
||||
} from "@cosmjs/stargate";
|
||||
import { Tendermint34Client } from "@cosmjs/tendermint-rpc";
|
||||
import { HttpEndpoint, Tendermint34Client } from "@cosmjs/tendermint-rpc";
|
||||
import { assert, assertDefined } from "@cosmjs/utils";
|
||||
import { MsgWithdrawDelegatorReward } from "cosmjs-types/cosmos/distribution/v1beta1/tx";
|
||||
import { MsgDelegate, MsgUndelegate } from "cosmjs-types/cosmos/staking/v1beta1/tx";
|
||||
@ -172,7 +172,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
|
||||
private readonly gasPrice: GasPrice | undefined;
|
||||
|
||||
public static async connectWithSigner(
|
||||
endpoint: string,
|
||||
endpoint: string | HttpEndpoint,
|
||||
signer: OfflineSigner,
|
||||
options: SigningCosmWasmClientOptions = {},
|
||||
): Promise<SigningCosmWasmClient> {
|
||||
|
||||
@ -122,3 +122,6 @@ export {
|
||||
} from "./stargateclient";
|
||||
export { StdFee } from "@cosmjs/amino";
|
||||
export { Coin, coin, coins, makeCosmoshubPath, parseCoins } from "@cosmjs/proto-signing";
|
||||
|
||||
// Re-exported because this is part of the StargateClient/SigningStargateClient APIs
|
||||
export { HttpEndpoint } from "@cosmjs/tendermint-rpc";
|
||||
|
||||
@ -12,7 +12,7 @@ import {
|
||||
Registry,
|
||||
TxBodyEncodeObject,
|
||||
} from "@cosmjs/proto-signing";
|
||||
import { Tendermint34Client } from "@cosmjs/tendermint-rpc";
|
||||
import { HttpEndpoint, Tendermint34Client } from "@cosmjs/tendermint-rpc";
|
||||
import { assert, assertDefined } from "@cosmjs/utils";
|
||||
import { Coin } from "cosmjs-types/cosmos/base/v1beta1/coin";
|
||||
import { MsgWithdrawDelegatorReward } from "cosmjs-types/cosmos/distribution/v1beta1/tx";
|
||||
@ -116,7 +116,7 @@ export class SigningStargateClient extends StargateClient {
|
||||
private readonly gasPrice: GasPrice | undefined;
|
||||
|
||||
public static async connectWithSigner(
|
||||
endpoint: string,
|
||||
endpoint: string | HttpEndpoint,
|
||||
signer: OfflineSigner,
|
||||
options: SigningStargateClientOptions = {},
|
||||
): Promise<SigningStargateClient> {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
import { toHex } from "@cosmjs/encoding";
|
||||
import { Uint53 } from "@cosmjs/math";
|
||||
import { Tendermint34Client, toRfc3339WithNanoseconds } from "@cosmjs/tendermint-rpc";
|
||||
import { HttpEndpoint, Tendermint34Client, toRfc3339WithNanoseconds } from "@cosmjs/tendermint-rpc";
|
||||
import { sleep } from "@cosmjs/utils";
|
||||
import { MsgData } from "cosmjs-types/cosmos/base/abci/v1beta1/abci";
|
||||
import { Coin } from "cosmjs-types/cosmos/base/v1beta1/coin";
|
||||
@ -149,7 +149,7 @@ export class StargateClient {
|
||||
private readonly accountParser: AccountParser;
|
||||
|
||||
public static async connect(
|
||||
endpoint: string,
|
||||
endpoint: string | HttpEndpoint,
|
||||
options: StargateClientOptions = {},
|
||||
): Promise<StargateClient> {
|
||||
const tmClient = await Tendermint34Client.connect(endpoint);
|
||||
|
||||
@ -12,6 +12,10 @@ export {
|
||||
toRfc3339WithNanoseconds,
|
||||
toSeconds,
|
||||
} from "./dates";
|
||||
export {
|
||||
// This type is part of the Tendermint34Client.connect API
|
||||
HttpEndpoint,
|
||||
} from "./rpcclients";
|
||||
export { HttpClient, WebsocketClient } from "./rpcclients"; // TODO: Why do we export those outside of this package?
|
||||
export {
|
||||
AbciInfoRequest,
|
||||
|
||||
@ -13,13 +13,13 @@ const tendermintUrl = defaultInstance.url;
|
||||
describe("http", () => {
|
||||
it("can send a health request", async () => {
|
||||
pendingWithoutTendermint();
|
||||
const response = await http("POST", `http://${tendermintUrl}`, createJsonRpcRequest("health"));
|
||||
const response = await http("POST", `http://${tendermintUrl}`, undefined, createJsonRpcRequest("health"));
|
||||
expect(response).toEqual(jasmine.objectContaining({ jsonrpc: "2.0" }));
|
||||
});
|
||||
|
||||
it("errors for non-open port", async () => {
|
||||
await expectAsync(
|
||||
http("POST", `http://localhost:56745`, createJsonRpcRequest("health")),
|
||||
http("POST", `http://localhost:56745`, undefined, createJsonRpcRequest("health")),
|
||||
).toBeRejectedWithError(/(ECONNREFUSED|Failed to fetch)/i);
|
||||
});
|
||||
});
|
||||
|
||||
@ -11,6 +11,8 @@ import { hasProtocol, RpcClient } from "./rpcclient";
|
||||
// Global symbols in some environments
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch
|
||||
declare const fetch: any | undefined;
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
declare const Headers: any | undefined;
|
||||
|
||||
function filterBadStatus(res: any): any {
|
||||
if (res.status >= 400) {
|
||||
@ -25,23 +27,55 @@ function filterBadStatus(res: any): any {
|
||||
* For some reason, fetch does not complain about missing server-side CORS support.
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
export async function http(method: "POST", url: string, request?: any): Promise<any> {
|
||||
export async function http(
|
||||
method: "POST",
|
||||
url: string,
|
||||
headers: Record<string, string> | undefined,
|
||||
request?: any,
|
||||
): Promise<any> {
|
||||
if (typeof fetch !== "undefined") {
|
||||
const body = request ? JSON.stringify(request) : undefined;
|
||||
return fetch(url, { method: method, body: body })
|
||||
const settings = {
|
||||
method: method,
|
||||
body: body,
|
||||
headers: headers ? new Headers(headers) : undefined,
|
||||
};
|
||||
return fetch(url, settings)
|
||||
.then(filterBadStatus)
|
||||
.then((res: any) => res.json());
|
||||
} else {
|
||||
return axios.request({ url: url, method: method, data: request }).then((res) => res.data);
|
||||
return axios
|
||||
.request({ url: url, method: method, data: request, headers: headers })
|
||||
.then((res) => res.data);
|
||||
}
|
||||
}
|
||||
|
||||
export interface HttpEndpoint {
|
||||
/**
|
||||
* The URL of the HTTP endpoint.
|
||||
*
|
||||
* For POST APIs like Tendermint RPC in CosmJS,
|
||||
* this is without the method specific paths (e.g. https://cosmoshub-4--rpc--full.datahub.figment.io/)
|
||||
*/
|
||||
readonly url: string;
|
||||
/**
|
||||
* HTTP headers that are sent with every request, such as authorization information.
|
||||
*/
|
||||
readonly headers: Record<string, string>;
|
||||
}
|
||||
|
||||
export class HttpClient implements RpcClient {
|
||||
protected readonly url: string;
|
||||
protected readonly headers: Record<string, string> | undefined;
|
||||
|
||||
public constructor(url: string) {
|
||||
// accept host.name:port and assume http protocol
|
||||
this.url = hasProtocol(url) ? url : "http://" + url;
|
||||
public constructor(endpoint: string | HttpEndpoint) {
|
||||
if (typeof endpoint === "string") {
|
||||
// accept host.name:port and assume http protocol
|
||||
this.url = hasProtocol(endpoint) ? endpoint : "http://" + endpoint;
|
||||
} else {
|
||||
this.url = endpoint.url;
|
||||
this.headers = endpoint.headers;
|
||||
}
|
||||
}
|
||||
|
||||
public disconnect(): void {
|
||||
@ -49,7 +83,7 @@ export class HttpClient implements RpcClient {
|
||||
}
|
||||
|
||||
public async execute(request: JsonRpcRequest): Promise<JsonRpcSuccessResponse> {
|
||||
const response = parseJsonRpcResponse(await http("POST", this.url, request));
|
||||
const response = parseJsonRpcResponse(await http("POST", this.url, this.headers, request));
|
||||
if (isJsonRpcErrorResponse(response)) {
|
||||
throw new Error(JSON.stringify(response.error));
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// This folder contains Tendermint-specific RPC clients
|
||||
|
||||
export { HttpClient } from "./httpclient";
|
||||
export { HttpClient, HttpEndpoint } from "./httpclient";
|
||||
export { instanceOfRpcStreamingClient, RpcClient, RpcStreamingClient, SubscriptionEvent } from "./rpcclient";
|
||||
export { WebsocketClient } from "./websocketclient";
|
||||
|
||||
@ -4,6 +4,7 @@ import { Stream } from "xstream";
|
||||
import { createJsonRpcRequest } from "../jsonrpc";
|
||||
import {
|
||||
HttpClient,
|
||||
HttpEndpoint,
|
||||
instanceOfRpcStreamingClient,
|
||||
RpcClient,
|
||||
SubscriptionEvent,
|
||||
@ -19,10 +20,14 @@ export class Tendermint34Client {
|
||||
*
|
||||
* Uses HTTP when the URL schema is http or https. Uses WebSockets otherwise.
|
||||
*/
|
||||
public static async connect(url: string): Promise<Tendermint34Client> {
|
||||
const useHttp = url.startsWith("http://") || url.startsWith("https://");
|
||||
const rpcClient = useHttp ? new HttpClient(url) : new WebsocketClient(url);
|
||||
return Tendermint34Client.create(rpcClient);
|
||||
public static async connect(endpoint: string | HttpEndpoint): Promise<Tendermint34Client> {
|
||||
if (typeof endpoint === "object") {
|
||||
return Tendermint34Client.create(new HttpClient(endpoint));
|
||||
} else {
|
||||
const useHttp = endpoint.startsWith("http://") || endpoint.startsWith("https://");
|
||||
const rpcClient = useHttp ? new HttpClient(endpoint) : new WebsocketClient(endpoint);
|
||||
return Tendermint34Client.create(rpcClient);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
Reference in New Issue
Block a user