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

RFC: monorepo jellyfish development #29

Closed
wants to merge 1 commit into from
Closed

Conversation

fuxingloh
Copy link
Contributor

@fuxingloh fuxingloh commented Mar 2, 2021

A collection of JavaScript tools and libraries for DeFiChain to build decentralized finance on Bitcoin.

This is an early 1st milestone RFC to tackle DeFiChain JS Library Protocol Implementation/Interfacing technical design. There will be 4 milestones in total (protocols, wallet, remote & documentation) and this being the biggest unit of work due to the mono repo and utility and toolchain setup.

The purpose of this RFC is to provide a feedback loop before new features or significant change/implementation get introduced to the DeFiChain ecosystem. Extra attention is required for this as this repo is meant to be used by the masses. As this is an RFC, NOT A CODE REVIEW, some codes are missing and this is not to be merged.

For the reviewer, the question is 'does this make sense for the JS ecosystem' & 'is this easy to use'?

Jellyfish Monorepo

All to be npm published. As jellyfish is all JavaScript related, this mono repo represent a collection of JavaScript tools and libraries for DeFiChain to build decentralized finance on Bitcoin. We can expect more to be added in the future.

  • @defichain/jellyfish
  • @defichain/jellyfish-core
  • @defichain/jellyfish-jsonrpc
  • @defichain/jellyfish-wallet (next milestone, by Q1 🤞)
  • @defichain/testcontainers

@defichain/testcontainers

Similar to testcontainers in the Java ecosystem, this library provide a lightweight, throwaway instances of regtest, testnet or mainnet provisioned automatically in Docker container. @defichain/testcontainers encapsulate on top of defi/defichain:latest and directly interface with the Docker REST API. see #20

With @defichain/testcontainers, it allows the JS ecosystem to:

  1. E2E application integration test without hassle
  2. Parallel unit test runner as port number and container are dynamically generated on demand
  3. Supercharge CI/CD workflow, run locally, run anyway, run on CI
  4. Supercharge jellyfish-core development with integration test guarantees
  5. Easy for any developer to test dApp on the DeFiChain JS ecosystem

Usage Example

import {MainNetDocker, RegTestDocker, TestNetDocker} from '@defichain/testcontainers'

describe('reg test', () => {
  const node = new RegTestDocker()

  beforeEach(async () => {
    await node.start({
      user: 'foo',
      password: 'bar',
    })
    await node.ready()
  })

  afterEach(async () => {
    await node.stop()
  })

  it('should getmintinginfo and chain should be regtest', async () => {
    const client = Jellyfish.jsonrpc(await node.getRpcUrl())
    const result = await client.call('getmintinginfo', [])
    expect(result.result.chain).toBe('regtest')
  })
})

@defichain/jellyfish-core

@defichain/jellyfish-core the protocol agnostic DeFiChain client implementation with APIs separated into their category.

Implementation Details

client.'category'.'method'() example

Client APIs are implemented categorically as follows:

category method JS CCP
mining getmintinginfo client.mining.getMintingInfo() rpc/mining.cpp#getmintinginfo
rawtransaction sendrawtransaction client.transaction.sendRawTransaction(tx) rpc/sendrawtransaction.cpp#sendrawtransaction

The client:

https://github.com/DeFiCh/jellyfish/blob/36d11134b74e9285ae36229fdaa3f33876bf3cee/packages/jellyfish-core/src/core.ts#L8-L12

The protocol interfacing, with strongly typed interfaces:

https://github.com/DeFiCh/jellyfish/blob/36d11134b74e9285ae36229fdaa3f33876bf3cee/packages/jellyfish-core/src/methods/mining.ts#L3-L23

This allow library consumer to use it as follow:

const result = await client.blockchain.getBestBlockHash()
// or
client.blockchain.getBestBlockHash()
  .then((result) => {
    console.log(result)
  }).catch((err)=> {
    console.log('panic!')
  }).finally(() => {
    console.log('cleanup')  
  })

@defichain/jellyfish-jsonrpc

Nothing really special about this package, it just imlements @defichain/jellyfish-core in the JSON-RPC 1.0 specification. 2 dependencies with 4 deeply are selected, jsonbig as JS number is implemented with IEEE-754, defi must not use floating point arithmetic for obvious reason (need to write TDD to guarantee this behavior) see #18. cross-fetch a isomorphic fetch client that is RN, Node.JS and browser compatible. See #17

