Skip to content

Commit

Permalink
fix jellyfish-json path based bignumber remapping (#128)
Browse files Browse the repository at this point in the history
* added path based PrecisionMapping
* apply & refactor jellyfish-json consumers
  • Loading branch information
fuxingloh authored Apr 16, 2021
1 parent ac7d29c commit db5a0b9
Show file tree
Hide file tree
Showing 10 changed files with 297 additions and 328 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,5 @@ node_modules
# dist & pack
dist
*.tgz

coverage
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { JellyfishJSON, ApiClient, Precision, RpcApiError } from '../src'
import { ApiClient, RpcApiError } from '../src'
import { DeFiDContainer } from '@defichain/testcontainers'
import { JellyfishJSON, Precision, PrecisionPath } from '@defichain/jellyfish-json'

/**
* Jellyfish client adapter for container
Expand All @@ -16,7 +17,7 @@ export class ContainerAdapterClient extends ApiClient {
/**
* Wrap the call from client to testcontainers.
*/
async call<T> (method: string, params: any[], precision: Precision): Promise<T> {
async call<T> (method: string, params: any[], precision: Precision | PrecisionPath): Promise<T> {
const body = JellyfishJSON.stringify({
jsonrpc: '1.0',
id: Math.floor(Math.random() * 100000000000000),
Expand All @@ -25,9 +26,9 @@ export class ContainerAdapterClient extends ApiClient {
})

const text = await this.container.post(body)
const response = JellyfishJSON.parse(text, precision)

const { result, error } = response
const { result, error } = JellyfishJSON.parse(text, {
result: precision
})

if (error !== undefined && error !== null) {
throw new RpcApiError(error)
Expand Down
6 changes: 5 additions & 1 deletion packages/jellyfish-api-core/src/category/blockchain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,11 @@ export class Blockchain {
* @return Promise<UTXODetails>
*/
async getTxOut (txId: string, index: number, includeMempool = true): Promise<UTXODetails> {
return await this.client.call('gettxout', [txId, index, includeMempool], { value: 'bignumber' })
return await this.client.call('gettxout', [
txId, index, includeMempool
], {
value: 'bignumber'
})
}
}

Expand Down
13 changes: 8 additions & 5 deletions packages/jellyfish-api-core/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Precision, PrecisionMapping } from '@defichain/jellyfish-json'
import { Precision, PrecisionPath } from '@defichain/jellyfish-json'
import { Blockchain } from './category/blockchain'
import { Mining } from './category/mining'
import { Wallet } from './category/wallet'
Expand All @@ -19,9 +19,9 @@ export abstract class ApiClient {
/**
* A promise based procedure call handling
*
* @param method Name of the RPC method
* @param params Array of params as RPC payload
* @param precision
* @param {string} method name of the RPC method
* @param {any[]} params array of params as RPC payload
* @param {Precision | PrecisionPath} precision
* Numeric precision to parse RPC payload as 'lossless', 'bignumber' or 'number'.
*
* 'lossless' uses LosslessJSON that parses numeric values as LosslessNumber. With LosslessNumber, one can perform
Expand All @@ -31,11 +31,14 @@ export abstract class ApiClient {
*
* 'number' parse all numeric values as 'Number' and precision will be loss if it exceeds IEEE-754 standard.
*
* 'PrecisionPath' path based precision mapping, specifying 'bignumber' will automatically map all Number in that
* path as 'bignumber'. Otherwise, it will default to number, This applies deeply.
*
* @throws ApiError
* @throws RpcApiError
* @throws ClientApiError
*/
abstract call<T> (method: string, params: any[], precision: Precision | PrecisionMapping): Promise<T>
abstract call<T> (method: string, params: any[], precision: Precision | PrecisionPath): Promise<T>
}

/**
Expand Down
9 changes: 6 additions & 3 deletions packages/jellyfish-api-jsonrpc/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
import fetch from 'cross-fetch'
import { Response } from 'cross-fetch/lib.fetch'
import AbortController from 'abort-controller'
import { PrecisionPath } from '@defichain/jellyfish-json'

/**
* ClientOptions for JsonRpc
Expand Down Expand Up @@ -58,7 +59,7 @@ export class JsonRpcClient extends ApiClient {
/**
* Implements JSON-RPC 1.0 specification for ApiClient
*/
async call<T> (method: string, params: any[], precision: Precision): Promise<T> {
async call<T> (method: string, params: any[], precision: Precision | PrecisionPath): Promise<T> {
const body = JsonRpcClient.stringify(method, params)
const response = await this.fetchTimeout(body)
const text = await response.text()
Expand All @@ -83,8 +84,10 @@ export class JsonRpcClient extends ApiClient {
})
}

private static parse (text: string, precision: Precision): any {
const { result, error } = JellyfishJSON.parse(text, precision)
private static parse (text: string, precision: Precision | PrecisionPath): any {
const { result, error } = JellyfishJSON.parse(text, {
result: precision
})

if (error !== undefined && error !== null) {
throw new RpcApiError(error)
Expand Down
12 changes: 12 additions & 0 deletions packages/jellyfish-json/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,15 @@ describe('stringify', () => {
expect(string).toBe('{"bignumber":1200000000.00000001}')
})
})

it('should remap object at root with precision', () => {
const parsed = JellyfishJSON.parse(`{
"big": 10.4,
"num": 1234
}`, {
big: 'bignumber'
})

expect(parsed.big instanceof BigNumber).toBe(true)
expect(parsed.num).toBe(1234)
})
Loading

0 comments on commit db5a0b9

Please sign in to comment.