Giter Club home page Giter Club logo

cosmjs's Introduction

CosmJS

CosmJS is the Swiss Army knife to power JavaScript based client solutions ranging from Web apps/explorers over browser extensions to server-side clients like faucets/scrapers in the Cosmos ecosystem.

"Cosm" is short for Cosmos and "JS" is short for runs everywhere โ€“ we actually develop in TypeScript.

Documentation

Here is a list of examples using the Stargate package for use with Cosmos SDK 0.41 applications (like gaia 4). Take a look at the wiki page, "What can CosmJS do for me?" and various tests (ex) for more example usage of the packages.

API documentation

The full API documentation is hosted at cosmos.github.io/cosmjs. This is a bit tricky to navigate and requires basic TypeScript understanding. It is helpful if you want to look up details for advanced use cases. This documentation is auto-generated based on the current main branch and can occasionally diverge from the latest release.

Using custom Stargate modules

Documentation on how to use your own custom modules with CosmJS for Stargate chains (Cosmos SDK v0.41) can be found here.

Packages

CosmJS is a library that consists of many smaller npm packages within the @cosmjs namespace, a so-called monorepo. Here are some of them to get an idea:

Package Description Latest
@cosmjs/stargate A client library for the Cosmos SDK 0.40+ (Stargate) npm version
@cosmjs/faucet A faucet application for node.js npm version
@cosmjs/cosmwasm-stargate Client for Stargate chains with the CosmWasm module enabled npm version
@cosmjs/crypto Cryptography for blockchain projects, e.g. hashing (SHA-2, Keccak256, Ripemd160), signing (secp256k1, ed25519), HD key derivation (BIP-39, SLIP-0010), KDFs and symmetric encryption for key storage (PBKDF2, Argon2, XChaCha20Poly1305) npm version
@cosmjs/encoding Encoding helpers for blockchain projects npm version
@cosmjs/math Safe integers; decimals for handling financial amounts npm version

Modularity

We're pretty proud of the modularity and a clean dependency tree in this monorepo. This ensures software quality on our side and lets users pick exactly what they need. Here you see how everything fits together (every item is a npm package; right depends on left):

CosmJS dependency tree

If this was not enough to scare you away, check out the version including app runtime dependencies: cosmjs-tree-full.png.

Supported JS environments

Currently the codebase supports the following runtime environments:

  1. Node.js 14+
  2. Modern browsers (Chromium/Firefox/Safari, no Internet Explorer or Edge Spartan)
  3. Browser extensions (Chromium/Firefox)

Our current JavaScript target standard is ES2020. We use WebAssembly to implement certain cryptographic functions.

We're happy to adjust this list according to users' needs as long as you don't ask for Internet Explorer support. If your environment does not support Wasm, we can work on a solution with swappable implementations.

Webpack Configs

With WebPack 5, you have to be explicit about the usage of Node.js types and modules that were simply replaced with re-implementations for browsers in Webpack 4.

Configs for 0.28 and later:

module.exports = [
  {
    // ...
    plugins: [
      ...,
      new webpack.ProvidePlugin({
        Buffer: ["buffer", "Buffer"],
      }),
    ],
    // ...
    resolve: {
      fallback: {
        buffer: false,
        crypto: false,
        events: false,
        path: false,
        stream: false,
        string_decoder: false,
      },
    },
  },
];

Configs for CosmJS < 0.28

module.exports = [
  {
    // ...
    plugins: [
      ...,
      new webpack.ProvidePlugin({
        Buffer: ["buffer", "Buffer"],
      }),
    ],
    // ...
    resolve: {
      fallback: {
        buffer: false,
        crypto: false,
        events: false,
        path: false,
        stream: require.resolve("stream-browserify"),
        string_decoder: false,
      },
    },
  },
];

Roadmap

We maintain a development board, use release milestones and share important updates in the CosmWasm Community Call. For higher level roadmap discussion please reach out to the team.

Known limitations

