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

feat: add explicit fee parameters #60

Merged
merged 5 commits into from
Jun 3, 2022
Merged
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ So, it exposes CosmJS basic functions as they are, such as `connectWithSigner` a
### Installation

```bash
yarn add @medibloc/panacea-js @cosmjs/proto-signing @cosmjs/stargate
yarn add @medibloc/panacea-js @cosmjs/proto-signing @cosmjs/stargate cosmjs-types
```

### Examples
Expand Down
37 changes: 23 additions & 14 deletions docs/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
```ts
import { panaceaWalletOpts, SigningPanaceaClient } from "@medibloc/panacea-js";
import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing";
import { assertIsBroadcastTxSuccess } from "@cosmjs/stargate";
import { assertIsDeliverTxSuccess } from "@cosmjs/stargate";

const mnemonic = "bulb rail ...";
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, panaceaWalletOpts);
Expand All @@ -19,16 +19,25 @@ const amount = {
denom: "umed",
amount: "123456789",
};
const result = await client.sendTokens(firstAccount.address, recipient, [amount], "memo");
assertIsBroadcastTxSuccess(result);
const fee = {
amount: [{
denom: "umed",
amount: "1000000",
}],
gas: "200000",
};

// or, you can set the fee as "auto"
const result = await client.sendTokens(firstAccount.address, recipient, [amount], fee, "memo");
assertIsDeliverTxSuccess(result);
```

## Creating AOL topics and adding records

```ts
import { panaceaWalletOpts, SigningPanaceaClient } from "@medibloc/panacea-js";
import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing";
import { assertIsBroadcastTxSuccess } from "@cosmjs/stargate";
import { assertIsDeliverTxSuccess } from "@cosmjs/stargate";
import { TextEncoder } from "util";
import Long from "long";

Expand All @@ -42,24 +51,24 @@ const client = await SigningPanaceaClient.connectWithSigner(tendermintRpcEndpoin

const ownerAddress = firstAccount.address;
const topicName = "topic-1"
let result = await client.createTopic(ownerAddress, topicName, "description", "memo");
assertIsBroadcastTxSuccess(result);
let result = await client.createTopic(ownerAddress, topicName, "description", "auto", "memo");
assertIsDeliverTxSuccess(result);

const topic = await client.getPanaceaClient().getTopic(ownerAddress, topicName);
console.log(topic);

const writerAddress = ownerAddress;
result = await client.addWriter(ownerAddress, topicName, writerAddress, "moniker", "description", "memo");
assertIsBroadcastTxSuccess(result);
result = await client.addWriter(ownerAddress, topicName, writerAddress, "moniker", "description", "auto", "memo");
assertIsDeliverTxSuccess(result);

const writer = await client.getPanaceaClient().getWriter(ownerAddress, topicName, writerAddress);
console.log(writer);

// Encode key and value as you want
const key = new TextEncoder().encode("key1");
const value = new TextEncoder().encode("value1");
result = await client.addRecord(ownerAddress, topicName, key, value, writerAddress, "memo");
assertIsBroadcastTxSuccess(result);
result = await client.addRecord(ownerAddress, topicName, key, value, writerAddress, "auto", "memo");
assertIsDeliverTxSuccess(result);

const record = await client.getPanaceaClient().getRecord(ownerAddress, topicName, Long.fromInt(0));
console.log(record);
Expand All @@ -77,15 +86,15 @@ const writerWallet = await DirectSecp256k1HdWallet.fromMnemonic("...", panaceaWa
const tendermintRpcEndpoint = "http://localhost:26657";
const client = await GroupSigningPanaceaClient.connectWithSigner(tendermintRpcEndpoint, [feePayerWallet, writerWallet]);

const result = await client.addRecordWithFeePayer(ownerAddress, topicName, key, value, writerAddress, feePayerAddress, "");
const result = await client.addRecordWithFeePayer(ownerAddress, topicName, key, value, writerAddress, feePayerAddress, "auto", "");
```

## Creating DIDs