https://github.com/DeFiCh/jellyfish/blob/36d11134b74e9285ae36229fdaa3f33876bf3cee/packages/jellyfish-jsonrpc/src/jsonrpc.ts#L1-L3

https://github.com/DeFiCh/jellyfish/blob/36d11134b74e9285ae36229fdaa3f33876bf3cee/packages/jellyfish-jsonrpc/src/jsonrpc.ts#L21-L29

@defichain/jellyfish

This is the entrypoint for most dApp developer. Distributed as @defichain/jellyfish, it is a bundler that creates 4 types of JavaScript packages for public use. This package provides conventional defaults and bundle all code required for dApps building. For library consumer, it is plug and play, they don't need to care how it works underneath.

1. dist/jellyfish.cjs.js for node.js

Common JS for Node.JS users, plug and play no transpiler required.

const express = require('express')
const Jellyfish = require('@defichain/jellyfish')

const app = express()
const client = Jellyfish.jsonrpc('http://?.defichain.com')

app.get('/', (req, res) => {
  client.mining.getMintingInfo().then((info) => {
    res.send(JSON.stringify(info))
  })
})

app.listen(3000)

2. dist/jellyfish.umd.js for browser

For the global CDN users, this allows developer to just declare jellyfish.js script and use it on any webpage.

  1. ReactJS Global Mode
  2. VueJS Global Mode
  3. WordPress websites
  4. The plain old HTML & JavaScript

All library code that are required for jellyfish to work on their browser are automatically bundled into the fat javascript file. (20 KB+) This included bignumber, JSONBig, jellyfish-jsonrpc and in the future all other jellyfish tools e.g. jellyfish-wallet. The bundler is set to polyfill on >0.25% of all browser and target node 12 and above implementation.

<script src="https://unpkg.com/@defichain/jellyfish@latest/dist/jellyfish.umd.js"/>
<script lang="js">
  var client = Jellyfish.jsonrpc('http://?.defichain.com')
  client.mining.getMintingInfo().then(info => {
    console.log(info)
  })
</script>

3. dist/jellyfish.esm.js for ES module

For webpack, parcel, and variety of users that want to use their own bundler (tree shaking), ES modules packages are also provided.

import * as jf from '@defichain/jellyfish'

const client = jf.jsonrpc('http://?.defichain.com')

4. dist/jellyfish.d.ts for TS types

TypeScript's types are also exported for convenience’s sake, removes the need for @types/jellyfish.

import {Jellyfish, JellyfishClient} from '@defichain/jellyfish'

const client: JellyfishClient = Jellyfish.jsonrpc('http://?.defichain.com')

Next?

If all is approved this implementation style will be internally frozen and slowly patched into main.

@defichain-bot defichain-bot added the needs/kind Needs kind label label Mar 2, 2021
@defichain-bot

This comment has been minimized.

@fuxingloh fuxingloh changed the title RFC: monorepo development rfc RFC: monorepo jellyfish development Mar 2, 2021
@fuxingloh fuxingloh marked this pull request as ready for review March 2, 2021 05:23
Copy link

@uzyn uzyn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love the overall structure on the planning.

* @param url
*/
jsonrpc(url: string): JellyfishJsonRpc {
return new JellyfishJsonRpc(url)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would call it new Jellyfish() if it makes sense so it's clean when it's used externally.

new Jellyfish(url, {
    useNodeWallet: false, // default to false
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely will pay more attention to this, I rewrote that part a few times.

packages/jellyfish-core/src/methods/mining.ts Show resolved Hide resolved
@fuxingloh
Copy link
Contributor Author

Thanks for taking part in this RFC, the implementation style will be locked and slowly patched into main.

Things under consideration are:

  1. structuring of interfaces readability vs reusability
  2. constructing of Jellyfish client

@fuxingloh fuxingloh closed this Mar 4, 2021
@BirthdayResearch BirthdayResearch locked and limited conversation to collaborators Mar 4, 2021
@fuxingloh fuxingloh deleted the rfc-protocol branch March 11, 2021 03:11
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
needs/kind Needs kind label
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants