diff --git a/README.md b/README.md index 3093c8c..f537e50 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # panacea-js -Official client-side JavaScript library for the [medibloc blockchain](https://github.com/medibloc/panacea-core). +Official client-side JavaScript library for the [medibloc blockchain](https://github.com/medibloc/panacea-core) (Stargate-compatible). ## Install diff --git a/package.json b/package.json index 6c02c04..f6cc2b4 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,10 @@ }, "homepage": "https://medibloc.org", "dependencies": { + "@cosmjs/crypto": "^0.25.4", + "@cosmjs/proto-signing": "^0.25.4", + "@cosmjs/stargate": "^0.25.4", + "@cosmjs/tendermint-rpc": "^0.25.4", "@medibloc/amino-js": "^1.2.0", "axios": "^0.21.1", "bech32": "^1.1.4", @@ -66,6 +70,7 @@ "eslint": "^7.9.0", "jest": "^26.4.2", "ts-jest": "^26.3.0", + "ts-proto": "^1.81.3", "typescript": "^4.0.2" } } diff --git a/protocgen.sh b/protocgen.sh new file mode 100755 index 0000000..ed1a6a8 --- /dev/null +++ b/protocgen.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +#set -eo pipefail +set -euxo pipefail + +SRC_PATH="third_party/proto" +DST_PATH="src/proto" + +# Fetch 3rd-party proto files +protodep up -u + +# Compile only Panacea proto files +mkdir -p ${DST_PATH} +protoc \ + --plugin=./node_modules/.bin/protoc-gen-ts_proto \ + --ts_proto_out="${DST_PATH}" \ + --proto_path="${SRC_PATH}" \ + --ts_proto_opt="esModuleInterop=true,forceLong=long,useOptional=true" \ + ${SRC_PATH}/panacea/**/*.proto diff --git a/test/index.ts b/test/index.ts new file mode 100644 index 0000000..c7539e3 --- /dev/null +++ b/test/index.ts @@ -0,0 +1,112 @@ +import { stringToPath } from "@cosmjs/crypto"; +import { DirectSecp256k1HdWallet, GeneratedType, Registry } from "@cosmjs/proto-signing"; +import { + assertIsBroadcastTxSuccess, + createProtobufRpcClient, + defaultRegistryTypes, + QueryClient, + SigningStargateClient +} from '@cosmjs/stargate'; +import { MsgCreateTopic } from '../src/pb/aol/tx'; +import { Tendermint34Client } from '@cosmjs/tendermint-rpc'; +import { QueryClientImpl } from '../src/pb/aol/query'; + +const rpcEndpoint = "http://localhost:26657" +const mnemonic = "bless front exercise burst solid venture vapor asthma clean table recall affair decrease hollow fabric voice display grid slim bag kingdom hole junior polar"; +const walletOpts = { + hdPaths: [stringToPath("m/44'/371'/0'/0/0")], + prefix: "panacea", +} + +describe('yo', () => { + it('it1', async () => { + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, walletOpts); + const [firstAccount] = await wallet.getAccounts(); + + const client = await SigningStargateClient.connectWithSigner(rpcEndpoint, wallet); + + const msg = { + typeUrl: "/cosmos.bank.v1beta1.MsgSend", + value: { + fromAddress: firstAccount.address, + toAddress: "panacea1trm407dm66g6mccm4k080e3mh3frcqqy743a74", + amount: [{ + denom: "umed", + amount: "100", + }], + }, + }; + + const fees = { + amount: [ + { + denom: "umed", + amount: "1000000", + }, + ], + gas: "100000", + }; + + const result = await client.signAndBroadcast(firstAccount.address, [msg], fees, "this is a memo"); + assertIsBroadcastTxSuccess(result); + + const coins = await client.getAllBalances(firstAccount.address); + console.log(coins); + }); + + it('custom module', async () => { + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, walletOpts); + const [firstAccount] = await wallet.getAccounts(); + + const a: [string, GeneratedType] = ["/medibloc.panaceacore.aol.MsgCreateTopic", MsgCreateTopic]; + const i: Iterable<[string, GeneratedType]> = [...defaultRegistryTypes, a]; + const myRegistry = new Registry(i); + + + const client = await SigningStargateClient.connectWithSigner(rpcEndpoint, wallet, { registry: myRegistry }); + + const msg = { + typeUrl: "/medibloc.panaceacore.aol.MsgCreateTopic", + value: { + topicName: "topic1", + description: "this is a description", + ownerAddress: firstAccount.address, + }, + }; + + const fees = { + amount: [ + { + denom: "umed", + amount: "1000000", + }, + ], + gas: "100000", + }; + + const result = await client.signAndBroadcast(firstAccount.address, [msg], fees, "this is a memo"); + assertIsBroadcastTxSuccess(result); + }); + + it('custom module - query', async () => { + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, walletOpts); + const [firstAccount] = await wallet.getAccounts(); + + // Tendermint34Client knows how to talk to the Tendermint RPC endpoint + const tmClient = await Tendermint34Client.connect(rpcEndpoint); + // The generic Stargate query client knows how to use the Tendermint34Client to submit unverified ABCI queries + const queryClient = new QueryClient(tmClient); + // This helper function wraps the generic Stargate query client for use by the specific generated query client. + const rpcClient = createProtobufRpcClient(queryClient); + + // Here we instantiate a specific query client which will have the custom methods defined in the proto file. + const queryService = new QueryClientImpl(rpcClient); + + const result = await queryService.Topic({ + ownerAddress: firstAccount.address, + topicName: "topic1", + }); + + console.log(result); + }); +}); diff --git a/tsconfig.json b/tsconfig.json index 0cf7a4d..b7bb49d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -22,7 +22,7 @@ "removeComments": true, /* Do not emit comments to output. */ // "noEmit": true, /* Do not emit outputs. */ // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ /* Strict Type-Checking Options */