```ts
import { panaceaWalletOpts, SigningPanaceaClient, Secp256k1, DidUtil } from "@medibloc/panacea-js";
import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing";
import { assertIsBroadcastTxSuccess } from "@cosmjs/stargate";
import { assertIsDeliverTxSuccess } from "@cosmjs/stargate";

const mnemonic = "bulb rail ...";
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, panaceaWalletOpts);
Expand Down Expand Up @@ -129,8 +138,8 @@ const didDocument = {

const signature = DidUtil.signDidDocument(privKey, didDocument);

const result = await client.createDid(didDocument, verificationMethodId, signature, firstAccount.address);
assertIsBroadcastTxSuccess(result);
const result = await client.createDid(didDocument, verificationMethodId, signature, firstAccount.address, "auto");
assertIsDeliverTxSuccess(result);

const didDocumentWithSeq = await client.getPanaceaClient().getDid(didDocument.id);
console.log(didDocumentWithSeq);
Expand Down
17 changes: 9 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,18 @@
},
"homepage": "https://medibloc.org",
"dependencies": {
"@cosmjs/amino": "0.25.5",
"@cosmjs/crypto": "0.25.5",
"@cosmjs/encoding": "0.25.5",
"@cosmjs/math": "0.25.5",
"@cosmjs/proto-signing": "0.25.5",
"@cosmjs/stargate": "0.25.5",
"@cosmjs/tendermint-rpc": "0.25.5",
"@cosmjs/utils": "0.25.5",
"@cosmjs/amino": "0.28.4",
"@cosmjs/crypto": "0.28.4",
"@cosmjs/encoding": "0.28.4",
"@cosmjs/math": "0.28.4",
"@cosmjs/proto-signing": "0.28.4",
"@cosmjs/stargate": "0.28.4",
"@cosmjs/tendermint-rpc": "0.28.4",
"@cosmjs/utils": "0.28.4",
"@types/bs58": "4.0.1",
"@types/secp256k1": "4.0.3",
"bs58": "4.0.1",
"cosmjs-types": "0.5.0",
"secp256k1": "4.0.2",
"uuid": "8.3.0"
},
Expand Down
15 changes: 11 additions & 4 deletions src/group-signing-panacea-client.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ describe("GroupSigningPanaceaClient", () => {
denom: "umed",
amount: "5000000",
}
const res = await client.sendTokens(ownerAddress, writerAddress, [amount])
const res = await client.sendTokens(ownerAddress, writerAddress, [amount], "auto")
expect(res).toBeTruthy();

topicName = uuidv4();
Expand All @@ -75,10 +75,10 @@ describe("GroupSigningPanaceaClient", () => {
beforeAll(async () => {
const client = await SigningPanaceaClient.connectWithSigner(panacead.tendermintUrl, ownerWallet);

let res = await client.createTopic(ownerAddress, topicName, "", "");
let res = await client.createTopic(ownerAddress, topicName, "", "auto", "");
expect(res).toBeTruthy();

res = await client.addWriter(ownerAddress, topicName, writerAddress, "", "", "");
res = await client.addWriter(ownerAddress, topicName, writerAddress, "", "", "auto", "");
expect(res).toBeTruthy();

client.disconnect();
Expand All @@ -90,7 +90,14 @@ describe("GroupSigningPanaceaClient", () => {
const key = new TextEncoder().encode("key1");
const value = new TextEncoder().encode("value1");

const res = await client.addRecordWithFeePayer(ownerAddress, topicName, key, value, writerAddress, feePayerAddress, "");
const fee = {
amount: [{
denom: "umed",
amount: "1000000",
}],
gas: "200000",
}
const res = await client.addRecordWithFeePayer(ownerAddress, topicName, key, value, writerAddress, feePayerAddress, fee, "");
expect(res).toBeTruthy();

const record = await client.getPanaceaClient().getRecord(ownerAddress, topicName, Long.fromInt(0));
Expand Down
23 changes: 12 additions & 11 deletions src/group-signing-panacea-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,19 @@ import {
OfflineSigner,
TxBodyEncodeObject
} from "@cosmjs/proto-signing";
import { BroadcastTxResponse, SignerData, StdFee } from "@cosmjs/stargate";
import { AuthInfo, SignerInfo, TxRaw } from "@cosmjs/stargate/build/codec/cosmos/tx/v1beta1/tx";
import { DeliverTxResponse, SignerData, StdFee } from "@cosmjs/stargate";
import { assert } from "@cosmjs/utils";
import { encodeSecp256k1Pubkey } from "@cosmjs/amino";
import { Any } from "@cosmjs/stargate/build/codec/google/protobuf/any";
import { Coin } from "@cosmjs/stargate/build/codec/cosmos/base/v1beta1/coin";
import { SignMode } from "@cosmjs/stargate/build/codec/cosmos/tx/signing/v1beta1/signing";
import Long from "long";
import { Int53 } from "@cosmjs/math";
import { fromBase64 } from "@cosmjs/encoding";
import { SigningPanaceaClient, SigningPanaceaClientOptions } from "./signing-panacea-client";
import { SigningPanaceaClient } from "./signing-panacea-client";
import { Tendermint34Client } from "@cosmjs/tendermint-rpc";
import { SigningStargateClientOptions } from "@cosmjs/stargate/build/signingstargateclient";
import { AuthInfo, SignerInfo, TxRaw } from "cosmjs-types/cosmos/tx/v1beta1/tx";
import { Any } from "cosmjs-types/google/protobuf/any";
import { Coin } from "cosmjs-types/cosmos/base/v1beta1/coin";
import { SignMode } from "cosmjs-types/cosmos/tx/signing/v1beta1/signing";

/**
* A class for executing transactions to Panacea with signing by multiple addresses (aka. Group Signing).
Expand All @@ -40,7 +41,7 @@ export class GroupSigningPanaceaClient extends SigningPanaceaClient {
public static async connectWithSigners(
endpoint: string,
signers: OfflineSigner[],
options: SigningPanaceaClientOptions = {},
options: SigningStargateClientOptions = {},
): Promise<GroupSigningPanaceaClient> {
const tmClient = await Tendermint34Client.connect(endpoint);
return new GroupSigningPanaceaClient(tmClient, signers, options);
Expand All @@ -49,7 +50,7 @@ export class GroupSigningPanaceaClient extends SigningPanaceaClient {
protected constructor(
tmClient: Tendermint34Client | undefined,
signers: OfflineSigner[],
options: SigningPanaceaClientOptions,
options: SigningStargateClientOptions,
) {
// Use the first signer for SigningPanaceaClient
super(tmClient, signers[0], options);
Expand All @@ -71,7 +72,7 @@ export class GroupSigningPanaceaClient extends SigningPanaceaClient {
*
* Make sure that GroupSigningPanaceaClient was created with [feePayerSigner, writerSigner]. The order matters.
*/
public async addRecordWithFeePayer(ownerAddress: string, topicName: string, key: Uint8Array, value: Uint8Array, writerAddress: string, feePayerAddress: string, memo?: string): Promise<BroadcastTxResponse> {
public async addRecordWithFeePayer(ownerAddress: string, topicName: string, key: Uint8Array, value: Uint8Array, writerAddress: string, feePayerAddress: string, fee: StdFee, memo?: string): Promise<DeliverTxResponse> {
const msg = {
typeUrl: GroupSigningPanaceaClient.msgTypeAddRecord,
value: {
Expand All @@ -83,7 +84,7 @@ export class GroupSigningPanaceaClient extends SigningPanaceaClient {
feePayerAddress: feePayerAddress,
}
}
return this.groupSignAndBroadcast([feePayerAddress, writerAddress], [msg], this.panaceaFees.addWriter, memo);
return this.groupSignAndBroadcast([feePayerAddress, writerAddress], [msg], fee, memo);
}

// Reference: https://github.com/cosmos/cosmjs/blob/06fbc34f72f12c30a396c3ca296f80eca9fa60b0/packages/stargate/src/signingstargateclient.ts#L280
Expand All @@ -92,7 +93,7 @@ export class GroupSigningPanaceaClient extends SigningPanaceaClient {
messages: readonly EncodeObject[],
fee: StdFee,
memo = "",
): Promise<BroadcastTxResponse> {
): Promise<DeliverTxResponse> {
const txRaw = await this.groupSign(signerAddresses, messages, fee, memo);
const txBytes = TxRaw.encode(txRaw).finish();
return this.broadcastTx(txBytes, this.broadcastTimeoutMs, this.broadcastPollIntervalMs);
Expand Down
21 changes: 11 additions & 10 deletions src/panacea-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { Record } from "./proto/panacea/aol/v2/record";
import Long from "long";
import { DIDDocumentWithSeq } from "./proto/panacea/did/v2/did";
import { Token } from "./proto/panacea/token/v2/token";
import { StargateClientOptions } from "@cosmjs/stargate/build/stargateclient";

const rpcErrMsgNotFound = /rpc error: code = NotFound/i;

Expand All @@ -26,22 +27,22 @@ const rpcErrMsgNotFound = /rpc error: code = NotFound/i;
* It extends StargateClient, so that you can call Stargate general queries, such as getBalance.
*/
export class PanaceaClient extends StargateClient {
constructor(tmClient: Tendermint34Client | undefined) {
super(tmClient);
constructor(tmClient: Tendermint34Client | undefined, options: StargateClientOptions) {
super(tmClient, options);
}

/**
* Creates a PanaceaClient.
*/
static async connect(endpoint: string): Promise<PanaceaClient> {
const tmClient = await Tendermint34Client.connect(endpoint);
return new PanaceaClient(tmClient);
return new PanaceaClient(tmClient, {});
}

async getTopic(ownerAddress: string, topicName: string): Promise<Topic | null> {
const queryService = new AolQueryClientImpl(createProtobufRpcClient(this.forceGetQueryClient()));
try {
const resp = await queryService.Topic({ownerAddress: ownerAddress, topicName: topicName});
const resp = await queryService.Topic({ ownerAddress: ownerAddress, topicName: topicName });
return resp.topic ?? null;
} catch (error) {
if (rpcErrMsgNotFound.test(error)) {
Expand All @@ -53,7 +54,7 @@ export class PanaceaClient extends StargateClient {

async getTopics(ownerAddress: string, pageRequest?: PageRequest): Promise<QueryTopicsResponse> {
const queryService = new AolQueryClientImpl(createProtobufRpcClient(this.forceGetQueryClient()));
return await queryService.Topics({ownerAddress: ownerAddress, pagination: pageRequest});
return await queryService.Topics({ ownerAddress: ownerAddress, pagination: pageRequest });
}

async getWriter(ownerAddress: string, topicName: string, writerAddress: string): Promise<Writer | null> {
Expand All @@ -75,13 +76,13 @@ export class PanaceaClient extends StargateClient {

async getWriters(ownerAddress: string, topicName: string, pageRequest?: PageRequest): Promise<QueryWritersResponse> {
const queryService = new AolQueryClientImpl(createProtobufRpcClient(this.forceGetQueryClient()));
return await queryService.Writers({ownerAddress: ownerAddress, topicName: topicName, pagination: pageRequest});
return await queryService.Writers({ ownerAddress: ownerAddress, topicName: topicName, pagination: pageRequest });
}

async getRecord(ownerAddress: string, topicName: string, offset: Long): Promise<Record | null> {
const queryService = new AolQueryClientImpl(createProtobufRpcClient(this.forceGetQueryClient()));
try {
const resp = await queryService.Record({ownerAddress: ownerAddress, topicName: topicName, offset: offset})
const resp = await queryService.Record({ ownerAddress: ownerAddress, topicName: topicName, offset: offset });
return resp.record ?? null;
} catch (error) {
if (rpcErrMsgNotFound.test(error)) {
Expand All @@ -94,7 +95,7 @@ export class PanaceaClient extends StargateClient {
async getDid(did: string): Promise<DIDDocumentWithSeq | null> {
const queryService = new DidQueryClientImpl(createProtobufRpcClient(this.forceGetQueryClient()));
try {
const resp = await queryService.DID({didBase64: new Buffer(did).toString('base64')});
const resp = await queryService.DID({ didBase64: new Buffer(did).toString('base64') });
return resp.didDocumentWithSeq ?? null;
} catch (error) {
if (rpcErrMsgNotFound.test(error)) {
Expand All @@ -107,7 +108,7 @@ export class PanaceaClient extends StargateClient {
async getToken(symbol: string): Promise<Token | null> {
const queryService = new TokenQueryClientImpl(createProtobufRpcClient(this.forceGetQueryClient()));
try {
const resp = await queryService.Token({symbol: symbol});
const resp = await queryService.Token({ symbol: symbol });
return resp.token ?? null;
} catch (error) {
if (rpcErrMsgNotFound.test(error)) {
Expand All @@ -119,6 +120,6 @@ export class PanaceaClient extends StargateClient {

async getTokens(pageRequest?: PageRequest): Promise<QueryTokensResponse> {
const queryService = new TokenQueryClientImpl(createProtobufRpcClient(this.forceGetQueryClient()));
return await queryService.Tokens({pagination: pageRequest});
return await queryService.Tokens({ pagination: pageRequest });
}
}
Loading