0.26

  1. When connecting to a Cosmos SDK 0.44+ backend, the verified queries from AuthExtension and BankExtension as well as StargateClient.getAccountVerified will fail because the storage keys are not stable. Unverified queries can be used instead. Those queries are deprecated now and will be removed in 0.27 (#910).

0.25

  1. Decoding blocks of height 1 is unsupported. This is fixed in #815 and will be released as part of CosmJS 0.26.

0.24

  1. AuthExtension and all higher level Stargate clients only support BaseAccounts for all functionality, including getting account numbers and sequences for transaction signing. This will be implemented for all common Cosmos SDK account types in the 0.25 series.

Get in touch

The CosmJS development team is happy to get in touch with you for all questions and suggestions.

Development

See HACKING.md.

cosmjs's People

Contributors

abefernan avatar alpe avatar arnabghose997 avatar assafmo avatar bartmacbartek avatar blorgon1 avatar calvinkei avatar clockworkgr avatar davidesegullo avatar dependabot[bot] avatar ethanfrey avatar giansalex avatar hleb-albau avatar hyperbolic-versor avatar jakehartnell avatar janfabian avatar loin3 avatar madrezaz avatar merge-when-green[bot] avatar mergify[bot] avatar msteiner96 avatar mvid avatar noahsaso avatar pynixwang avatar riccardom avatar shanev avatar tien avatar vilsbole avatar webmaster128 avatar willclarktech avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cosmjs's Issues

Convert postTx error to structured error

We have this code (2x) and in tests extract data from the error string via string matsching. The values should be available in a structured error type. The error message can remain the same.

    if (result.code) {
      throw new Error(
        `Error when posting tx ${result.txhash} at height ${result.height}. Code: ${result.code}; Raw log: ${result.raw_log}`,
      );
    }

Give up strictly typed address prefix

type CosmosAddressBech32Prefix = "cosmos" | "cosmosvalcons" | "cosmosvaloper" is already annoying when reading prefix from config and not future-proof when it comes to custom prefixes.

Reconsider docker deployment

The original faucet from IOV used Docker for deployment and was never pushed to npm. With this monorepo, we get npm deployment for free because we use the same process for all packages. Now we have a good amount of duplication in the build process (for npm and for docker).

I wonder of we should instead

  1. Install the faucet build from npm inside the Docker. This would require an external Dockerfile, since the code is not yet uploaded to npm when we create a version tag.
  2. Don't support Docker at all and instead document how to install and run via npm (like it was done with @iov/cli). Whoever wants to containerize it can do so with a few simple commands.

Add support for subscriptions

We should expose some sort of subscription listener to the RestClient and use it in the CosmWasmConnection. In particular, for full bcp-compatibility, we need to implement:

  • watchBlockHeaders
  • watchAccount

And postTx could be done nicer with a subscription that with a poll.

I believe these are needed for dropping in CosmWasmConnection into the iov-wallet

Fix order of transaction in SearchBySentFromOrToQuery

In CosmWasmClient.searchTx with SearchBySentFromOrToQuery, we get all sent results first and then all received results. The list should be sorted.

Iderally this is implemented with an deduplicating insertion algorithm in pre-sorted sources.

Extract @comsmwasm/sdk

I think we should have a package @comsmwasm/sdk that serves as an implementation for @cosmwasm/bcp as follows:

out

This package should expose chain-specific functionality in the simplest interface possible, without being restricted by the requirements of BCP.

Add x/wasm queries

We expose a number of custom queries in x/wasmd.

We should add methods to CosmosConnection to make these queries. This will also allow us to check the state from #8 easier. Simple Promise queries (not subscriptions) is fine for the first iteration. Good to investigate what would be needed for "watching" state, to make issues on wasmd as needed

Update: add queries to RestClient in sdk, not to CosmWasmConnection in bcp

Replace static sleep with polling betwen wasmd and rest server start

The

sleep 10

if [ "$(docker inspect -f '{{.State.Running}}' "$CONTAINER_NAME")" != "true" ]; then
  echo "Container named '$CONTAINER_NAME' not running. We cannot continue." \
    "This can happen when 'docker run' needs too long to download and start." \
    "It might be worth retrying this step once the image is in the local docker cache."
  docker kill "$CONTAINER_NAME"
  exit 1
fi

can be changed to a timeout call (something like timeout 60 bash -c "until curl -s http://localhost:1317/node_info > /dev/null; do sleep 1; done") to make the rest server start faster on average and to make the script more resilient to slow envirinments.

Remove BCP functionality from here

The package @cosmwasm/bcp was a successful experiment to show token contracts in a multichain wallet. There is no intend to add this functionality into a BCP based wallet like Neuma in production quality. In order to simplify our codebase, we plan the following steps:

  • Refactor @cosmwasm/faucet to work with @cosmwasm/sdk directly and remove the dependency on @cosmwasm/bcp. This implies the removal of smart contract token support from the faucet. It is simplifies to just support bank tokens, which is most important for fees.
  • Remove CosmWasm specifics (ERC20 smart contract token support) from @cosmwasm/bcp
  • Hand over @cosmwasm/bcp to IOV Core (under which target name?)

Mid-term additions

  • Split @cosmwasm/sdk into Cosmos SDK and CosmWasm functionality, such that CosmWasm becomes optional (#182)

@davepuchyr Number 2. and 3. is service work for IOV to express our gratitude for being able to build on top of IOV Core and maintain healty code for everyone in the ecosystem. Please folllow this ticket closely and chip in if I get something wrong.

Properly sign tx

This follows on #6 which will make it easier to debug.

Currently, posting a sendtx fails due to invalid chain-id or nonce (invalid signature). I need to investigate, but a quick look showed we use one Nonce, where cosmos-sdk has 2 uint64 - one is the account number (fixed per account), other is the sequence (per account, increments per tx).

If we need to keep Nonce = Long, we can encode account number in the top 32 bits, and sequence in the lower 32 bits. This is somewhat incorrect, but will work until 4 billion accounts are created or 4 billion tx from one account. That should at least buy us some time to refactor until that happens.

Fix exception "Unsigned integer r must be encoded as unpadded big endian."

In

  const { pubkey, signature } = decodeSignature(firstSignature);
  const secp256keSignature = new Secp256k1Signature(signature.slice(0, 32), signature.slice(32, 64));

the Secp256k1Signature constructor throws "Unsigned integer r must be encoded as unpadded big endian." when r (or s) is padded, i.e. the integer is smaller than 32 bytes but a fixed-length encoding is given.

Test staking contract full stack

We now have a stable v0.8.0-alpha3 release and integration tests for the staking contract in wasmd.

To fully demo this, we need some very high level tests via cosmwasm-js showing the contract in use. It only needs to cover a happy path, but mainly showing client interaction down to the contract working.

Support multiple init files

If I have some generic setup code (helpers) and some contract-specific code (see #148) it would be nice to import both of them without merging the source files. This could be done if we support multiple instances of --init in packages/cli/src/cli.ts

export function main(originalArgs: readonly string[]): void {
  const parser = new ArgumentParser({ description: "The CosmWasm REPL" });
  parser.addArgument("--version", {
    action: "storeTrue",
    help: "Print version and exit",
  });
  parser.addArgument("--init", {
    metavar: "FILEPATH",
    help: "Read initial TypeScript code from file",
  });
  // ...
    if (args.init) {
    init += fs.readFileSync(args.init, "utf8") + "\n";
  }

Integrate util, encoding, and crypto package

After BCP is moved out, we have 3 @iov/* dependencies left: util, encoding, and crypto. Those should be included here to swap the dependency (IOV Core depends on Cosm JS).

util and crypto can be unchanged. encoding should be split:

  • @cosmjs/encoding: fromAscii, fromBase64, fromHex, fromUtf8, toAscii, toBase64, toHex, toUtf8, Bech32, fromRfc3339, toRfc3339
  • @cosmjs/math: Decimal, Int53, Uint32, Uint53, Uint64,
  • @cosmjs/util: isUint8Array, isNonNullObject
  • not copied: TransactionEncoder, JsonCompatible*, isJsonCompatible*

Let faucet and cosmwasm packages use different accounts

Starting with #184, faucet does not depend on cosmwasm anymore. As a consequence, lerna runs their tests in parallel. Unfortunately we need to block that in order to avoid sequence issues which occur because both packages use the same test account / mnemonic.

We should have a default test account, let's say alice with a handful of addresses and the faucet that is really made for the faucet. Then we can use alice my default as the test user.

Set up CI

Ideally would be circleci (as that is used for the other repos).
If that is too hard, we can use travis (which is used in iov-core, so easy to port).

CI should build/lint/test the code. Both unit tests and integration tests against a locally running chain scripts/cosm/start.sh

Note, that some tests currently fail on master. This will be more useful once we get to green (please xit those tests if they are still broken when starting on this task)

Clarify license

This code is originally from @iov/cosmos at https://github.com/iov-one/iov-core under Apache license from IOV. We made quite a few modifications. I would like to keep it under Apache LICENSE, but I think just keeping IOV as only name is not right. Just replacing them in the notice is also not right. What is the proper way to express this?

From stack exchange: https://stackoverflow.com/questions/7569978/forking-an-apache-license-v2-open-source-project-and-copyright-notices

An article that explains the importance of the NOTICE file: https://www.osehra.org/wiki/how-apply-apache-20-license-your-software-project

In the simplest scenario, there will be a single individual or a single organization, who holds the copyright of the entire body of code, and who choses to license the full body of code under a single license.

In a more typical scenario, there might be multiple copyright holders, who hold rights to different portions of the code, and who may have chosen to distribute those different portions of the code under different, but compatible, licenses. This scenario can rapidly become confusing, and it is the role of the NOTICE file to clarify the situation of who contribute what, and under what license it is being distributed.

Although I guess just reading section 4 from the license text itself a few times is probably the best answer

Auto-calculate TokenInfo

One of the biggest config issues is the array of TokenInfo needed to properly handle the chain in CosmWasmConnection. We can query supply for a list of all denoms on the chain. Then auto-generate TokenInfo as follows:

  • if denom starts with "u": ticker = drop "u", convert to uppercase, fractionalDigits = 6
  • else: ticker = convert to uppercase, fractionalDigits = 0

We can allow a TickerInfo override that will replace any auto-generated info, but this means for many test chains, we can get away without any config here, and make life easier when integrating.

Throw error on failed tx

Two integration tests on current master hang. The tx fails on checktx (bad sig) and returns an error message (top of CosmosConnection.postTx). Make sure this throws the proper error when a non-zero code is received. This will make the currently hanging tests (waiting for a success/failure deliver response) die early and easier to debug. Also makes any production code much more stable.

Extract common env from `scripts/cosm`

There are a few common values used between start, stop, cli, and generate_template. Let's pull them into a separate env file, and derive those that we can (like CONTAINER_NAME from REPOSITORY).

See #2 (review) for details

Log parsing too strict

Running through the new mask demo, I use an opaque message to trigger a staking action from the mask contract. In the end, cosmwasm-js throws an error parsing the logs. We should be less strict, either support more, silently ignore them, or just parse them without care for the type. In any case this should not be an error

>> .editor
// Entering editor mode (^D to finish, ^C to cancel)
const staking2 = {
  type: "cosmos-sdk/MsgDelegate",
  value: {
    delegator_address: mask,
    validator_address: "cosmosvaloper1e8gslcu2u2p5zp9rgj8alz4q3lt6hvywqppf23",
    amount: {
      denom: "ustake",
      amount: "300000"
    }
  }
};

undefined
>> const callOpaque2: HandleMsg = { reflectmsg: { msgs: [opaqueMsg(staking2)]}};
undefined
>> client.execute(mask, callOpaque2)
Thrown:
Error: Event type must be one of message, transfer, wasm; got delegate
    at process._tickCallback (internal/process/next_tick.js:68:7)
    at SigningCosmWasmClient.postTx (/home/ethan/js/cosmwasm-js/packages/sdk/src/cosmwasmclient.ts:312:27)
    at Object.parseLogs (/home/ethan/js/cosmwasm-js/packages/sdk/src/logs.ts:71:16)
    at Array.map (<anonymous>)
    at parseLog (/home/ethan/js/cosmwasm-js/packages/sdk/src/logs.ts:65:20)
    at Array.map (<anonymous>)
    at parseEvent (/home/ethan/js/cosmwasm-js/packages/sdk/src/logs.ts:47:11)

Adapt to wasmd 0.7

  • Upgrade local wasm image to 0.7.0
  • Adapt code (e.g. order of instances in describe("getContracts", () => {, required instance label)
  • Add address and labels to Contract interface
  • Create separate ContractDetails interface that contains initMsg and remove it from Contract

CosmWasmConnection.searchTx: don't query nonces

In contrast to getTx, we don't need signed transactions for searchTx:

export interface BlockchainConnection {
  // ...

  readonly getTx: (
    id: TransactionId,
  ) => Promise<ConfirmedAndSignedTransaction<UnsignedTransaction> | FailedTransaction>;

  // ...

  readonly searchTx: (
    query: TransactionQuery,
  ) => Promise<readonly (ConfirmedTransaction<UnsignedTransaction> | FailedTransaction)[]>;
}

This is on purpose to allow scraper backends for loading long lists while at the same time allowing the application to get all information for a single transaction on demand.

If we refactor the code a bit, we don't need to query const accountForHeight = await this.restClient.authAccounts(senderAddress, response.height); for every search result to get the nonce.

Remove globalFractionalDigits from faucet

This whole code is a hack:

// Load this from connection?
let globalFractionalDigits: number | undefined;

export function setFractionalDigits(input: number): void {
  globalFractionalDigits = input;
}

export function getFractionalDigits(): number {
  if (globalFractionalDigits === undefined) {
    throw new Error("Fractional digits not set");
  }
  return globalFractionalDigits;
}

We should have a ticker to digits function, which can easily be implemented in codec.ts, where the token configuration is available.

Add CLI bindings for contracts in cosmwasm-examples

This was inspired by the desire to make TS-CLI bindings for mask contract

It would be nice to have a CLI script for each one that would allow higher-level access (beyond helpers.ts). Have the proper types for the messages and the queries, and expose proper functions. Take in a Pen and SigningCosmWasmClient as args and do the rest.

  • Upload code (this is generic, can be left in helpers)
  • Instantiate code (with proper types)
  • Execute code (one per method)
  • Query (one per method)

Note: mask requires some double encoding (eg. the json message body for contract msg needs to be serialized, converted to bytes, and then base64-encoded). Making a helper here is a big advantage over doing it manually. Maybe for erc20 this doesn't make a big difference, but at least having the (auto-generated ๐Ÿ˜„ ) types defined here may make it easier for people ("how do I submit a transfer?")

Design best practices for reactive apps

Continuing a discussion from #99

@webmaster128 had concerns with the Stream interface we provide, both polling and websockets (with reconnect issues). These are important concerns as he has worked with said interface around a year at iov and has had many learnings.

That said, the entire design of "reactive frontend apps" is only getting bigger and bigger and I would like to work out some way to support that, even if it involved changes to a backend rpc server. Let us explore what other popular frameworks do and how they handle edge cases about breaking subscriptions, etc.

Some good examples:

Meteor

Apollo

I'd love to hear a deeper look into these protocols or other references. I don't think anyone has a perfect solution, but good to look how they tackle these problems (and maybe we can build on one?)

Add x/wasm tx types

There are three new tx types we should support from x/wasmd:

  • MsgStoreCode
  • MsgInstantiateContract
  • MsgExecuteContract

Let's add typescript definitions for them and support in postTx

Add bcp integration tests to CI

Currently we do not run a local chain, not test with COSMOS_ENABLED=1. This means we must still manually check for errors. (See #25)

We basically need this:

./scripts/cosm/start.sh
cd packages/bcp
COSMOS_ENABLED=1 yarn test
cd -
./scripts/cosm/stop.sh

Revisit examples for the CLI

I wanted to make some additions and realized helpers.ts is using RestClient and (almost) entirely superceded by CosmWasmClient. Let's give these an overhaul to the newest version.

Add missing fields for node info

Right now we only have the network ID in the type and tests. There is much more:

{
  node_info: {
    protocol_version: { p2p: '7', block: '10', app: '0' },
    id: '67289558533ad6df13f96bfb7c8ae44b457a919a',
    listen_addr: 'tcp://0.0.0.0:26656',
    network: 'testing',
    version: '0.33.0',
    channels: '4020212223303800',
    moniker: 'testing',
    other: { tx_index: 'on', rpc_address: 'tcp://0.0.0.0:26657' }
  },
  application_version: {
    name: 'wasm',
    server_name: 'wasmd',
    client_name: 'wasmcli',
    version: '0.6.0',
    commit: 'e1a2cc3337f785a9109e011570537502cdbd38e2',
    build_tags: 'netgo,ledger',
    go: 'go version go1.13.7 linux/amd64'
  }
}

I was looking for a node height, which is not available here. So this has no priority as far as I can see.

Improve compatibility between Pen and CosmWasmClient

Right now, CosmWasmClient does not care how transactions are signed. Any callback in the form (signBytes: Uint8Array): Promise<StdSignature> can do the job. This is any async interface to even allow user interaction (e.g. typing a password). This flexibility is nice when replacing Pen with a production-ready key manager.

The goal of this ticket is to replace the 4 lines

      const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic);
      const client = CosmWasmClient.makeWritable(httpUrl, faucet.address, async signBytes => {
        return encodeSecp256k1Signature(pen.pubkey, await pen.createSignature(signBytes));
      });

into two lines.

Since CosmWasmClient is supposed to be a production-ready class and Secp256k1Pen is just a dummy throw away signer, we probably should adapt the later to expose the required interface.

Remove dependency on amino-js

It uses hardcoded types, compiled from the go codebase of cosmos hub. This is currently 0.36, while wasmd is on 0.38 pre-release.

For json encoding/decoding we have no need of amino-js and can copy over the types they used (and adjust them as needed for 0.38). The only benefit we get from it is binary encoding, but if we talk to the rest server, I think there is no need - all my interactions with it have given me json - except for pubkeys and addresses in binary.

For interacting directly with tendermint we need a library, but word is they will be in protobuf in next 3-6 months, so I'd rather wait on that for an integration

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.