Pull out AuthModule

This commit is contained in:
Simon Warta 2020-07-07 23:31:14 +02:00
parent b352e942ab
commit c85c172395
16 changed files with 158 additions and 69 deletions

View File

@ -2,6 +2,7 @@
import { Sha256 } from "@cosmjs/crypto";
import { Bech32, fromAscii, fromBase64, fromHex, toAscii, toBase64, toHex } from "@cosmjs/encoding";
import {
AuthModule,
Coin,
coin,
coins,
@ -10,6 +11,7 @@ import {
Pen,
PostTxsResponse,
Secp256k1Pen,
setupAuthModule,
StdFee,
} from "@cosmjs/sdk38";
import { assert } from "@cosmjs/utils";
@ -37,10 +39,10 @@ import {
} from "../testutils.spec";
import { setupWasmModule, WasmModule } from "./wasm";
type WasmClient = LcdClient & WasmModule;
type WasmClient = LcdClient & AuthModule & WasmModule;
function makeWasmClient(apiUrl: string): WasmClient {
return LcdClient.withModules({ apiUrl }, setupWasmModule);
return LcdClient.withModules({ apiUrl }, setupAuthModule, setupWasmModule);
}
async function uploadContract(

View File

@ -3,7 +3,7 @@ import { fromBase64, fromHex, toHex } from "@cosmjs/encoding";
import { Uint53 } from "@cosmjs/math";
import { Coin } from "./coins";
import { BroadcastMode, LcdClient } from "./lcdapi";
import { AuthModule, BroadcastMode, LcdClient, setupAuthModule } from "./lcdapi";
import { Log, parseLogs } from "./logs";
import { decodeBech32Pubkey } from "./pubkey";
import { CosmosSdkTx, PubKey, StdTx } from "./types";
@ -130,11 +130,11 @@ export interface Block {
/** Use for testing only */
export interface PrivateCosmWasmClient {
readonly lcdClient: LcdClient;
readonly lcdClient: LcdClient & AuthModule;
}
export class CosmosClient {
protected readonly lcdClient: LcdClient;
protected readonly lcdClient: LcdClient & AuthModule;
/** Any address the chain considers valid (valid bech32 with proper prefix) */
protected anyValidAddress: string | undefined;
@ -150,7 +150,7 @@ export class CosmosClient {
* @param broadcastMode Defines at which point of the transaction processing the postTx method (i.e. transaction broadcasting) returns
*/
public constructor(apiUrl: string, broadcastMode = BroadcastMode.Block) {
this.lcdClient = new LcdClient(apiUrl, broadcastMode);
this.lcdClient = LcdClient.withModules({ apiUrl: apiUrl, broadcastMode: broadcastMode }, setupAuthModule);
}
public async getChainId(): Promise<string> {

View File

@ -22,6 +22,7 @@ export {
export { makeSignBytes } from "./encoding";
export {
AuthAccountsResponse,
AuthModule,
BlockResponse,
BroadcastMode,
EncodeTxResponse,
@ -32,6 +33,9 @@ export {
normalizeLcdApiArray,
PostTxsResponse,
SearchTxsResponse,
setupAuthModule,
setupSupplyModule,
SupplyModule,
TxsResponse,
} from "./lcdapi";
export { RestClient } from "./restclient";

View File

@ -0,0 +1,68 @@
/* eslint-disable @typescript-eslint/camelcase */
import { encodeBech32Pubkey } from "../pubkey";
import {
faucet,
makeRandomAddress,
nonNegativeIntegerMatcher,
pendingWithoutWasmd,
unused,
wasmd,
} from "../testutils.spec";
import { AuthModule, setupAuthModule } from "./auth";
import { LcdClient } from "./lcdclient";
function makeAuthClient(apiUrl: string): LcdClient & AuthModule {
return LcdClient.withModules({ apiUrl }, setupAuthModule);
}
describe("auth", () => {
it("works for unused account without pubkey", async () => {
pendingWithoutWasmd();
const client = makeAuthClient(wasmd.endpoint);
const { height, result } = await client.authAccounts(unused.address);
expect(height).toMatch(nonNegativeIntegerMatcher);
expect(result).toEqual({
type: "cosmos-sdk/Account",
value: {
address: unused.address,
public_key: "", // not known to the chain
coins: [
{
amount: "1000000000",
denom: "ucosm",
},
{
amount: "1000000000",
denom: "ustake",
},
],
account_number: unused.accountNumber,
sequence: 0,
},
});
});
// This fails in the first test run if you forget to run `./scripts/wasmd/init.sh`
it("has correct pubkey for faucet", async () => {
pendingWithoutWasmd();
const client = makeAuthClient(wasmd.endpoint);
const { result } = await client.authAccounts(faucet.address);
expect(result.value).toEqual(
jasmine.objectContaining({
public_key: encodeBech32Pubkey(faucet.pubkey, "cosmospub"),
}),
);
});
// This property is used by CosmWasmClient.getAccount
it("returns empty address for non-existent account", async () => {
pendingWithoutWasmd();
const client = makeAuthClient(wasmd.endpoint);
const nonExistentAccount = makeRandomAddress();
const { result } = await client.authAccounts(nonExistentAccount);
expect(result).toEqual({
type: "cosmos-sdk/Account",
value: jasmine.objectContaining({ address: "" }),
});
});
});

View File

@ -0,0 +1,37 @@
import { Coin } from "../coins";
import { LcdClient, LcdModule } from "./lcdclient";
export interface CosmosSdkAccount {
/** Bech32 account address */
readonly address: string;
readonly coins: readonly Coin[];
/** Bech32 encoded pubkey */
readonly public_key: string;
readonly account_number: number;
readonly sequence: number;
}
export interface AuthAccountsResponse {
readonly height: string;
readonly result: {
readonly type: "cosmos-sdk/Account";
readonly value: CosmosSdkAccount;
};
}
export interface AuthModule extends LcdModule {
readonly authAccounts: (address: string) => Promise<AuthAccountsResponse>;
}
export function setupAuthModule(base: LcdClient): AuthModule {
return {
authAccounts: async (address: string) => {
const path = `/auth/accounts/${address}`;
const responseData = await base.get(path);
if (responseData.result.type !== "cosmos-sdk/Account") {
throw new Error("Unexpected response data format");
}
return responseData as AuthAccountsResponse;
},
};
}

View File

@ -1,4 +1,3 @@
import { Coin } from "../coins";
import { CosmosSdkTx } from "../types";
/**
@ -100,24 +99,6 @@ export interface BlockResponse {
readonly block: Block;
}
export interface CosmosSdkAccount {
/** Bech32 account address */
readonly address: string;
readonly coins: readonly Coin[];
/** Bech32 encoded pubkey */
readonly public_key: string;
readonly account_number: number;
readonly sequence: number;
}
export interface AuthAccountsResponse {
readonly height: string;
readonly result: {
readonly type: "cosmos-sdk/Account";
readonly value: CosmosSdkAccount;
};
}
export interface TxsResponse {
readonly height: string;
readonly txhash: string;

View File

@ -2,14 +2,14 @@
// Standard modules (see tracking issue https://github.com/CosmWasm/cosmjs/issues/276)
//
export { SupplyModule, TotalSupplyAllReponse, TotalSupplyReponse } from "./supply";
export { AuthModule, AuthAccountsResponse, setupAuthModule } from "./auth";
export { setupSupplyModule, SupplyModule, TotalSupplyAllReponse, TotalSupplyReponse } from "./supply";
//
// Base types
//
export {
AuthAccountsResponse,
BlockResponse,
BroadcastMode,
EncodeTxResponse,

View File

@ -21,6 +21,7 @@ import {
wasmdEnabled,
} from "../testutils.spec";
import { StdFee } from "../types";
import { setupAuthModule } from "./auth";
import { TxsResponse } from "./base";
import { LcdApiArray, LcdClient, normalizeLcdApiArray } from "./lcdclient";
@ -523,7 +524,7 @@ describe("LcdClient", () => {
gas: "890000",
};
const client = new LcdClient(wasmd.endpoint);
const client = LcdClient.withModules({ apiUrl: wasmd.endpoint }, setupAuthModule);
const { account_number, sequence } = (await client.authAccounts(faucet.address)).result.value;
const signBytes = makeSignBytes([theMsg], fee, wasmd.chainId, memo, account_number, sequence);
@ -576,7 +577,7 @@ describe("LcdClient", () => {
gas: "890000",
};
const client = new LcdClient(wasmd.endpoint);
const client = LcdClient.withModules({ apiUrl: wasmd.endpoint }, setupAuthModule);
const { account_number: an1, sequence: sequence1 } = (await client.authAccounts(address1)).result.value;
const { account_number: an2, sequence: sequence2 } = (await client.authAccounts(address2)).result.value;
const { account_number: an3, sequence: sequence3 } = (await client.authAccounts(address3)).result.value;
@ -641,7 +642,7 @@ describe("LcdClient", () => {
gas: "890000",
};
const client = new LcdClient(wasmd.endpoint);
const client = LcdClient.withModules({ apiUrl: wasmd.endpoint }, setupAuthModule);
const { account_number, sequence } = (await client.authAccounts(address1)).result.value;
const signBytes = makeSignBytes([msg1, msg2], fee, wasmd.chainId, memo, account_number, sequence);
@ -701,7 +702,7 @@ describe("LcdClient", () => {
gas: "890000",
};
const client = new LcdClient(wasmd.endpoint);
const client = LcdClient.withModules({ apiUrl: wasmd.endpoint }, setupAuthModule);
const { account_number: an1, sequence: sequence1 } = (await client.authAccounts(address1)).result.value;
const { account_number: an2, sequence: sequence2 } = (await client.authAccounts(address2)).result.value;
@ -769,7 +770,7 @@ describe("LcdClient", () => {
gas: "890000",
};
const client = new LcdClient(wasmd.endpoint);
const client = LcdClient.withModules({ apiUrl: wasmd.endpoint }, setupAuthModule);
const { account_number: an1, sequence: sequence1 } = (await client.authAccounts(address1)).result.value;
const { account_number: an2, sequence: sequence2 } = (await client.authAccounts(address2)).result.value;
@ -832,7 +833,7 @@ describe("LcdClient", () => {
gas: "890000",
};
const client = new LcdClient(wasmd.endpoint);
const client = LcdClient.withModules({ apiUrl: wasmd.endpoint }, setupAuthModule);
const { account_number: an1, sequence: sequence1 } = (await client.authAccounts(address1)).result.value;
const { account_number: an2, sequence: sequence2 } = (await client.authAccounts(address2)).result.value;

View File

@ -4,7 +4,6 @@ import axios, { AxiosError, AxiosInstance } from "axios";
import { CosmosSdkTx, StdTx } from "../types";
import {
AuthAccountsResponse,
BlockResponse,
BroadcastMode,
EncodeTxResponse,
@ -263,17 +262,6 @@ export class LcdClient {
return data;
}
// The /auth endpoints
public async authAccounts(address: string): Promise<AuthAccountsResponse> {
const path = `/auth/accounts/${address}`;
const responseData = await this.get(path);
if (responseData.result.type !== "cosmos-sdk/Account") {
throw new Error("Unexpected response data format");
}
return responseData as AuthAccountsResponse;
}
// The /blocks endpoints
public async blocksLatest(): Promise<BlockResponse> {

View File

@ -1,5 +1,5 @@
import { Coin } from "./coins";
import { BroadcastMode, LcdClient } from "./lcdapi";
import { AuthModule, BroadcastMode, LcdClient } from "./lcdapi";
import { Log } from "./logs";
import { CosmosSdkTx, PubKey, StdTx } from "./types";
export interface GetNonceResult {
@ -94,10 +94,10 @@ export interface Block {
}
/** Use for testing only */
export interface PrivateCosmWasmClient {
readonly lcdClient: LcdClient;
readonly lcdClient: LcdClient & AuthModule;
}
export declare class CosmosClient {
protected readonly lcdClient: LcdClient;
protected readonly lcdClient: LcdClient & AuthModule;
/** Any address the chain considers valid (valid bech32 with proper prefix) */
protected anyValidAddress: string | undefined;
private chainId;

View File

@ -20,6 +20,7 @@ export {
export { makeSignBytes } from "./encoding";
export {
AuthAccountsResponse,
AuthModule,
BlockResponse,
BroadcastMode,
EncodeTxResponse,
@ -30,6 +31,9 @@ export {
normalizeLcdApiArray,
PostTxsResponse,
SearchTxsResponse,
setupAuthModule,
setupSupplyModule,
SupplyModule,
TxsResponse,
} from "./lcdapi";
export { RestClient } from "./restclient";

22
packages/sdk38/types/lcdapi/auth.d.ts vendored Normal file
View File

@ -0,0 +1,22 @@
import { Coin } from "../coins";
import { LcdClient, LcdModule } from "./lcdclient";
export interface CosmosSdkAccount {
/** Bech32 account address */
readonly address: string;
readonly coins: readonly Coin[];
/** Bech32 encoded pubkey */
readonly public_key: string;
readonly account_number: number;
readonly sequence: number;
}
export interface AuthAccountsResponse {
readonly height: string;
readonly result: {
readonly type: "cosmos-sdk/Account";
readonly value: CosmosSdkAccount;
};
}
export interface AuthModule extends LcdModule {
readonly authAccounts: (address: string) => Promise<AuthAccountsResponse>;
}
export declare function setupAuthModule(base: LcdClient): AuthModule;

View File

@ -0,0 +1 @@
export {};

View File

@ -1,4 +1,3 @@
import { Coin } from "../coins";
import { CosmosSdkTx } from "../types";
/**
* The mode used to send transaction
@ -85,22 +84,6 @@ export interface BlockResponse {
readonly block_id: BlockId;
readonly block: Block;
}
export interface CosmosSdkAccount {
/** Bech32 account address */
readonly address: string;
readonly coins: readonly Coin[];
/** Bech32 encoded pubkey */
readonly public_key: string;
readonly account_number: number;
readonly sequence: number;
}
export interface AuthAccountsResponse {
readonly height: string;
readonly result: {
readonly type: "cosmos-sdk/Account";
readonly value: CosmosSdkAccount;
};
}
export interface TxsResponse {
readonly height: string;
readonly txhash: string;

View File

@ -1,6 +1,6 @@
export { SupplyModule, TotalSupplyAllReponse, TotalSupplyReponse } from "./supply";
export { AuthModule, AuthAccountsResponse, setupAuthModule } from "./auth";
export { setupSupplyModule, SupplyModule, TotalSupplyAllReponse, TotalSupplyReponse } from "./supply";
export {
AuthAccountsResponse,
BlockResponse,
BroadcastMode,
EncodeTxResponse,

View File

@ -1,6 +1,5 @@
import { CosmosSdkTx, StdTx } from "../types";
import {
AuthAccountsResponse,
BlockResponse,
BroadcastMode,
EncodeTxResponse,
@ -147,7 +146,6 @@ export declare class LcdClient {
constructor(apiUrl: string, broadcastMode?: BroadcastMode);
get(path: string): Promise<any>;
post(path: string, params: any): Promise<any>;
authAccounts(address: string): Promise<AuthAccountsResponse>;
blocksLatest(): Promise<BlockResponse>;
blocks(height: number): Promise<BlockResponse>;
nodeInfo(): Promise<NodeInfoResponse>;