diff --git a/.eslintrc.js b/.eslintrc.js index 1887a948..84622bae 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -47,18 +47,7 @@ module.exports = { }], "max-len": [2, 120], "object-curly-newline": ["error", { - "ObjectExpression": { - "minProperties": 1, - "multiline": true - }, - "ObjectPattern": { - "consistent": true - }, - "ImportDeclaration": "never", - "ExportDeclaration": { - "multiline": true, - "minProperties": 3 - } + "consistent": true }] }, "globals": { diff --git a/CHANGELOG.md b/CHANGELOG.md index b0926d0a..4699c00e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,32 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [0.21.0](https://github.com/nervosnetwork/ckb-sdk-js/compare/v0.20.0...v0.21.0) (2019-09-21) + + +### Code Refactoring + +* **address** rename public key identifier to publicKeyHash ([b33c096](https://github.com/nervosnetwork/ckb-sdk-js/commit/b33c096)) + + +### Features + +* **rpc:** format the outputs of the params formatter ([740b403](https://github.com/nervosnetwork/ckb-sdk-js/commit/740b403)) +* **rpc:** update the interface of getLiveCell ([0280d7f](https://github.com/nervosnetwork/ckb-sdk-js/commit/0280d7f)) +* **utils:** format the outputs of the utils module ([a30071c](https://github.com/nervosnetwork/ckb-sdk-js/commit/a30071c)) + + +### BREAKING CHANGES + +* **rpc:** update the interface of getLiveCell +* **address** rename public key identifier to publicKeyHash +* **rpc:** hexilize the outputs of the params formatter +* **utils:** hexilize the outputs of the utils module + + + + + # [0.20.0](https://github.com/nervosnetwork/ckb-sdk-js/compare/v0.19.1...v0.20.0) (2019-09-07) diff --git a/lerna.json b/lerna.json index c01dbaa9..0ea8f1f1 100644 --- a/lerna.json +++ b/lerna.json @@ -2,5 +2,5 @@ "packages": [ "packages/*" ], - "version": "0.20.0" + "version": "0.21.0" } diff --git a/packages/ckb-cli/CHANGELOG.md b/packages/ckb-cli/CHANGELOG.md index d9e71d1b..307f644c 100644 --- a/packages/ckb-cli/CHANGELOG.md +++ b/packages/ckb-cli/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [0.21.0](https://github.com/nervosnetwork/ckb-sdk-js/compare/v0.20.0...v0.21.0) (2019-09-21) + +**Note:** Version bump only for package @nervosnetwork/ckb-cli + + + + + # [0.20.0](https://github.com/nervosnetwork/ckb-sdk-js/compare/v0.19.1...v0.20.0) (2019-09-07) **Note:** Version bump only for package @nervosnetwork/ckb-cli diff --git a/packages/ckb-cli/package.json b/packages/ckb-cli/package.json index 30f50fa2..49de390f 100644 --- a/packages/ckb-cli/package.json +++ b/packages/ckb-cli/package.json @@ -1,6 +1,6 @@ { "name": "@nervosnetwork/ckb-cli", - "version": "0.20.0", + "version": "0.21.0", "description": "Command line package based on @nervosnetwork/ckb-sdk-core", "author": "Nervos ", "homepage": "https://github.com/nervosnetwork/ckb-sdk-js#readme", @@ -34,15 +34,15 @@ "url": "https://github.com/nervosnetwork/ckb-sdk-js/issues" }, "dependencies": { - "@nervosnetwork/ckb-sdk-core": "0.20.0", + "@nervosnetwork/ckb-sdk-core": "0.21.0", "blessed": "0.1.81", "blessed-contrib": "4.8.16", "commander": "2.20.0", - "inquirer": "6.2.1" + "inquirer": "6.5.2" }, "devDependencies": { "@types/blessed": "0.1.12", "@types/inquirer": "6.5.0" }, - "gitHead": "478433630dd40501f1f67dc259bf9d252c56fcd3" + "gitHead": "5a1aaff6006c91e45e8ba39ceb6ef7c2f870e6cd" } diff --git a/packages/ckb-sdk-address/CHANGELOG.md b/packages/ckb-sdk-address/CHANGELOG.md index 0130283f..b3d9bc3d 100644 --- a/packages/ckb-sdk-address/CHANGELOG.md +++ b/packages/ckb-sdk-address/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [0.21.0](https://github.com/nervosnetwork/ckb-sdk-js/compare/v0.20.0...v0.21.0) (2019-09-21) + + +### Code Refactoring + +* **address** rename public key identifier to publicKeyHash ([b33c096](https://github.com/nervosnetwork/ckb-sdk-js/commit/b33c096)) + + +### BREAKING CHANGES + +* **address** rename public key identifier to publicKeyHash + + + + + # [0.20.0](https://github.com/nervosnetwork/ckb-sdk-js/compare/v0.19.1...v0.20.0) (2019-09-07) **Note:** Version bump only for package @nervosnetwork/ckb-sdk-address diff --git a/packages/ckb-sdk-address/__tests__/ckb-sdk-address.test.js b/packages/ckb-sdk-address/__tests__/ckb-sdk-address.test.js deleted file mode 100644 index 4844a2a0..00000000 --- a/packages/ckb-sdk-address/__tests__/ckb-sdk-address.test.js +++ /dev/null @@ -1,59 +0,0 @@ -const Address = require('../lib').default - -describe('ckb-sdk-address', () => { - it('generate address with default configuration', () => { - const fixture = { - privateKey: 'e79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3', - address: 'ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83', - } - const address = new Address(fixture.privateKey) - expect(address.value).toBe(fixture.address) - }) - - it('generate address specified prefix', () => { - const fixture = { - privateKey: 'e79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3', - prefix: 'ckt', - address: 'ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83', - } - const address = new Address(fixture.privateKey, { - prefix: fixture.prefix, - }) - expect(address.value).toBe(fixture.address) - }) - - it('generate address specified type of 0x01', () => { - const fixture = { - privateKey: 'e79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3', - type: '0x01', - address: 'ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83', - } - const address = new Address(fixture.privateKey, { - type: fixture.type, - }) - expect(address.value).toBe(fixture.address) - }) - - it('generate address specified type 0x01 and code hash index of 0x00', () => { - const fixture = { - privateKey: 'e79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3', - type: '0x01', - codeHashIndex: '0x00', - address: 'ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83', - } - const address = new Address(fixture.privateKey, { - type: fixture.type, - codeHashIndex: fixture.codeHashIndex, - }) - expect(address.value).toBe(fixture.address) - }) - - it('generate identifier with default configuration', () => { - const fixture = { - privateKey: 'e79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e', - identifier: '2f663ae60e00153d223657c685a15604255b168b', - } - const address = new Address(fixture.privateKey) - expect(address.identifier).toBe(fixture.identifier) - }) -}) diff --git a/packages/ckb-sdk-address/__tests__/fixtures.json b/packages/ckb-sdk-address/__tests__/fixtures.json new file mode 100644 index 00000000..2cc2c727 --- /dev/null +++ b/packages/ckb-sdk-address/__tests__/fixtures.json @@ -0,0 +1,76 @@ +{ + "generateAddress": { + "with default configuration": { + "privateKey": "0xe79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3", + "expected": { + "publicKeyHash": "0x36c329ed630d6ce750712a477543672adab57f4c", + "address": "ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83" + } + }, + "with specified prefix": { + "privateKey": "0xe79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3", + "prefix": "ckt", + "expected": { + "publicKeyHash": "0x36c329ed630d6ce750712a477543672adab57f4c", + "address": "ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83" + } + }, + "with specified type of 0x01": { + "privateKey": "0xe79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3", + "type": "0x01", + "expected": { + "publicKeyHash": "0x36c329ed630d6ce750712a477543672adab57f4c", + "address": "ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83" + } + }, + "with specified type of 0x01 and code hash of 0x00": { + "privateKey": "0xe79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3", + "type": "0x01", + "codeHashIndex": "0x00", + "expected": { + "publicKeyHash": "0x36c329ed630d6ce750712a477543672adab57f4c", + "address": "ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83" + } + }, + "with private key in bytes format": { + "privateKey": [ + 231, + 159, + 50, + 7, + 234, + 73, + 128, + 183, + 254, + 215, + 153, + 86, + 213, + 147, + 66, + 73, + 206, + 172, + 71, + 81, + 164, + 250, + 224, + 26, + 15, + 124, + 74, + 150, + 136, + 75, + 196, + 227 + ], + "expected": { + "publicKeyHash": "0x36c329ed630d6ce750712a477543672adab57f4c", + "address": "ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83" + } + } + } +} diff --git a/packages/ckb-sdk-address/__tests__/index.test.js b/packages/ckb-sdk-address/__tests__/index.test.js new file mode 100644 index 00000000..2b5eaa79 --- /dev/null +++ b/packages/ckb-sdk-address/__tests__/index.test.js @@ -0,0 +1,22 @@ +const { default: Address } = require('../lib') +const { generateAddress: generateAddressFixtures } = require('./fixtures.json') + +describe('ckb-sdk-address', () => { + describe('generate address', () => { + const fixtureTable = Object.entries(generateAddressFixtures).map( + ([title, { privateKey, expected, exception, ...config }]) => [title, privateKey, config, expected, exception] + ) + + test.each(fixtureTable)('%s', (_title, privateKey, config, expected, exception) => { + const option = Object.keys(config).length ? config : undefined + if (undefined !== expected) { + const address = new Address(privateKey, option) + expect(address.publicKeyHash).toBe(expected.publicKeyHash) + expect(address.value).toBe(expected.address) + } + if (undefined !== exception) { + expect(() => new Address(privateKey, option)).toThrow(new Error(exception)) + } + }) + }) +}) diff --git a/packages/ckb-sdk-address/package.json b/packages/ckb-sdk-address/package.json index 5675824b..cbcd948d 100644 --- a/packages/ckb-sdk-address/package.json +++ b/packages/ckb-sdk-address/package.json @@ -1,6 +1,6 @@ { "name": "@nervosnetwork/ckb-sdk-address", - "version": "0.20.0", + "version": "0.21.0", "description": "Address module of @nervosnetwork/ckb-sdk-core", "keywords": [ "CKB", @@ -27,14 +27,14 @@ }, "scripts": { "tsc": "tsc", - "test": "echo \"Error: run tests from root\" && exit 1" + "test": "../../node_modules/.bin/jest" }, "bugs": { "url": "https://github.com/nervosnetwork/ckb-sdk-js/issues" }, "dependencies": { - "@nervosnetwork/ckb-sdk-utils": "0.20.0", - "@nervosnetwork/ckb-types": "0.20.0" + "@nervosnetwork/ckb-sdk-utils": "0.21.0", + "@nervosnetwork/ckb-types": "0.21.0" }, - "gitHead": "478433630dd40501f1f67dc259bf9d252c56fcd3" + "gitHead": "5a1aaff6006c91e45e8ba39ceb6ef7c2f870e6cd" } diff --git a/packages/ckb-sdk-address/src/index.ts b/packages/ckb-sdk-address/src/index.ts index 7a75544f..1081a1f3 100644 --- a/packages/ckb-sdk-address/src/index.ts +++ b/packages/ckb-sdk-address/src/index.ts @@ -2,12 +2,12 @@ import ECPair from '@nervosnetwork/ckb-sdk-utils/lib/ecpair' import * as utils from '@nervosnetwork/ckb-sdk-utils' import { AddressOptions } from '@nervosnetwork/ckb-sdk-utils/lib/address' -const { hexToBytes, pubkeyToAddress, blake160, AddressPrefix, AddressType } = utils +const { pubkeyToAddress, blake160, AddressPrefix, AddressType } = utils class Address extends ECPair { public value = '' - public identifier = '' + public publicKeyHash = '' public constructor( sk: Uint8Array | string, @@ -27,13 +27,13 @@ class Address extends ECPair { codeHashIndex: '0x00', } ) { - super(typeof sk === 'string' ? hexToBytes(sk) : sk) + super(sk) this.value = addressAlgorithm(this.publicKey, { prefix, type, codeHashIndex, }) - this.identifier = blake160(this.publicKey as string, 'hex') + this.publicKeyHash = `0x${blake160(this.publicKey as string, 'hex')}` } } diff --git a/packages/ckb-sdk-core/CHANGELOG.md b/packages/ckb-sdk-core/CHANGELOG.md index efa030ab..56732801 100644 --- a/packages/ckb-sdk-core/CHANGELOG.md +++ b/packages/ckb-sdk-core/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [0.21.0](https://github.com/nervosnetwork/ckb-sdk-js/compare/v0.20.0...v0.21.0) (2019-09-21) + + +### Code Refactoring + +* **address** rename public key identifier to publicKeyHash ([b33c096](https://github.com/nervosnetwork/ckb-sdk-js/commit/b33c096)) + + +### BREAKING CHANGES + +* **address** rename public key identifier to publicKeyHash + + + + + # [0.20.0](https://github.com/nervosnetwork/ckb-sdk-js/compare/v0.19.1...v0.20.0) (2019-09-07) **Note:** Version bump only for package @nervosnetwork/ckb-sdk-core diff --git a/packages/ckb-sdk-core/__tests__/ckb-core.test.js b/packages/ckb-sdk-core/__tests__/ckb-core.test.js deleted file mode 100644 index 2668b485..00000000 --- a/packages/ckb-sdk-core/__tests__/ckb-core.test.js +++ /dev/null @@ -1,98 +0,0 @@ -const successFixtures = require('./successFixtures.json') -const exceptionFixtures = require('./exceptionFixtures.json') - -const Core = require('../lib').default - -const url = 'http://localhost:8114' -const core = new Core(url) - -describe('ckb-core', () => { - describe('success', () => { - it('load the secp256k1 dep', async () => { - jest.setTimeout(50000) - const fixture = successFixtures.loadSecp256k1Dep - expect(core.config.loadSecp256k1Dep).toEqual(undefined) - - const secp256k1Dep = await core.loadSecp256k1Dep() - expect(secp256k1Dep).toEqual(fixture.target) - }) - - it('sign witnesses', () => { - const fixture = successFixtures.signWitnesses - const signedWitnessesByPrivateKey = core.signWitnesses(fixture.privateKey)(fixture.message) - expect(signedWitnessesByPrivateKey).toEqual(fixture.target) - - const signedWitnessesByAddressObject = core.signWitnesses(core.generateAddress(fixture.privateKey))( - fixture.message - ) - expect(signedWitnessesByAddressObject).toEqual(fixture.target) - }) - - it('compute script hash', async () => { - const fixture = { - script: { - codeHash: '0xb35557e7e9854206f7bc13e3c3a7fa4cf8892c84a09237fb0aab40aab3771eee', - hashType: 'data', - args: [], - }, - scriptHash: '0x9e9e450fa32ef75e7063023574f1fd3647e8eb35ff5ce9e3c04fb3056c8e37d6', - } - const computedHash = await core.rpc.computeScriptHash(fixture.script) - expect(computedHash).toBe(fixture.scriptHash) - }) - - it('sign transaction', async () => { - const fixture = successFixtures.signTransaction - const signedTransactionWithPrivateKey = await core.signTransaction(fixture.privateKey)(fixture.transaction) - const signedTransactionWithAddressObj = await core.signTransaction(core.generateAddress(fixture.privateKey))( - fixture.transaction - ) - expect(signedTransactionWithPrivateKey).toEqual(fixture.target) - expect(signedTransactionWithAddressObj).toEqual(fixture.target) - }) - }) - - describe('exceptions', () => { - describe('sign witneses', () => { - it('throw an error when key is missing', () => { - const fixture = exceptionFixtures.signWitnessesWithoutKey - expect(() => core.signWitnesses(fixture.privateKey)(fixture.message)).toThrowError(fixture.exception) - }) - - it('throw an error when transaction hash is missing', () => { - const fixture = exceptionFixtures.signWitnessesWithoutTransactionHash - expect(() => core.signWitnesses(fixture.privateKey)(fixture.message)).toThrowError(fixture.exception) - }) - }) - - describe('sign transaction', () => { - it('throw an error when key is missing', () => { - const fixture = exceptionFixtures.signTransactionWithoutKey - expect(core.signTransaction(fixture.privateKey)(fixture.transaction)).rejects.toEqual( - new Error(fixture.exception) - ) - }) - - it('throw an error when trasnaction is missing', () => { - const fixture = exceptionFixtures.signTransactionWithoutTransaction - expect(core.signTransaction(fixture.privateKey)(fixture.transaction)).rejects.toEqual( - new Error(fixture.exception) - ) - }) - - it('throw an error when witnesses is missing', () => { - const fixture = exceptionFixtures.signTransactionWithoutWitnesses - expect(core.signTransaction(fixture.privateKey)(fixture.transaction)).rejects.toEqual( - new Error(fixture.exception) - ) - }) - - it('throw an error with invalid cound of witnesses', () => { - const fixture = exceptionFixtures.signTransactionWithInvalidCountOfWitnesses - expect(core.signTransaction(fixture.privateKey)(fixture.transaction)).rejects.toEqual( - new Error(fixture.exception) - ) - }) - }) - }) -}) diff --git a/packages/ckb-sdk-core/__tests__/exceptionFixtures.json b/packages/ckb-sdk-core/__tests__/exceptionFixtures.json deleted file mode 100644 index 4f7cc657..00000000 --- a/packages/ckb-sdk-core/__tests__/exceptionFixtures.json +++ /dev/null @@ -1,156 +0,0 @@ -{ - "signWitnessesWithoutKey": { - "privateKey": null, - "message": { - "transactionHash": "0xac1bb95455cdfb89b6e977568744e09b6b80e08cab9477936a09c4ca07f5b8ab", - "witnesses": [ - { - "data": [] - } - ] - }, - "exception": "Private key or address object is required" - }, - - "signWitnessesWithoutTransactionHash": { - "privateKey": "0xe79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3", - "message": { - "transactionHash": null, - "witnesses": [ - { - "data": [] - } - ] - }, - "exception": "Transaction hash is required" - }, - - "signTransactionWithoutKey": { - "privateKey": null, - "transaction": { - "deps": [ - { - "cell": { - "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" - }, - "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "inputs": [ - { - "previousOutput": { - "cell": { - "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" - }, - "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - "since": "0" - } - ], - "outputs": [ - { - "capacity": "5000000000000", - "data": "0x", - "lock": { - "args": [], - "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - "type": null - } - ], - "version": "0", - "witnesses": [{ "data": [] }] - }, - "exception": "Private key or address object is required" - }, - - "signTransactionWithoutTransaction": { - "privateKey": "0xe79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3", - "transaction": null, - "exception": "Transaction is required" - }, - - "signTransactionWithoutWitnesses": { - "privateKey": "0xe79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3", - "transaction": { - "deps": [ - { - "cell": { - "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" - }, - "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "inputs": [ - { - "previousOutput": { - "cell": { - "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" - }, - "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - "since": "0" - } - ], - "outputs": [ - { - "capacity": "5000000000000", - "data": "0x", - "lock": { - "args": [], - "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - "type": null - } - ], - "version": "0", - "witnesses": null - }, - "exception": "Witnesses is required" - }, - - "signTransactionWithInvalidCountOfWitnesses": { - "privateKey": "0xe79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3", - "transaction": { - "deps": [ - { - "cell": { - "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" - }, - "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "inputs": [ - { - "previousOutput": { - "cell": { - "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" - }, - "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - "since": "0" - } - ], - "outputs": [ - { - "capacity": "5000000000000", - "data": "0x", - "lock": { - "args": [], - "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - "type": null - } - ], - "version": "0", - "witnesses": [] - }, - "exception": "Invalid count of witnesses" - } -} diff --git a/packages/ckb-sdk-core/__tests__/fixtures.json b/packages/ckb-sdk-core/__tests__/fixtures.json new file mode 100644 index 00000000..684ee460 --- /dev/null +++ b/packages/ckb-sdk-core/__tests__/fixtures.json @@ -0,0 +1,256 @@ +{ + "loadSecp256k1Dep": { + "target": { + "hashType": "type", + "codeHash": "0x1892ea40d82b53c678ff88312450bbb17e164d7a3e0a90941aa58839f56f8df2", + "outPoint": { + "txHash": "0x6347ee7ce5fc6828133590558b867097b895149a66e51cf353c361f7128e2091", + "index": "0x0" + } + } + }, + "signWitnesses": { + "basic witnesses": { + "privateKey": "0xe79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3", + "message": { + "transactionHash": "0xac1bb95455cdfb89b6e977568744e09b6b80e08cab9477936a09c4ca07f5b8ab", + "witnesses": [ + { + "data": [] + } + ] + }, + "expected": [ + { + "data": [ + "0x2c643579e47045be050d3842ed9270151af8885e33954bddad0e53e81d1c2dbe2dc637877a8302110846ebc6a16d9148c106e25f945063ad1c4d4db2b695240800" + ] + } + ] + }, + "without private key should throw an error": { + "privateKey": null, + "message": { + "transactionHash": "0xac1bb95455cdfb89b6e977568744e09b6b80e08cab9477936a09c4ca07f5b8ab", + "witnesses": [ + { + "data": [] + } + ] + }, + "exception": "Private key or address object is required" + }, + "without transaction hash should throw an error": { + "privateKey": "0xe79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3", + "message": { + "transactionHash": null, + "witnesses": [ + { + "data": [] + } + ] + }, + "exception": "Transaction hash is required" + } + }, + "signTransaction": { + "basic transaction": { + "privateKey": "0xe79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3", + "transaction": { + "cellDeps": [], + "headerDeps": [], + "inputs": [ + { + "previousOutput": { + "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "index": "0xffffffff" + }, + "since": "0x0" + } + ], + "outputs": [ + { + "capacity": "0x48c27395000", + "lock": { + "args": [], + "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "hashType": "data" + }, + "type": null + } + ], + "outputsData": ["0x"], + "version": "0x0", + "witnesses": [{ "data": [] }] + }, + "expected": { + "cellDeps": [], + "headerDeps": [], + "inputs": [ + { + "previousOutput": { + "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "index": "0xffffffff" + }, + "since": "0x0" + } + ], + "outputs": [ + { + "capacity": "0x48c27395000", + "lock": { + "args": [], + "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "hashType": "data" + }, + "type": null + } + ], + "outputsData": ["0x"], + "version": "0x0", + "witnesses": [ + { + "data": [ + "0x9f626950d515cb7829467646a5cab7c66c873c542a4ad4c6420fde4ea9eda14d23404d26a114a7e989bf6ca7e11d6ec8777fa4410fa88c55ace33ed7ba45f5c800" + ] + } + ] + } + }, + "without private key should throw an error": { + "privateKey": null, + "transaction": { + "deps": [ + { + "cell": { + "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "index": "0xffffffff" + }, + "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "inputs": [ + { + "previousOutput": { + "cell": { + "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "index": "0xffffffff" + }, + "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "since": "0x0" + } + ], + "outputs": [ + { + "capacity": "0x48c27395000", + "data": "0x", + "lock": { + "args": [], + "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + "type": null + } + ], + "version": "0x0", + "witnesses": [{ "data": [] }] + }, + "exception": "Private key or address object is required" + }, + "without transaction should throw an error": { + "privateKey": "0xe79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3", + "transaction": null, + "exception": "Transaction is required" + }, + "without witnesses should throw an error": { + "privateKey": "0xe79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3", + "transaction": { + "deps": [ + { + "cell": { + "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "index": "0xffffffff" + }, + "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "inputs": [ + { + "previousOutput": { + "cell": { + "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "index": "0xffffffff" + }, + "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "since": "0x0" + } + ], + "outputs": [ + { + "capacity": "0x48c27395000", + "data": "0x", + "lock": { + "args": [], + "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + "type": null + } + ], + "version": "0x0", + "witnesses": null + }, + "exception": "Witnesses is required" + }, + "with invalid count of witnesses should throw an error": { + "privateKey": "0xe79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3", + "transaction": { + "deps": [ + { + "cell": { + "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "index": "0xffffffff" + }, + "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "inputs": [ + { + "previousOutput": { + "cell": { + "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "index": "0xffffffff" + }, + "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "since": "0x0" + } + ], + "outputs": [ + { + "capacity": "0x48c27395000", + "data": "0x", + "lock": { + "args": [], + "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + "type": null + } + ], + "version": "0x0", + "witnesses": [] + }, + "exception": "Invalid count of witnesses" + } + }, + "computeScriptHash": { + "baisc": { + "script": { + "codeHash": "0xb35557e7e9854206f7bc13e3c3a7fa4cf8892c84a09237fb0aab40aab3771eee", + "hashType": "data", + "args": [] + }, + "expected": "0x9e9e450fa32ef75e7063023574f1fd3647e8eb35ff5ce9e3c04fb3056c8e37d6" + } + } +} diff --git a/packages/ckb-sdk-core/__tests__/index.test.js b/packages/ckb-sdk-core/__tests__/index.test.js new file mode 100644 index 00000000..12e465ea --- /dev/null +++ b/packages/ckb-sdk-core/__tests__/index.test.js @@ -0,0 +1,76 @@ +const fixtures = require('./fixtures.json') + +const { default: Core } = require('../lib') + +const url = 'http://localhost:8114' +const core = new Core(url) + +describe('ckb-core', () => { + it('load the secp256k1 dep', async () => { + jest.setTimeout(50000) + const fixture = fixtures.loadSecp256k1Dep + expect(core.config.loadSecp256k1Dep).toEqual(undefined) + + const secp256k1Dep = await core.loadSecp256k1Dep() + expect(secp256k1Dep).toEqual(fixture.target) + }) + + describe('sign witnesses', () => { + const fixtureTable = Object.entries(fixtures.signWitnesses).map( + ([title, { privateKey, message, expected, exception }]) => [title, privateKey, message, expected, exception] + ) + test.each(fixtureTable)('%s', (_title, privateKey, message, expected, exception) => { + if (undefined !== expected) { + const signedWitnessesByPrivateKey = core.signWitnesses(privateKey)(message) + expect(signedWitnessesByPrivateKey).toEqual(expected) + + const signedWitnessesByAddressObject = core.signWitnesses(core.generateAddress(privateKey))(message) + expect(signedWitnessesByAddressObject).toEqual(expected) + } + if (undefined !== exception) { + expect(() => core.signWitnesses(privateKey)(message)).toThrowError(exception) + } + }) + }) + + describe('compute script hash', () => { + const fixtureTable = Object.entries(fixtures.computeScriptHash).map(([title, { script, expected, exception }]) => [ + title, + script, + expected, + exception, + ]) + test.each(fixtureTable)('%s', async (_title, script, expected, exception) => { + if (undefined !== exception) { + const computedHash = await core.rpc.computeScriptHash(script) + expect(computedHash).toBe(expected) + } + if (undefined !== exception) { + expect(core.rpc.computeScriptHash(script)).reject.toBe(new Error(exception)) + } + }) + }) + + describe('sign transaction', () => { + const fixtureTable = Object.entries(fixtures.signTransaction).map( + ([title, { privateKey, transaction, expected, exception }]) => [ + title, + privateKey, + transaction, + expected, + exception, + ] + ) + test.each(fixtureTable)('%s', (_title, privateKey, transaction, expected, exception) => { + if (undefined !== expected) { + const signedTransactionWithPrivateKey = core.signTransaction(privateKey)(transaction) + const signedTransactionWithAddressObj = core.signTransaction(core.generateAddress(privateKey))(transaction) + expect(signedTransactionWithPrivateKey).toEqual(expected) + expect(signedTransactionWithAddressObj).toEqual(expected) + } + if (undefined !== exception) { + expect(() => core.signTransaction(privateKey)(transaction)).toThrow(new Error(exception)) + } + }) + }) +}) diff --git a/packages/ckb-sdk-core/__tests__/successFixtures.json b/packages/ckb-sdk-core/__tests__/successFixtures.json deleted file mode 100644 index 808a3fec..00000000 --- a/packages/ckb-sdk-core/__tests__/successFixtures.json +++ /dev/null @@ -1,95 +0,0 @@ -{ - "loadSecp256k1Dep": { - "target": { - "hashType": "type", - "codeHash": "0x68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88", - "outPoint": { - "txHash": "0x9a0d9a0d8bb39cbe468783df7db219f8eb1a703691e3bd2f691f3d1568a3abc1", - "index": "0" - } - } - }, - - "signWitnesses": { - "privateKey": "0xe79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3", - "message": { - "transactionHash": "0xac1bb95455cdfb89b6e977568744e09b6b80e08cab9477936a09c4ca07f5b8ab", - "witnesses": [ - { - "data": [] - } - ] - }, - "target": [ - { - "data": [ - "0x2c643579e47045be050d3842ed9270151af8885e33954bddad0e53e81d1c2dbe2dc637877a8302110846ebc6a16d9148c106e25f945063ad1c4d4db2b695240800" - ] - } - ] - }, - - "signTransaction": { - "privateKey": "0xe79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3", - "transaction": { - "cellDeps": [], - "headerDeps": [], - "inputs": [ - { - "previousOutput": { - "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" - }, - "since": "0" - } - ], - "outputs": [ - { - "capacity": "5000000000000", - "lock": { - "args": [], - "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", - "hashType": "data" - }, - "type": null - } - ], - "outputsData": ["0x"], - "version": "0", - "witnesses": [{ "data": [] }] - }, - "target": { - "cellDeps": [], - "headerDeps": [], - "inputs": [ - { - "previousOutput": { - "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" - }, - "since": "0" - } - ], - "outputs": [ - { - "capacity": "5000000000000", - "lock": { - "args": [], - "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", - "hashType": "data" - }, - "type": null - } - ], - "outputsData": ["0x"], - "version": "0", - "witnesses": [ - { - "data": [ - "0x9f626950d515cb7829467646a5cab7c66c873c542a4ad4c6420fde4ea9eda14d23404d26a114a7e989bf6ca7e11d6ec8777fa4410fa88c55ace33ed7ba45f5c800" - ] - } - ] - } - } -} diff --git a/packages/ckb-sdk-core/examples/sendTransaction.js b/packages/ckb-sdk-core/examples/sendTransaction.js index 991ff655..30786d7a 100644 --- a/packages/ckb-sdk-core/examples/sendTransaction.js +++ b/packages/ckb-sdk-core/examples/sendTransaction.js @@ -4,7 +4,7 @@ const Core = require('../lib').default const bootstrap = async () => { const nodeUrl = process.env.NODE_URL || 'http://localhost:8114' // example node url const privateKey = process.env.PRIV_KEY || '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' // example private key - const blockAssemblerCodeHash = '0x1d107ddec56ec77b79c41cd10b35a3b47434c93a604ecb8e8e73e7372fe1a794' // transcribe the block_assembler.code_hash in the ckb.toml from the ckb project + const blockAssemblerCodeHash = '0x1892ea40d82b53c678ff88312450bbb17e164d7a3e0a90941aa58839f56f8df2' // transcribe the block_assembler.code_hash in the ckb.toml from the ckb project const core = new Core(nodeUrl) // instantiate the JS SDK with provided node url @@ -15,7 +15,7 @@ const bootstrap = async () => { * - value, the address string * - privateKey, the private key in hex string format * - publicKey, the public key in hex string format - * - identifier, the identifier of the public key, a blake160-ed public key is use here + * - publicKeyHash, the publicKeyHash of the public key, a blake160-ed public key is use here * - sign(msg): signature string * - verify(msg, signature): boolean */ @@ -26,23 +26,23 @@ const bootstrap = async () => { console.log(myAddressObj.value) /** - * calculate the lockHash by the address identifier - * 1. the identifier of the address is required in the args field of lock script + * calculate the lockHash by the address publicKeyHash + * 1. the publicKeyHash of the address is required in the args field of lock script * 2. compose the lock script with the code hash(as a miner, we use blockAssemblerCodeHash here), and args * 3. calculate the hash of lock script via core.utils.scriptToHash method */ const lockScript = { - hashType: "data", + hashType: "type", codeHash: blockAssemblerCodeHash, - args: [`0x${myAddressObj.identifier}`], + args: [myAddressObj.publicKeyHash], } /** * to see the lock script */ // console.log(JSON.stringify(lockScript, null, 2)) - const lockHash = `0x${core.utils.scriptToHash(lockScript)}` + const lockHash = core.utils.scriptToHash(lockScript) /** * to see the lock hash */ @@ -105,11 +105,11 @@ const bootstrap = async () => { // .then(console.log) /** - * @notice fill the blaked160ed public key as the identifier of the target address in the output's args, + * @notice fill the blaked160ed public key as the publicKeyHash of the target address in the output's args, * which is used to specify the next owner of the output, namely the fresh cell. * @notice use bigint or big number to handle the capacity for safety */ - const generateTransaction = async (targetIdentifier, capacity) => { + const generateTransaction = async (targetPublicKeyHash, capacity) => { const targetCapacity = BigInt(capacity) /** @@ -120,7 +120,7 @@ const bootstrap = async () => { lock: { hashType: secp256k1Dep.hashType, codeHash: secp256k1Dep.codeHash, - args: [targetIdentifier], + args: [targetPublicKeyHash], }, } @@ -132,7 +132,7 @@ const bootstrap = async () => { lock: { hashType: secp256k1Dep.hashType, codeHash: secp256k1Dep.codeHash, - args: [`0x${myAddressObj.identifier}`], + args: [myAddressObj.publicKeyHash], }, } @@ -146,8 +146,7 @@ const bootstrap = async () => { const unspentCell = unspentCells[i] inputs.push({ previousOutput: unspentCell.outPoint, - since: '0', - args: [], + since: '0x0', }) inputCapacity += BigInt(unspentCells[i].capacity) if (inputCapacity >= targetCapacity) { @@ -168,21 +167,21 @@ const bootstrap = async () => { const outputs = changeOutput.capacity > 0n ? [{ ...targetOutput, - capacity: targetOutput.capacity.toString(), + capacity: `0x${targetOutput.capacity.toString(16)}`, }, { ...changeOutput, - capacity: changeOutput.capacity.toString(), + capacity: `0x${changeOutput.capacity.toString(16)}`, }, ] : [{ ...targetOutput, - capacity: targetOutput.capacity.toString(), + capacity: `0x${targetOutput.capacity.toString(16)}`, }, ] const outputsData = outputs.map(output => "0x") const tx = { - version: '0', + version: '0x0', cellDeps: [{ outPoint: secp256k1Dep.outPoint, depType: "depGroup", @@ -201,14 +200,14 @@ const bootstrap = async () => { /** * to see the generated transaction */ - // generateTransaction(`0x${blake160edPublicKey}`, 1000000000000).then(tx => { + // generateTransaction(blake160edPublicKey, 1000000000000).then(tx => { // console.log(JSON.stringify(tx, null, 2)) // }) /** * send transaction */ - const tx = await generateTransaction(`0x${myAddressObj.identifier}`, 60000000000) // generate the raw transaction with empty witnesses + const tx = await generateTransaction(myAddressObj.publicKeyHash, 60000000000) // generate the raw transaction with empty witnesses const signedTx = await core.signTransaction(myAddressObj)(tx) /** * to see the signed transaction diff --git a/packages/ckb-sdk-core/package.json b/packages/ckb-sdk-core/package.json index 0391283d..bbf6e442 100644 --- a/packages/ckb-sdk-core/package.json +++ b/packages/ckb-sdk-core/package.json @@ -1,6 +1,6 @@ { "name": "@nervosnetwork/ckb-sdk-core", - "version": "0.20.0", + "version": "0.21.0", "description": "JavaScript SDK for Nervos Network CKB Project", "author": "Nervos ", "homepage": "https://github.com/nervosnetwork/ckb-sdk-js#readme", @@ -23,16 +23,17 @@ "url": "git+https://github.com/nervosnetwork/ckb-sdk-js.git" }, "scripts": { - "tsc": "tsc" + "tsc": "tsc", + "test": "../../node_modules/.bin/jest" }, "bugs": { "url": "https://github.com/nervosnetwork/ckb-sdk-js/issues" }, "dependencies": { - "@nervosnetwork/ckb-sdk-address": "0.20.0", - "@nervosnetwork/ckb-sdk-rpc": "0.20.0", - "@nervosnetwork/ckb-sdk-utils": "0.20.0", - "@nervosnetwork/ckb-types": "0.20.0" + "@nervosnetwork/ckb-sdk-address": "0.21.0", + "@nervosnetwork/ckb-sdk-rpc": "0.21.0", + "@nervosnetwork/ckb-sdk-utils": "0.21.0", + "@nervosnetwork/ckb-types": "0.21.0" }, - "gitHead": "478433630dd40501f1f67dc259bf9d252c56fcd3" + "gitHead": "5a1aaff6006c91e45e8ba39ceb6ef7c2f870e6cd" } diff --git a/packages/ckb-sdk-core/src/index.ts b/packages/ckb-sdk-core/src/index.ts index ecf5d19d..2ae469cb 100644 --- a/packages/ckb-sdk-core/src/index.ts +++ b/packages/ckb-sdk-core/src/index.ts @@ -86,7 +86,7 @@ class Core { * cell list * @link https://github.com/nervosnetwork/ckb/blob/dbadf484cea6bdba0329d58102726068be997a50/docs/hashes.toml */ - const block = await this.rpc.getBlockByNumber('0') + const block = await this.rpc.getBlockByNumber('0x0') if (!block) throw new Error('Cannot load the genesis block') const secp256k1CodeTx = block.transactions[0] if (!secp256k1CodeTx) throw new Error('Cannot load the transaction which has the secp256k1 code cell') @@ -97,7 +97,7 @@ class Core { throw new Error('Secp256k1 type script not found in the cell') } - const secp256k1TypeHash = `0x${this.utils.scriptToHash(secp256k1CodeTx.outputs[1].type)}` + const secp256k1TypeHash = this.utils.scriptToHash(secp256k1CodeTx.outputs[1].type) const secp256k1DepTx = block.transactions[1] if (!secp256k1DepTx) throw new Error('Cannot load the transaction which has the secp256k1 dep cell') @@ -110,7 +110,7 @@ class Core { codeHash: secp256k1TypeHash, outPoint: { txHash: secp256k1DepTx.hash, - index: '0', + index: '0x0', }, } return this.config.secp256k1Dep @@ -130,12 +130,12 @@ class Core { const signedWitnesses = witnesses.map(witness => { const oldData = witness.data || [] const s = this.utils.blake2b(32, null, null, this.utils.PERSONAL) - s.update(this.utils.hexToBytes(transactionHash.replace(/^0x/, ''))) + s.update(this.utils.hexToBytes(transactionHash)) oldData.forEach(datum => { s.update(this.utils.hexToBytes(datum)) }) - const message = s.digest('hex') - const data = [`0x${addrObj.signRecoverable(message)}`, ...oldData] + const message = `0x${s.digest('hex')}` + const data = [addrObj.signRecoverable(message), ...oldData] return { data, } @@ -143,7 +143,7 @@ class Core { return signedWitnesses } - public signTransaction = (key: string | Address) => async (transaction: CKBComponents.RawTransaction) => { + public signTransaction = (key: string | Address) => (transaction: CKBComponents.RawTransaction) => { if (!key) throw new Error('Private key or address object is required') if (!transaction) throw new Error('Transaction is required') if (!transaction.witnesses) throw new Error('Witnesses is required') @@ -152,7 +152,7 @@ class Core { if (transaction.outputsData.length < transaction.outputs.length) throw new Error('Invalid count of outputsData') const transactionHash = this.utils.rawTransactionToHash(transaction) - const signedWitnesses = await this.signWitnesses(key)({ + const signedWitnesses = this.signWitnesses(key)({ transactionHash, witnesses: transaction.witnesses, }) diff --git a/packages/ckb-sdk-rpc/CHANGELOG.md b/packages/ckb-sdk-rpc/CHANGELOG.md index 87d22972..e65cd52a 100644 --- a/packages/ckb-sdk-rpc/CHANGELOG.md +++ b/packages/ckb-sdk-rpc/CHANGELOG.md @@ -3,6 +3,24 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [0.21.0](https://github.com/nervosnetwork/ckb-sdk-js/compare/v0.20.0...v0.21.0) (2019-09-21) + + +### Features + +* **rpc:** format the outputs of the params formatter ([740b403](https://github.com/nervosnetwork/ckb-sdk-js/commit/740b403)) +* **rpc:** update the interface of getLiveCell ([0280d7f](https://github.com/nervosnetwork/ckb-sdk-js/commit/0280d7f)) + + +### BREAKING CHANGES + +* **rpc:** update the interface of getLiveCell +* **rpc:** hexilize the outputs of the params formatter + + + + + # [0.20.0](https://github.com/nervosnetwork/ckb-sdk-js/compare/v0.19.1...v0.20.0) (2019-09-07) **Note:** Version bump only for package @nervosnetwork/ckb-sdk-rpc diff --git a/packages/ckb-sdk-rpc/__tests__/ckb-rpc.test.js b/packages/ckb-sdk-rpc/__tests__/ckb-rpc.test.js index 50c8b878..4374d3a8 100644 --- a/packages/ckb-sdk-rpc/__tests__/ckb-rpc.test.js +++ b/packages/ckb-sdk-rpc/__tests__/ckb-rpc.test.js @@ -35,7 +35,7 @@ describe('ckb-rpc success', () => { }) it('get block hash and get block of genesis block', async () => { - const hash = await rpc.getBlockHash('0') + const hash = await rpc.getBlockHash('0x0') expect(hash.length).toBe(66) const block = await rpc.getBlock(hash) expect(block.header.hash).toBe(hash) @@ -52,7 +52,7 @@ describe('ckb-rpc success', () => { }) it('get transaction', async () => { - const hash = await rpc.getBlockHash('0') + const hash = await rpc.getBlockHash('0x0') const block = await rpc.getBlock(hash) const { transactions } = block if (transactions.length) { @@ -71,15 +71,15 @@ describe('ckb-rpc success', () => { it('get live cell', async () => { const outPoint = { txHash: '0xff5a36107851d244e1543821f9f039c3d4eb69d9968750b0b0e82e78da86c987', - index: '0', + index: '0x0', } - const cellRes = await rpc.getLiveCell(outPoint) + const cellRes = await rpc.getLiveCell(outPoint, true) expect(cellRes.status).toBe('unknown') }) it('get cells by lock hash', async () => { const lockHash = '0x0da2fe99fe549e082d4ed483c2e968a89ea8d11aabf5d79e5cbf06522de6e674' - const cells = await rpc.getCellsByLockHash(lockHash, '0', '100') + const cells = await rpc.getCellsByLockHash(lockHash, '0x0', '0x64') expect(Array.isArray(cells)).toBeTruthy() }) @@ -109,7 +109,7 @@ describe('ckb-rpc success', () => { }) it('get header', async () => { - const zeroBlock = await rpc.getBlockByNumber('0') + const zeroBlock = await rpc.getBlockByNumber('0x0') const zeroBlockHeader = zeroBlock.header const zeroBlockHash = zeroBlockHeader.hash const header = await rpc.getHeader(zeroBlockHash) @@ -117,46 +117,48 @@ describe('ckb-rpc success', () => { }) it('get header by number', async () => { - const zeroBlock = await rpc.getBlockByNumber('0') + const zeroBlock = await rpc.getBlockByNumber('0x0') const zeroBlockHeader = zeroBlock.header - const header = await rpc.getHeaderByNumber('0') + const header = await rpc.getHeaderByNumber('0x0') expect(header).toEqual(zeroBlockHeader) }) }) describe('send transaction', () => { it('send transaction', async () => { - const blockHash = await rpc.getBlockHash('0') - const block = await rpc.getBlock(blockHash) - const txHash = block.transactions[0].hash const tx = { - version: '0', - cellDeps: [], + cellDeps: [ + { + outPoint: { + txHash: '0x0000000000000000000000000000000000000000000000000000000000000000', + index: '0x1', + }, + depType: 'code', + }, + ], + headerDeps: [], inputs: [ { previousOutput: { - cell: { - txHash, - index: '0', - }, - blockHash, + txHash: '0x0000000000000000000000000000000000000000000000000000000000000000', + index: '0x0', }, - args: [], - since: '0', + since: '0x0', }, ], outputs: [ { + capacity: '0x48c27395000', lock: { args: [], codeHash: '0x0000000000000000000000000000000000000000000000000000000000000001', - hashType: 'Data', + hashType: 'data', }, type: null, - capacity: '1', - data: '0x', }, ], + version: '0x0', + outputsData: ['0x'], witnesses: [], } const hash = rpc.sendTransaction(tx) diff --git a/packages/ckb-sdk-rpc/__tests__/formatters/params.fixtures.json b/packages/ckb-sdk-rpc/__tests__/formatters/params.fixtures.json new file mode 100644 index 00000000..d2ef010e --- /dev/null +++ b/packages/ckb-sdk-rpc/__tests__/formatters/params.fixtures.json @@ -0,0 +1,342 @@ +{ + "toNumber": [ + { + "param": "0x1", + "expected": "0x1" + }, + { + "param": 20, + "expected": "0x14" + }, + { + "param": null, + "exception": "The number null should be a number or a hex string" + }, + { + "param": "1", + "exception": "If the number 1 is a hex string, please prefix it with 0x" + } + ], + "toHash": [ + { + "param": "0xe5f2d07b747f38718293987a9175764d4c03229a8a69d0bd48f7bea6c18930b1", + "expected": "0xe5f2d07b747f38718293987a9175764d4c03229a8a69d0bd48f7bea6c18930b1" + }, + { + "param": "e5f2d07b747f38718293987a9175764d4c03229a8a69d0bd48f7bea6c18930b1", + "expected": "0xe5f2d07b747f38718293987a9175764d4c03229a8a69d0bd48f7bea6c18930b1" + }, + { + "param": 1, + "exception": "Hash 1 should be type of string" + } + ], + "toOutPoint": [ + { + "param": null, + "expected": null + }, + { + "param": { + "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "index": "0xffffffff" + }, + "expected": { + "tx_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "index": "0xffffffff" + } + }, + { + "param": null, + "expected": null + } + ], + "toDepType": [ + { + "param": "code", + "expected": "code" + }, + { + "param": "depGroup", + "expected": "dep_group" + } + ], + "toCellDep": [ + { + "param": null, + "expected": null + }, + { + "param": { + "depType": "depGroup" + }, + "expected": { + "out_point": null, + "dep_type": "dep_group" + } + }, + { + "param": { + "outPoint": null + }, + "expected": { + "out_point": null, + "dep_type": "code" + } + }, + { + "param": { + "outPoint": null, + "depType": "depGroup" + }, + "expected": { + "out_point": null, + "dep_type": "dep_group" + } + }, + { + "param": { + "outPoint": { + "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "index": "0xffffffff" + }, + "depType": "code" + }, + "expected": { + "out_point": { + "tx_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "index": "0xffffffff" + }, + "dep_type": "code" + } + } + ], + + "toInput": [ + { + "param": null, + "expected": null + }, + { + "param": { + "previousOutput": null, + "since": 0 + }, + "expected": { + "previous_output": null, + "since": "0x0" + } + }, + { + "param": { + "previousOutput": { + "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "index": "0xffffffff" + }, + "since": "0x0" + }, + "expected": { + "previous_output": { + "tx_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "index": "0xffffffff" + }, + "since": "0x0" + } + } + ], + "toOutput": [ + { + "param": null, + "expected": null + }, + { + "param": { + "capacity": "0x48c27395000", + "data": "0x", + "lock": { + "args": [], + "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "hashType": "data" + }, + "type": null + }, + "expected": { + "capacity": "0x48c27395000", + "data": "0x", + "lock": { + "args": [], + "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "hash_type": "data" + }, + "type": null + } + }, + { + "param": { + "capacity": "0x48c27395000", + "data": "0x", + "lock": { + "args": [], + "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "hashType": "data" + } + }, + "expected": { + "capacity": "0x48c27395000", + "data": "0x", + "lock": { + "args": [], + "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "hash_type": "data" + }, + "type": null + } + } + ], + "toRawTransaction": [ + { + "param": null, + "expected": null + }, + { + "param": { + "version": "0x0" + }, + "expected": { + "version": "0x0", + "cell_deps": [], + "header_deps": [], + "inputs": [], + "outputs": [], + "outputs_data": [] + } + }, + { + "param": { + "cellDeps": [ + { + "outPoint": { + "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "index": "0xffffffff" + }, + "depType": "code" + } + ], + "headerDeps": [], + "inputs": [ + { + "previousOutput": null, + "since": "0x0" + }, + { + "previousOutput": { + "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "index": "0xffffffff" + }, + "since": "0x0" + } + ], + "outputs": [ + { + "capacity": "0x48c27395000", + "lock": { + "args": [], + "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "hashType": "data" + }, + "type": null + } + ], + "version": "0x0", + "outputsData": ["0x"], + "witnesses": [] + }, + "expected": { + "cell_deps": [ + { + "out_point": { + "tx_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "index": "0xffffffff" + }, + "dep_type": "code" + } + ], + "header_deps": [], + "inputs": [ + { + "previous_output": null, + "since": "0x0" + }, + { + "previous_output": { + "tx_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "index": "0xffffffff" + }, + "since": "0x0" + } + ], + "outputs": [ + { + "capacity": "0x48c27395000", + "lock": { + "args": [], + "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "hash_type": "data" + }, + "type": null + } + ], + "version": "0x0", + "outputs_data": ["0x"], + "witnesses": [] + } + } + ], + "toPageNumber": [ + { + "param": "0x12", + "expected": "0x12" + }, + { + "param": 12, + "expected": "0xc" + }, + { + "expected": "0x1" + } + ], + "toPageSize": [ + { + "param": "0x12", + "expected": "0x12" + }, + { + "param": 12, + "expected": "0xc" + }, + { + "expected": "0x32" + }, + { + "param": "-1", + "exception": "Page size is expected to be positive" + }, + { + "param": "51", + "exception": "Page size is up to 50" + } + ], + "toReverseOrder": [ + { + "param": true, + "expected": true + }, + { + "param": false, + "expected": false + }, + { + "expected": false + } + ] +} diff --git a/packages/ckb-sdk-rpc/__tests__/formatters/params.json b/packages/ckb-sdk-rpc/__tests__/formatters/params.json deleted file mode 100644 index 8a11aea3..00000000 --- a/packages/ckb-sdk-rpc/__tests__/formatters/params.json +++ /dev/null @@ -1,332 +0,0 @@ -{ - "success": { - "toHash": [ - { - "source": "0xe5f2d07b747f38718293987a9175764d4c03229a8a69d0bd48f7bea6c18930b1", - "target": "0xe5f2d07b747f38718293987a9175764d4c03229a8a69d0bd48f7bea6c18930b1" - }, - { - "source": "e5f2d07b747f38718293987a9175764d4c03229a8a69d0bd48f7bea6c18930b1", - "target": "0xe5f2d07b747f38718293987a9175764d4c03229a8a69d0bd48f7bea6c18930b1" - } - ], - "toOutPoint": [ - { - "source": null, - "target": null - }, - { - "source": { - "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" - }, - "target": { - "tx_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" - } - }, - { - "source": null, - "target": null - } - ], - "toDepType": [ - { - "source": "code", - "target": "code" - }, - { - "source": "depGroup", - "target": "dep_group" - } - ], - "toCellDep": [ - { - "source": null, - "target": null - }, - { - "source": { - "depType": "depGroup" - }, - "target": { - "out_point": null, - "dep_type": "dep_group" - } - }, - { - "source": { - "outPoint": null - }, - "target": { - "out_point": null, - "dep_type": "code" - } - }, - { - "source": { - "outPoint": null, - "depType": "depGroup" - }, - "target": { - "out_point": null, - "dep_type": "dep_group" - } - }, - { - "source": { - "outPoint": { - "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" - }, - "depType": "code" - }, - "target": { - "out_point": { - "tx_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" - }, - "dep_type": "code" - } - } - ], - "toNumber": [ - { - "source": "1", - "target": "1" - } - ], - - "toInput": [ - { - "source": null, - "target": null - }, - { - "source": { - "previousOutput": null, - "since": 0 - }, - "target": { - "previous_output": null, - "since": 0 - } - }, - { - "source": { - "previousOutput": { - "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" - }, - "since": "0" - }, - "target": { - "previous_output": { - "tx_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" - }, - "since": "0" - } - } - ], - "toOutput": [ - { - "source": null, - "target": null - }, - { - "source": { - "capacity": "5000000000000", - "data": "0x", - "lock": { - "args": [], - "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", - "hashType": "data" - }, - "type": null - }, - "target": { - "capacity": "5000000000000", - "data": "0x", - "lock": { - "args": [], - "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", - "hash_type": "data" - }, - "type": null - } - }, - { - "source": { - "capacity": "5000000000000", - "data": "0x", - "lock": { - "args": [], - "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", - "hashType": "data" - } - }, - "target": { - "capacity": "5000000000000", - "data": "0x", - "lock": { - "args": [], - "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", - "hash_type": "data" - }, - "type": null - } - } - ], - "toRawTransaction": [ - { - "source": null, - "target": null - }, - { - "source": { - "version": "0" - }, - "target": { - "version": "0", - "cell_deps": [], - "header_deps": [], - "inputs": [], - "outputs": [], - "outputs_data": [] - } - }, - { - "source": { - "cellDeps": [ - { - "outPoint": { - "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" - }, - "depType": "code" - } - ], - "headerDeps": [], - "inputs": [ - { - "previousOutput": null, - "since": 0 - }, - { - "previousOutput": { - "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" - }, - "since": "0" - } - ], - "outputs": [ - { - "capacity": "5000000000000", - "data": "0x", - "lock": { - "args": [], - "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", - "hashType": "data" - }, - "type": null - } - ], - "version": "0", - "outputsData": ["0x"] - }, - "target": { - "cell_deps": [ - { - "out_point": { - "tx_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" - }, - "dep_type": "code" - } - ], - "header_deps": [], - "inputs": [ - { - "previous_output": null, - "since": 0 - }, - { - "previous_output": { - "tx_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" - }, - "since": "0" - } - ], - "outputs": [ - { - "capacity": "5000000000000", - "data": "0x", - "lock": { - "args": [], - "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", - "hash_type": "data" - }, - "type": null - } - ], - "version": "0", - "outputs_data": ["0x"] - } - } - ], - "toPageNumber": [ - { - "source": "12", - "target": "12" - }, - { - "source": 12, - "target": "12" - }, - { - "target": "1" - } - ], - "toPageSize": [ - { - "source": "12", - "target": "12" - }, - { - "source": 12, - "target": "12" - }, - { - "target": "50" - } - ], - "toReverseOrder": [ - { - "source": true, - "target": true - }, - { - "source": false, - "target": false - }, - { - "target": false - } - ] - }, - "failure": { - "toPageSize": [ - { - "source": "-1", - "error": "Page size is expected to be positive" - }, - { - "source": "51", - "error": "Page size is up to 50" - } - ] - } -} diff --git a/packages/ckb-sdk-rpc/__tests__/formatters/params.test.js b/packages/ckb-sdk-rpc/__tests__/formatters/params.test.js index 1d6a0083..4d462036 100644 --- a/packages/ckb-sdk-rpc/__tests__/formatters/params.test.js +++ b/packages/ckb-sdk-rpc/__tests__/formatters/params.test.js @@ -1,21 +1,21 @@ -const paramsFmt = require('../../lib/paramsFormatter').default -const fixtures = require('./params.json') +const { default: paramsFmt } = require('../../lib/paramsFormatter') +const fixtures = require('./params.fixtures.json') -const { success, failure } = fixtures - -describe('params formatter success', () => { - test.each(Object.keys(success))('%s', metohdName => { - success[metohdName].forEach(fixture => { - const formatted = paramsFmt[metohdName](fixture.source) - expect(formatted).toEqual(fixture.target) - }) - }) -}) - -describe('param formatter failure', () => { - test.each(Object.keys(failure))('%s', methodName => { - failure[methodName].forEach(fixture => { - expect(() => paramsFmt[methodName](fixture.source)).toThrowError(fixture.error) +describe('params formatter', () => { + describe.each(Object.keys(fixtures))('%s', methodName => { + const fixtureTable = Object.values(fixtures[methodName]).map(({ param, expected, exception }) => [ + param, + expected, + exception, + ]) + test.each(fixtureTable)('%j => %j', (param, expected, exception) => { + if (undefined !== expected) { + const formatted = paramsFmt[methodName](param) + expect(formatted).toEqual(expected) + } + if (undefined !== exception) { + expect(() => paramsFmt[methodName](param)).toThrow(new Error(exception)) + } }) }) }) diff --git a/packages/ckb-sdk-rpc/__tests__/formatters/result.fixtures.json b/packages/ckb-sdk-rpc/__tests__/formatters/result.fixtures.json new file mode 100644 index 00000000..9bcd8661 --- /dev/null +++ b/packages/ckb-sdk-rpc/__tests__/formatters/result.fixtures.json @@ -0,0 +1,1247 @@ +{ + "toNumber": [ + { + "result": "2", + "expected": "2" + } + ], + "toHash": [ + { + "result": "0xe5f2d07b747f38718293987a9175764d4c03229a8a69d0bd48f7bea6c18930b1", + "expected": "0xe5f2d07b747f38718293987a9175764d4c03229a8a69d0bd48f7bea6c18930b1" + } + ], + "toScript": [ + { + "result": null, + "expected": null + }, + { + "result": { + "args": [], + "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "hash_type": "data" + }, + "expected": { + "args": [], + "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "hashType": "data" + } + } + ], + "toInput": [ + { + "result": null, + "expected": null + }, + { + "result": { + "previous_output": { + "hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "index": "4294967295" + }, + "since": "0" + }, + "expected": { + "previousOutput": { + "hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "index": "4294967295" + }, + "since": "0" + } + } + ], + "toOutput": [ + { + "result": null, + "expected": null + }, + { + "result": { + "capacity": "5000000000000", + "lock": { + "args": [], + "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "hash_type": "data" + }, + "type": { + "args": [], + "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "hash_type": "type" + } + }, + "expected": { + "capacity": "5000000000000", + "lock": { + "args": [], + "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "hashType": "data" + }, + "type": { + "args": [], + "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "hashType": "type" + } + } + }, + { + "result": { + "capacity": "5000000000000", + "lock": { + "args": [], + "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "hash_type": "data" + }, + "type": null + }, + "expected": { + "capacity": "5000000000000", + "lock": { + "args": [], + "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "hashType": "data" + }, + "type": null + } + } + ], + "toOutPoint": [ + { + "result": null, + "expected": null + }, + { + "result": { + "tx_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "index": "4294967295" + }, + "expected": { + "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "index": "4294967295" + } + } + ], + "toCellDep": [ + { + "result": null, + "expected": null + }, + { + "result": { + "dep_type": "dep_group" + }, + "expected": { + "outPoint": null, + "depType": "depGroup" + } + }, + { + "result": { + "out_point": null + }, + "expected": { + "outPoint": null, + "depType": "code" + } + }, + { + "result": { + "out_point": null, + "dep_type": "code" + }, + "expected": { + "outPoint": null, + "depType": "code" + } + }, + { + "result": { + "out_point": { + "tx_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "index": "4294967295" + }, + "dep_type": "code" + }, + "expected": { + "outPoint": { + "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "index": "4294967295" + }, + "depType": "code" + } + } + ], + "toTransaction": [ + { + "result": null, + "expected": null + }, + { + "result": { + "cell_deps": [], + "header_deps": [], + "hash": "0x8027376875e45318ed469bed6314408e8f1986de246cbd03a786b69073c948b8", + "inputs": [ + { + "previous_output": { + "tx_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "index": "4294967295" + }, + "since": "0" + } + ], + "outputs": [ + { + "capacity": "5000000000000", + "lock": { + "args": [], + "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "hash_type": "data" + }, + "type": null + } + ], + "version": "0", + "witnesses": [], + "outputs_data": ["0x"] + }, + "expected": { + "cellDeps": [], + "headerDeps": [], + "hash": "0x8027376875e45318ed469bed6314408e8f1986de246cbd03a786b69073c948b8", + "inputs": [ + { + "previousOutput": { + "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "index": "4294967295" + }, + "since": "0" + } + ], + "outputs": [ + { + "capacity": "5000000000000", + + "lock": { + "args": [], + "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "hashType": "data" + }, + "type": null + } + ], + "version": "0", + "witnesses": [], + "outputsData": ["0x"] + } + }, + { + "result": { + "hash": "0x8027376875e45318ed469bed6314408e8f1986de246cbd03a786b69073c948b8", + "version": "0", + "witnesses": [] + }, + "expected": { + "cellDeps": [], + "headerDeps": [], + "hash": "0x8027376875e45318ed469bed6314408e8f1986de246cbd03a786b69073c948b8", + "inputs": [], + "outputs": [], + "version": "0", + "witnesses": [], + "outputsData": [] + } + } + ], + "toUncleBlock": [ + { + "result": null, + "expected": null + }, + { + "result": { + "header": { + "dao": "0x010000000000000063ae2493990ab00000f0c890408900000061eb7ada030000", + "difficulty": "0x3e8", + "epoch": "0", + "hash": "0x0a663a245ae0b3545a24e4ec06066b9e9f0bd32e5fdbb9038ec15af59ef2593d", + "number": "1024", + "parent_hash": "0x5eae6dfdac4b3099619a131975fd0be6da3c099eeaae8261182627a53548fc87", + "proposals_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0", + "timestamp": "1557311767", + "transactions_root": "0x64a872caca3c7b671b64897230e88dec8800b594347d192661908a87f7fbcb9b", + "uncles_count": "0", + "uncles_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "version": "0", + "witnesses_root": "0x688c1ff7df5b9b454bd76a031d40e13b4e462aeee5f8497d0f9f6f1dbd5d8111" + }, + "proposals": [] + }, + "expected": { + "header": { + "dao": "0x010000000000000063ae2493990ab00000f0c890408900000061eb7ada030000", + "difficulty": "0x3e8", + "epoch": "0", + "hash": "0x0a663a245ae0b3545a24e4ec06066b9e9f0bd32e5fdbb9038ec15af59ef2593d", + "number": "1024", + "parentHash": "0x5eae6dfdac4b3099619a131975fd0be6da3c099eeaae8261182627a53548fc87", + "proposalsHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0", + "timestamp": "1557311767", + "transactionsRoot": "0x64a872caca3c7b671b64897230e88dec8800b594347d192661908a87f7fbcb9b", + "unclesCount": "0", + "unclesHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "version": "0", + "witnessesRoot": "0x688c1ff7df5b9b454bd76a031d40e13b4e462aeee5f8497d0f9f6f1dbd5d8111" + }, + "proposals": [] + } + } + ], + "toBlock": [ + { + "result": null, + "expected": null + }, + { + "result": { + "header": { + "dao": "0x010000000000000063ae2493990ab00000f0c890408900000061eb7ada030000", + "difficulty": "0x3e8", + "epoch": "0", + "hash": "0x0a663a245ae0b3545a24e4ec06066b9e9f0bd32e5fdbb9038ec15af59ef2593d", + "number": "1024", + "parent_hash": "0x5eae6dfdac4b3099619a131975fd0be6da3c099eeaae8261182627a53548fc87", + "proposals_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0", + "timestamp": "1557311767", + "transactions_root": "0x64a872caca3c7b671b64897230e88dec8800b594347d192661908a87f7fbcb9b", + "uncles_count": "0", + "uncles_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "version": "0", + "witnesses_root": "0x688c1ff7df5b9b454bd76a031d40e13b4e462aeee5f8497d0f9f6f1dbd5d8111" + }, + "proposals": [], + "transactions": [ + { + "cell_deps": [], + "header_deps": [], + "hash": "0x8027376875e45318ed469bed6314408e8f1986de246cbd03a786b69073c948b8", + "inputs": [ + { + "previous_output": { + "tx_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "index": "4294967295" + }, + "since": "0" + } + ], + "outputs": [ + { + "capacity": "5000000000000", + + "lock": { + "args": [], + "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "hash_type": "data" + }, + "type": null + } + ], + "version": "0", + "witnesses": [], + "outputs_data": ["0x"] + } + ], + "uncles": [] + }, + "expected": { + "header": { + "dao": "0x010000000000000063ae2493990ab00000f0c890408900000061eb7ada030000", + "difficulty": "0x3e8", + "epoch": "0", + "hash": "0x0a663a245ae0b3545a24e4ec06066b9e9f0bd32e5fdbb9038ec15af59ef2593d", + "number": "1024", + "parentHash": "0x5eae6dfdac4b3099619a131975fd0be6da3c099eeaae8261182627a53548fc87", + "proposalsHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0", + "timestamp": "1557311767", + "transactionsRoot": "0x64a872caca3c7b671b64897230e88dec8800b594347d192661908a87f7fbcb9b", + "unclesCount": "0", + "unclesHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "version": "0", + "witnessesRoot": "0x688c1ff7df5b9b454bd76a031d40e13b4e462aeee5f8497d0f9f6f1dbd5d8111" + }, + "proposals": [], + "transactions": [ + { + "cellDeps": [], + "headerDeps": [], + "hash": "0x8027376875e45318ed469bed6314408e8f1986de246cbd03a786b69073c948b8", + "inputs": [ + { + "previousOutput": { + "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "index": "4294967295" + }, + "since": "0" + } + ], + "outputs": [ + { + "capacity": "5000000000000", + + "lock": { + "args": [], + "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "hashType": "data" + }, + "type": null + } + ], + "version": "0", + "witnesses": [], + "outputsData": ["0x"] + } + ], + "uncles": [] + } + }, + { + "result": { + "header": { + "dao": "0x010000000000000063ae2493990ab00000f0c890408900000061eb7ada030000", + "difficulty": "0x3e8", + "epoch": "0", + "hash": "0x0a663a245ae0b3545a24e4ec06066b9e9f0bd32e5fdbb9038ec15af59ef2593d", + "number": "1024", + "parent_hash": "0x5eae6dfdac4b3099619a131975fd0be6da3c099eeaae8261182627a53548fc87", + "proposals_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0", + "timestamp": "1557311767", + "transactions_root": "0x64a872caca3c7b671b64897230e88dec8800b594347d192661908a87f7fbcb9b", + "uncles_count": "0", + "uncles_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "version": "0", + "witnesses_root": "0x688c1ff7df5b9b454bd76a031d40e13b4e462aeee5f8497d0f9f6f1dbd5d8111" + }, + "proposals": [] + }, + "expected": { + "header": { + "dao": "0x010000000000000063ae2493990ab00000f0c890408900000061eb7ada030000", + "difficulty": "0x3e8", + "epoch": "0", + "hash": "0x0a663a245ae0b3545a24e4ec06066b9e9f0bd32e5fdbb9038ec15af59ef2593d", + "number": "1024", + "parentHash": "0x5eae6dfdac4b3099619a131975fd0be6da3c099eeaae8261182627a53548fc87", + "proposalsHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0", + "timestamp": "1557311767", + "transactionsRoot": "0x64a872caca3c7b671b64897230e88dec8800b594347d192661908a87f7fbcb9b", + "unclesCount": "0", + "unclesHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "version": "0", + "witnessesRoot": "0x688c1ff7df5b9b454bd76a031d40e13b4e462aeee5f8497d0f9f6f1dbd5d8111" + }, + "proposals": [], + "transactions": [], + "uncles": [] + } + } + ], + "toAlertMessage": [ + { + "result": null, + "expected": null + }, + { + "result": { + "id": "1111", + "priority": "1111", + "notice_until": "1557287480008", + "message": "alert message" + }, + "expected": { + "id": "1111", + "priority": "1111", + "noticeUntil": "1557287480008", + "message": "alert message" + } + } + ], + "toBlockchainInfo": [ + { + "result": null, + "expected": null + }, + { + "result": { + "is_initial_block_download": false, + "epoch": "0", + "difficulty": "0x100", + "median_time": "1557287480008", + "chain": "ckb_dev", + "alerts": [] + }, + "expected": { + "isInitialBlockDownload": false, + "epoch": "0", + "difficulty": "0x100", + "medianTime": "1557287480008", + "chain": "ckb_dev", + "alerts": [] + } + } + ], + "toNodeInfo": [ + { + "result": null, + "expected": null + }, + { + "result": { + "addresses": [ + { + "address": "/ip4/192.168.0.2/tcp/8112/p2p/QmTRHCdrRtgUzYLNCin69zEvPvLYdxUZLLfLYyHVY3DZAS", + "score": "255" + }, + { + "address": "/ip4/0.0.0.0/tcp/8112/p2p/QmTRHCdrRtgUzYLNCin69zEvPvLYdxUZLLfLYyHVY3DZAS", + "score": "1" + } + ], + "is_outbound": null, + "node_id": "QmTRHCdrRtgUzYLNCin69zEvPvLYdxUZLLfLYyHVY3DZAS", + "version": "0.9.0" + }, + "expected": { + "addresses": [ + { + "address": "/ip4/192.168.0.2/tcp/8112/p2p/QmTRHCdrRtgUzYLNCin69zEvPvLYdxUZLLfLYyHVY3DZAS", + "score": "255" + }, + { + "address": "/ip4/0.0.0.0/tcp/8112/p2p/QmTRHCdrRtgUzYLNCin69zEvPvLYdxUZLLfLYyHVY3DZAS", + "score": "1" + } + ], + "isOutbound": null, + "nodeId": "QmTRHCdrRtgUzYLNCin69zEvPvLYdxUZLLfLYyHVY3DZAS", + "version": "0.9.0" + } + } + ], + "toTxPoolInfo": [ + { + "result": null, + "expected": null + }, + { + "result": { + "orphan": "33", + "pending": "34", + "proposed": "22", + "last_txs_updated_at": "1555507787683", + "total_tx_cycles": "12", + "total_tx_size": "156" + }, + "expected": { + "orphan": "33", + "pending": "34", + "proposed": "22", + "lastTxsUpdatedAt": "1555507787683", + "totalTxCycles": "12", + "totalTxSize": "156" + } + } + ], + "toPeers": [ + { + "result": null, + "expected": [] + }, + { + "result": [ + { + "addresses": [ + { + "address": "/ip4/192.168.0.3/tcp/8115", + "score": "1" + } + ], + "node_id": "QmaaaLB4uPyDpZwTQGhV63zuYrKm4reyN2tF1j2ain4oE7", + "version": "unknown" + }, + { + "addresses": [ + { + "address": "/ip4/192.168.0.4/tcp/8113", + "score": "255" + } + ], + "node_id": "QmRuGcpVC3vE7aEoB6fhUdq9uzdHbyweCnn1sDBSjfmcbM", + "version": "unknown" + }, + { + "addresses": [], + "node_id": "QmUddxwRqgTmT6tFujXbYPMLGLAE2Tciyv6uHGfdYFyDVa", + "version": "unknown" + } + ], + "expected": [ + { + "addresses": [ + { + "address": "/ip4/192.168.0.3/tcp/8115", + "score": "1" + } + ], + "nodeId": "QmaaaLB4uPyDpZwTQGhV63zuYrKm4reyN2tF1j2ain4oE7", + "version": "unknown" + }, + { + "addresses": [ + { + "address": "/ip4/192.168.0.4/tcp/8113", + "score": "255" + } + ], + "nodeId": "QmRuGcpVC3vE7aEoB6fhUdq9uzdHbyweCnn1sDBSjfmcbM", + "version": "unknown" + }, + { + "addresses": [], + "nodeId": "QmUddxwRqgTmT6tFujXbYPMLGLAE2Tciyv6uHGfdYFyDVa", + "version": "unknown" + } + ] + } + ], + "toPeersState": [ + { + "result": null, + "expected": null + }, + { + "result": { + "last_updated": "1557289448237", + "blocks_in_flight": "86", + "peer": "1" + }, + "expected": { + "lastUpdated": "1557289448237", + "blocksInFlight": "86", + "peer": "1" + } + } + ], + "toDepType": [ + { + "result": "dep_group", + "expected": "depGroup" + }, + { + "result": "code", + "expected": "code" + } + ], + "toCell": [ + { + "result": null, + "expected": null + }, + { + "result": { + "capacity": "5000000000000", + "lock": { + "args": [], + "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "hash_type": "data" + }, + "type": { + "args": [], + "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "hash_type": "type" + } + }, + "expected": { + "capacity": "5000000000000", + "lock": { + "args": [], + "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "hashType": "data" + }, + "type": { + "args": [], + "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "hashType": "type" + } + } + } + ], + "toLiveCell": [ + { + "result": null, + "expected": null + }, + { + "result": { + "data": { + "content": "0x7f454c460201010000000000000000000200f3000100000078000100000000004000000000000000980000000000000005000000400038000100400003000200010000000500000000000000000000000000010000000000000001000000000082000000000000008200000000000000001000000000000001459308d00573000000002e7368737472746162002e74657874000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b000000010000000600000000000000780001000000000078000000000000000a0000000000000000000000000000000200000000000000000000000000000001000000030000000000000000000000000000000000000082000000000000001100000000000000000000000000000001000000000000000000000000000000", + "hash": "0x28e83a1277d48add8e72fadaa9248559e1b632bab2bd60b27955ebc4c03800a5" + }, + "output": { + "capacity": "0x802665800", + "lock": { + "args": [], + "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "hash_type": "data" + }, + "type": null + } + }, + "expected": { + "data": { + "content": "0x7f454c460201010000000000000000000200f3000100000078000100000000004000000000000000980000000000000005000000400038000100400003000200010000000500000000000000000000000000010000000000000001000000000082000000000000008200000000000000001000000000000001459308d00573000000002e7368737472746162002e74657874000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b000000010000000600000000000000780001000000000078000000000000000a0000000000000000000000000000000200000000000000000000000000000001000000030000000000000000000000000000000000000082000000000000001100000000000000000000000000000001000000000000000000000000000000", + "hash": "0x28e83a1277d48add8e72fadaa9248559e1b632bab2bd60b27955ebc4c03800a5" + }, + "output": { + "capacity": "0x802665800", + "lock": { + "args": [], + "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "hashType": "data" + }, + "type": null + } + } + } + ], + "toLiveCellWithStatus": [ + { + "result": null, + "expected": null + }, + { + "result": { + "cell": { + "data": { + "content": "0x7f454c460201010000000000000000000200f3000100000078000100000000004000000000000000980000000000000005000000400038000100400003000200010000000500000000000000000000000000010000000000000001000000000082000000000000008200000000000000001000000000000001459308d00573000000002e7368737472746162002e74657874000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b000000010000000600000000000000780001000000000078000000000000000a0000000000000000000000000000000200000000000000000000000000000001000000030000000000000000000000000000000000000082000000000000001100000000000000000000000000000001000000000000000000000000000000", + "hash": "0x28e83a1277d48add8e72fadaa9248559e1b632bab2bd60b27955ebc4c03800a5" + }, + "output": { + "capacity": "0x802665800", + "lock": { + "args": [], + "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "hash_type": "data" + }, + "type": null + } + }, + "status": "live" + }, + "expected": { + "cell": { + "data": { + "content": "0x7f454c460201010000000000000000000200f3000100000078000100000000004000000000000000980000000000000005000000400038000100400003000200010000000500000000000000000000000000010000000000000001000000000082000000000000008200000000000000001000000000000001459308d00573000000002e7368737472746162002e74657874000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b000000010000000600000000000000780001000000000078000000000000000a0000000000000000000000000000000200000000000000000000000000000001000000030000000000000000000000000000000000000082000000000000001100000000000000000000000000000001000000000000000000000000000000", + "hash": "0x28e83a1277d48add8e72fadaa9248559e1b632bab2bd60b27955ebc4c03800a5" + }, + "output": { + "capacity": "0x802665800", + "lock": { + "args": [], + "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "hashType": "data" + }, + "type": null + } + }, + "status": "live" + } + } + ], + "toCellIncludingOutPoint": [ + { + "result": null, + "expected": null + }, + { + "result": { + "lock": { + "code_hash": "0x9e3b3557f11b2b3532ce352bfe8017e9fd11d154c4c7f9b7aaaa1e621b539a08", + "args": ["0x7f52f0fccdd1d11391c441adfb174f87bca612b0"], + "hash_type": "data" + }, + "type": null, + "capacity": "5000000000000", + "out_point": { + "index": "0", + "tx_hash": "0xecd3917b7d9833a34d30da39b943b1811163f30771aae3165f60529955afb37f" + } + }, + "expected": { + "lock": { + "codeHash": "0x9e3b3557f11b2b3532ce352bfe8017e9fd11d154c4c7f9b7aaaa1e621b539a08", + "args": ["0x7f52f0fccdd1d11391c441adfb174f87bca612b0"], + "hashType": "data" + }, + "type": null, + "capacity": "5000000000000", + "outPoint": { + "index": "0", + "txHash": "0xecd3917b7d9833a34d30da39b943b1811163f30771aae3165f60529955afb37f" + } + } + } + ], + "toCells": [ + { + "result": null, + "expected": [] + }, + { + "result": [ + { + "capacity": "5000000000000", + + "lock": { + "args": [], + "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "hash_type": "data" + }, + "type": null + } + ], + "expected": [ + { + "capacity": "5000000000000", + + "lock": { + "args": [], + "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "hashType": "data" + }, + "type": null + } + ] + } + ], + "toCellsIncludingOutPoint": [ + { + "result": null, + "expected": [] + }, + { + "result": [ + { + "lock": { + "codeHash": "0x9e3b3557f11b2b3532ce352bfe8017e9fd11d154c4c7f9b7aaaa1e621b539a08", + "args": ["0x7f52f0fccdd1d11391c441adfb174f87bca612b0"], + "hashType": "data" + }, + "type": null, + "capacity": "5000000000000", + "out_point": { + "index": "0", + "tx_hash": "0xecd3917b7d9833a34d30da39b943b1811163f30771aae3165f60529955afb37f" + } + } + ], + "expected": [ + { + "lock": { + "codeHash": "0x9e3b3557f11b2b3532ce352bfe8017e9fd11d154c4c7f9b7aaaa1e621b539a08", + "args": ["0x7f52f0fccdd1d11391c441adfb174f87bca612b0"], + "hashType": "data" + }, + "type": null, + "capacity": "5000000000000", + "outPoint": { + "index": "0", + "txHash": "0xecd3917b7d9833a34d30da39b943b1811163f30771aae3165f60529955afb37f" + } + } + ] + } + ], + "toHeader": [ + { + "result": null, + "expected": null + }, + { + "result": { + "dao": "0x01000000000000000000c16ff286230000203d88792d0000000961f400000000", + "difficulty": "0x3e8", + "epoch": "0", + "hash": "0xba0d878d2c3711d38b5ddc2bc917312ca3898cad98457cc7960e28ec31f26e7f", + "number": "1024", + "parent_hash": "0x3533d5f0882a60d3b25b7dd57002a5d9eb591e89a98231e8abc5bf48f7ee0592", + "proposals_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0", + "timestamp": "1557311767", + "transactions_root": "0x81389ffabda2d1658c75a81e390a82b335d4cb849b2269d134b042fea9cb9513", + "uncles_count": "0", + "uncles_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "version": "0", + "witnesses_root": "0xb36423f72fd5cdbf6297c189b9d74e970bf0b971a537f41b8334088afe27900a" + }, + "expected": { + "dao": "0x01000000000000000000c16ff286230000203d88792d0000000961f400000000", + "difficulty": "0x3e8", + "epoch": "0", + "hash": "0xba0d878d2c3711d38b5ddc2bc917312ca3898cad98457cc7960e28ec31f26e7f", + "number": "1024", + "parentHash": "0x3533d5f0882a60d3b25b7dd57002a5d9eb591e89a98231e8abc5bf48f7ee0592", + "proposalsHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0", + "timestamp": "1557311767", + "transactionsRoot": "0x81389ffabda2d1658c75a81e390a82b335d4cb849b2269d134b042fea9cb9513", + "unclesCount": "0", + "unclesHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "version": "0", + "witnessesRoot": "0xb36423f72fd5cdbf6297c189b9d74e970bf0b971a537f41b8334088afe27900a" + } + } + ], + "toTransactionWithStatus": [ + { + "result": null, + "expected": null + }, + { + "result": { + "transaction": { + "cell_deps": [], + "header_deps": [], + "hash": "0x8027376875e45318ed469bed6314408e8f1986de246cbd03a786b69073c948b8", + "inputs": [ + { + "previous_output": { + "tx_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "index": "4294967295" + }, + "since": "0" + } + ], + "outputs": [ + { + "capacity": "5000000000000", + "lock": { + "args": [], + "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "hash_type": "data" + }, + "type": null + } + ], + "version": "0", + "witnesses": [], + "outputs_data": ["0x"] + }, + "tx_status": { + "status": "committed", + "block_hash": "0xef285e5da29247ce39385cbd8dc36535f7ea1b5b0379db26e9d459a8b47d0d71" + } + }, + "expected": { + "transaction": { + "cellDeps": [], + "headerDeps": [], + "hash": "0x8027376875e45318ed469bed6314408e8f1986de246cbd03a786b69073c948b8", + "inputs": [ + { + "previousOutput": { + "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "index": "4294967295" + }, + "since": "0" + } + ], + "outputs": [ + { + "capacity": "5000000000000", + "lock": { + "args": [], + "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "hashType": "data" + }, + "type": null + } + ], + "version": "0", + "witnesses": [], + "outputsData": ["0x"] + }, + "txStatus": { + "status": "committed", + "blockHash": "0xef285e5da29247ce39385cbd8dc36535f7ea1b5b0379db26e9d459a8b47d0d71" + } + } + } + ], + "toEpoch": [ + { + "result": null, + "expected": null + }, + { + "result": { + "difficulty": "0x100", + "length": "1000", + "number": "0", + "start_number": "0" + }, + "expected": { + "difficulty": "0x100", + "length": "1000", + "number": "0", + "startNumber": "0" + } + } + ], + "toTransactionPoint": [ + { + "result": null, + "expected": null + }, + { + "result": { + "block_number": "1", + "index": "0", + "tx_hash": "0x41524669872de0ce874f926a9799b6944198571094fe94dc7ffa623a97c4f19f" + }, + "expected": { + "blockNumber": "1", + "index": "0", + "txHash": "0x41524669872de0ce874f926a9799b6944198571094fe94dc7ffa623a97c4f19f" + } + } + ], + "toTransactionsByLockHash": [ + { + "result": null, + "expected": null + }, + { + "result": [ + { + "consumed_by": null, + "created_by": { + "block_number": "1", + "index": "0", + "tx_hash": "0x41524669872de0ce874f926a9799b6944198571094fe94dc7ffa623a97c4f19f" + } + }, + { + "consumed_by": null, + "created_by": { + "block_number": "2", + "index": "0", + "tx_hash": "0x46ab01ddbbabef1af701f0843e11c7cfc0ce53f9aa9b554af74cadf8e3257d89" + } + } + ], + "expected": [ + { + "consumedBy": null, + "createdBy": { + "blockNumber": "1", + "index": "0", + "txHash": "0x41524669872de0ce874f926a9799b6944198571094fe94dc7ffa623a97c4f19f" + } + }, + { + "consumedBy": null, + "createdBy": { + "blockNumber": "2", + "index": "0", + "txHash": "0x46ab01ddbbabef1af701f0843e11c7cfc0ce53f9aa9b554af74cadf8e3257d89" + } + } + ] + } + ], + "toLiveCellsByLockHash": [ + { + "result": null, + "expected": null + }, + { + "result": [ + { + "cell_output": { + "capacity": "50000000000000", + "lock": { + "args": [], + "code_hash": "0x28e83a1277d48add8e72fadaa9248559e1b632bab2bd60b27955ebc4c03800a5" + }, + "type": null + }, + "created_by": { + "block_number": "1", + "index": "0", + "tx_hash": "0x41524669872de0ce874f926a9799b6944198571094fe94dc7ffa623a97c4f19f" + } + }, + { + "cell_output": { + "capacity": "50000000000000", + "lock": { + "args": [], + "code_hash": "0x28e83a1277d48add8e72fadaa9248559e1b632bab2bd60b27955ebc4c03800a5" + }, + "type": null + }, + "created_by": { + "block_number": "2", + "index": "0", + "tx_hash": "0x46ab01ddbbabef1af701f0843e11c7cfc0ce53f9aa9b554af74cadf8e3257d89" + } + } + ], + "expected": [ + { + "cellOutput": { + "capacity": "50000000000000", + "lock": { + "args": [], + "codeHash": "0x28e83a1277d48add8e72fadaa9248559e1b632bab2bd60b27955ebc4c03800a5" + }, + "type": null + }, + "createdBy": { + "blockNumber": "1", + "index": "0", + "txHash": "0x41524669872de0ce874f926a9799b6944198571094fe94dc7ffa623a97c4f19f" + } + }, + { + "cellOutput": { + "capacity": "50000000000000", + + "lock": { + "args": [], + "codeHash": "0x28e83a1277d48add8e72fadaa9248559e1b632bab2bd60b27955ebc4c03800a5" + }, + "type": null + }, + "createdBy": { + "blockNumber": "2", + "index": "0", + "txHash": "0x46ab01ddbbabef1af701f0843e11c7cfc0ce53f9aa9b554af74cadf8e3257d89" + } + } + ] + } + ], + "toLockHashIndexState": [ + { + "result": null, + "expected": null + }, + { + "result": { + "block_hash": "0xf35168c2e2e0c494ec97233091d5de51b7e5af7376bbc3d7572fc6438e2bb032", + "block_number": "1024", + "lock_hash": "0x9a9a6bdbc38d4905eace1822f85237e3a1e238bb3f277aa7b7c8903441123510" + }, + "expected": { + "blockHash": "0xf35168c2e2e0c494ec97233091d5de51b7e5af7376bbc3d7572fc6438e2bb032", + "blockNumber": "1024", + "lockHash": "0x9a9a6bdbc38d4905eace1822f85237e3a1e238bb3f277aa7b7c8903441123510" + } + } + ], + "toLockHashIndexStates": [ + { + "result": null, + "expected": null + }, + { + "result": [ + { + "block_hash": "0xf35168c2e2e0c494ec97233091d5de51b7e5af7376bbc3d7572fc6438e2bb032", + "block_number": "1024", + "lock_hash": "0x9a9a6bdbc38d4905eace1822f85237e3a1e238bb3f277aa7b7c8903441123510" + } + ], + "expected": [ + { + "blockHash": "0xf35168c2e2e0c494ec97233091d5de51b7e5af7376bbc3d7572fc6438e2bb032", + "blockNumber": "1024", + "lockHash": "0x9a9a6bdbc38d4905eace1822f85237e3a1e238bb3f277aa7b7c8903441123510" + } + ] + } + ], + "toBannedAddress": [ + { + "result": null, + "expected": null + }, + { + "result": { + "address": "192.168.0.2/32", + "ban_reason": "", + "ban_until": "1840546800000", + "created_at": "1562803123000" + }, + "expected": { + "address": "192.168.0.2/32", + "banReason": "", + "banUntil": "1840546800000", + "createdAt": "1562803123000" + } + } + ], + "toBannedAddresses": [ + { + "result": null, + "expected": null + }, + { + "result": [ + { + "address": "192.168.0.2/32", + "ban_reason": "", + "ban_until": "1840546800000", + "created_at": "1562803123000" + } + ], + "expected": [ + { + "address": "192.168.0.2/32", + "banReason": "", + "banUntil": "1840546800000", + "createdAt": "1562803123000" + } + ] + } + ], + "toCellbaseOutputCapacityDetails": [ + { + "result": null, + "expected": null + }, + { + "result": { + "primary": "100000000000", + "proposal_reward": "0", + "secondary": "1346505683", + "total": "101346505683", + "tx_fee": "0" + }, + "expected": { + "primary": "100000000000", + "proposalReward": "0", + "secondary": "1346505683", + "total": "101346505683", + "txFee": "0" + } + } + ] +} diff --git a/packages/ckb-sdk-rpc/__tests__/formatters/result.json b/packages/ckb-sdk-rpc/__tests__/formatters/result.json deleted file mode 100644 index b71e9452..00000000 --- a/packages/ckb-sdk-rpc/__tests__/formatters/result.json +++ /dev/null @@ -1,1200 +0,0 @@ -{ - "success": { - "toNumber": [ - { - "source": "2", - "target": "2" - } - ], - "toHash": [ - { - "source": "0xe5f2d07b747f38718293987a9175764d4c03229a8a69d0bd48f7bea6c18930b1", - "target": "0xe5f2d07b747f38718293987a9175764d4c03229a8a69d0bd48f7bea6c18930b1" - } - ], - "toScript": [ - { - "source": null, - "target": null - }, - { - "source": { - "args": [], - "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", - "hash_type": "data" - }, - "target": { - "args": [], - "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", - "hashType": "data" - } - } - ], - "toInput": [ - { - "source": null, - "target": null - }, - { - "source": { - "previous_output": { - "hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" - }, - "since": "0" - }, - "target": { - "previousOutput": { - "hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" - }, - "since": "0" - } - } - ], - "toOutput": [ - { - "source": null, - "target": null - }, - { - "source": { - "capacity": "5000000000000", - "lock": { - "args": [], - "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", - "hash_type": "data" - }, - "type": { - "args": [], - "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", - "hash_type": "type" - } - }, - "target": { - "capacity": "5000000000000", - "lock": { - "args": [], - "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", - "hashType": "data" - }, - "type": { - "args": [], - "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", - "hashType": "type" - } - } - }, - { - "source": { - "capacity": "5000000000000", - "lock": { - "args": [], - "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", - "hash_type": "data" - }, - "type": null - }, - "target": { - "capacity": "5000000000000", - "lock": { - "args": [], - "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", - "hashType": "data" - }, - "type": null - } - } - ], - "toOutPoint": [ - { - "source": null, - "target": null - }, - { - "source": { - "tx_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" - }, - "target": { - "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" - } - } - ], - "toCellDep": [ - { - "source": null, - "target": null - }, - { - "source": { - "dep_type": "dep_group" - }, - "target": { - "outPoint": null, - "depType": "depGroup" - } - }, - { - "source": { - "out_point": null - }, - "target": { - "outPoint": null, - "depType": "code" - } - }, - { - "source": { - "out_point": null, - "dep_type": "code" - }, - "target": { - "outPoint": null, - "depType": "code" - } - }, - { - "source": { - "out_point": { - "tx_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" - }, - "dep_type": "code" - }, - "target": { - "outPoint": { - "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" - }, - "depType": "code" - } - } - ], - "toTransaction": [ - { - "source": null, - "target": null - }, - { - "source": { - "cell_deps": [], - "header_deps": [], - "hash": "0x8027376875e45318ed469bed6314408e8f1986de246cbd03a786b69073c948b8", - "inputs": [ - { - "previous_output": { - "tx_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" - }, - "since": "0" - } - ], - "outputs": [ - { - "capacity": "5000000000000", - "lock": { - "args": [], - "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", - "hash_type": "data" - }, - "type": null - } - ], - "version": "0", - "witnesses": [], - "outputs_data": ["0x"] - }, - "target": { - "cellDeps": [], - "headerDeps": [], - "hash": "0x8027376875e45318ed469bed6314408e8f1986de246cbd03a786b69073c948b8", - "inputs": [ - { - "previousOutput": { - "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" - }, - "since": "0" - } - ], - "outputs": [ - { - "capacity": "5000000000000", - - "lock": { - "args": [], - "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", - "hashType": "data" - }, - "type": null - } - ], - "version": "0", - "witnesses": [], - "outputsData": ["0x"] - } - }, - { - "source": { - "hash": "0x8027376875e45318ed469bed6314408e8f1986de246cbd03a786b69073c948b8", - "version": "0", - "witnesses": [] - }, - "target": { - "cellDeps": [], - "headerDeps": [], - "hash": "0x8027376875e45318ed469bed6314408e8f1986de246cbd03a786b69073c948b8", - "inputs": [], - "outputs": [], - "version": "0", - "witnesses": [], - "outputsData": [] - } - } - ], - "toUncleBlock": [ - { - "source": null, - "target": null - }, - { - "source": { - "header": { - "dao": "0x010000000000000063ae2493990ab00000f0c890408900000061eb7ada030000", - "difficulty": "0x3e8", - "epoch": "0", - "hash": "0x0a663a245ae0b3545a24e4ec06066b9e9f0bd32e5fdbb9038ec15af59ef2593d", - "number": "1024", - "parent_hash": "0x5eae6dfdac4b3099619a131975fd0be6da3c099eeaae8261182627a53548fc87", - "proposals_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "nonce": "0", - "timestamp": "1557311767", - "transactions_root": "0x64a872caca3c7b671b64897230e88dec8800b594347d192661908a87f7fbcb9b", - "uncles_count": "0", - "uncles_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "version": "0", - "witnesses_root": "0x688c1ff7df5b9b454bd76a031d40e13b4e462aeee5f8497d0f9f6f1dbd5d8111" - }, - "proposals": [] - }, - "target": { - "header": { - "dao": "0x010000000000000063ae2493990ab00000f0c890408900000061eb7ada030000", - "difficulty": "0x3e8", - "epoch": "0", - "hash": "0x0a663a245ae0b3545a24e4ec06066b9e9f0bd32e5fdbb9038ec15af59ef2593d", - "number": "1024", - "parentHash": "0x5eae6dfdac4b3099619a131975fd0be6da3c099eeaae8261182627a53548fc87", - "proposalsHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "nonce": "0", - "timestamp": "1557311767", - "transactionsRoot": "0x64a872caca3c7b671b64897230e88dec8800b594347d192661908a87f7fbcb9b", - "unclesCount": "0", - "unclesHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "version": "0", - "witnessesRoot": "0x688c1ff7df5b9b454bd76a031d40e13b4e462aeee5f8497d0f9f6f1dbd5d8111" - }, - "proposals": [] - } - } - ], - "toBlock": [ - { - "source": null, - "target": null - }, - { - "source": { - "header": { - "dao": "0x010000000000000063ae2493990ab00000f0c890408900000061eb7ada030000", - "difficulty": "0x3e8", - "epoch": "0", - "hash": "0x0a663a245ae0b3545a24e4ec06066b9e9f0bd32e5fdbb9038ec15af59ef2593d", - "number": "1024", - "parent_hash": "0x5eae6dfdac4b3099619a131975fd0be6da3c099eeaae8261182627a53548fc87", - "proposals_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "nonce": "0", - "timestamp": "1557311767", - "transactions_root": "0x64a872caca3c7b671b64897230e88dec8800b594347d192661908a87f7fbcb9b", - "uncles_count": "0", - "uncles_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "version": "0", - "witnesses_root": "0x688c1ff7df5b9b454bd76a031d40e13b4e462aeee5f8497d0f9f6f1dbd5d8111" - }, - "proposals": [], - "transactions": [ - { - "cell_deps": [], - "header_deps": [], - "hash": "0x8027376875e45318ed469bed6314408e8f1986de246cbd03a786b69073c948b8", - "inputs": [ - { - "previous_output": { - "tx_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" - }, - "since": "0" - } - ], - "outputs": [ - { - "capacity": "5000000000000", - - "lock": { - "args": [], - "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", - "hash_type": "data" - }, - "type": null - } - ], - "version": "0", - "witnesses": [], - "outputs_data": ["0x"] - } - ], - "uncles": [] - }, - "target": { - "header": { - "dao": "0x010000000000000063ae2493990ab00000f0c890408900000061eb7ada030000", - "difficulty": "0x3e8", - "epoch": "0", - "hash": "0x0a663a245ae0b3545a24e4ec06066b9e9f0bd32e5fdbb9038ec15af59ef2593d", - "number": "1024", - "parentHash": "0x5eae6dfdac4b3099619a131975fd0be6da3c099eeaae8261182627a53548fc87", - "proposalsHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "nonce": "0", - "timestamp": "1557311767", - "transactionsRoot": "0x64a872caca3c7b671b64897230e88dec8800b594347d192661908a87f7fbcb9b", - "unclesCount": "0", - "unclesHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "version": "0", - "witnessesRoot": "0x688c1ff7df5b9b454bd76a031d40e13b4e462aeee5f8497d0f9f6f1dbd5d8111" - }, - "proposals": [], - "transactions": [ - { - "cellDeps": [], - "headerDeps": [], - "hash": "0x8027376875e45318ed469bed6314408e8f1986de246cbd03a786b69073c948b8", - "inputs": [ - { - "previousOutput": { - "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" - }, - "since": "0" - } - ], - "outputs": [ - { - "capacity": "5000000000000", - - "lock": { - "args": [], - "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", - "hashType": "data" - }, - "type": null - } - ], - "version": "0", - "witnesses": [], - "outputsData": ["0x"] - } - ], - "uncles": [] - } - }, - { - "source": { - "header": { - "dao": "0x010000000000000063ae2493990ab00000f0c890408900000061eb7ada030000", - "difficulty": "0x3e8", - "epoch": "0", - "hash": "0x0a663a245ae0b3545a24e4ec06066b9e9f0bd32e5fdbb9038ec15af59ef2593d", - "number": "1024", - "parent_hash": "0x5eae6dfdac4b3099619a131975fd0be6da3c099eeaae8261182627a53548fc87", - "proposals_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "nonce": "0", - "timestamp": "1557311767", - "transactions_root": "0x64a872caca3c7b671b64897230e88dec8800b594347d192661908a87f7fbcb9b", - "uncles_count": "0", - "uncles_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "version": "0", - "witnesses_root": "0x688c1ff7df5b9b454bd76a031d40e13b4e462aeee5f8497d0f9f6f1dbd5d8111" - }, - "proposals": [] - }, - "target": { - "header": { - "dao": "0x010000000000000063ae2493990ab00000f0c890408900000061eb7ada030000", - "difficulty": "0x3e8", - "epoch": "0", - "hash": "0x0a663a245ae0b3545a24e4ec06066b9e9f0bd32e5fdbb9038ec15af59ef2593d", - "number": "1024", - "parentHash": "0x5eae6dfdac4b3099619a131975fd0be6da3c099eeaae8261182627a53548fc87", - "proposalsHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "nonce": "0", - "timestamp": "1557311767", - "transactionsRoot": "0x64a872caca3c7b671b64897230e88dec8800b594347d192661908a87f7fbcb9b", - "unclesCount": "0", - "unclesHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "version": "0", - "witnessesRoot": "0x688c1ff7df5b9b454bd76a031d40e13b4e462aeee5f8497d0f9f6f1dbd5d8111" - }, - "proposals": [], - "transactions": [], - "uncles": [] - } - } - ], - "toAlertMessage": [ - { - "source": null, - "target": null - }, - { - "source": { - "id": "1111", - "priority": "1111", - "notice_until": "1557287480008", - "message": "alert message" - }, - "target": { - "id": "1111", - "priority": "1111", - "noticeUntil": "1557287480008", - "message": "alert message" - } - } - ], - "toBlockchainInfo": [ - { - "source": null, - "target": null - }, - { - "source": { - "is_initial_block_download": false, - "epoch": "0", - "difficulty": "0x100", - "median_time": "1557287480008", - "chain": "ckb_dev", - "alerts": [] - }, - "target": { - "isInitialBlockDownload": false, - "epoch": "0", - "difficulty": "0x100", - "medianTime": "1557287480008", - "chain": "ckb_dev", - "alerts": [] - } - } - ], - "toNodeInfo": [ - { - "source": null, - "target": null - }, - { - "source": { - "addresses": [ - { - "address": "/ip4/192.168.0.2/tcp/8112/p2p/QmTRHCdrRtgUzYLNCin69zEvPvLYdxUZLLfLYyHVY3DZAS", - "score": "255" - }, - { - "address": "/ip4/0.0.0.0/tcp/8112/p2p/QmTRHCdrRtgUzYLNCin69zEvPvLYdxUZLLfLYyHVY3DZAS", - "score": "1" - } - ], - "is_outbound": null, - "node_id": "QmTRHCdrRtgUzYLNCin69zEvPvLYdxUZLLfLYyHVY3DZAS", - "version": "0.9.0" - }, - "target": { - "addresses": [ - { - "address": "/ip4/192.168.0.2/tcp/8112/p2p/QmTRHCdrRtgUzYLNCin69zEvPvLYdxUZLLfLYyHVY3DZAS", - "score": "255" - }, - { - "address": "/ip4/0.0.0.0/tcp/8112/p2p/QmTRHCdrRtgUzYLNCin69zEvPvLYdxUZLLfLYyHVY3DZAS", - "score": "1" - } - ], - "isOutbound": null, - "nodeId": "QmTRHCdrRtgUzYLNCin69zEvPvLYdxUZLLfLYyHVY3DZAS", - "version": "0.9.0" - } - } - ], - "toTxPoolInfo": [ - { - "source": null, - "target": null - }, - { - "source": { - "orphan": "33", - "pending": "34", - "proposed": "22", - "last_txs_updated_at": "1555507787683", - "total_tx_cycles": "12", - "total_tx_size": "156" - }, - "target": { - "orphan": "33", - "pending": "34", - "proposed": "22", - "lastTxsUpdatedAt": "1555507787683", - "totalTxCycles": "12", - "totalTxSize": "156" - } - } - ], - "toPeers": [ - { - "source": null, - "target": [] - }, - { - "source": [ - { - "addresses": [ - { - "address": "/ip4/192.168.0.3/tcp/8115", - "score": "1" - } - ], - "node_id": "QmaaaLB4uPyDpZwTQGhV63zuYrKm4reyN2tF1j2ain4oE7", - "version": "unknown" - }, - { - "addresses": [ - { - "address": "/ip4/192.168.0.4/tcp/8113", - "score": "255" - } - ], - "node_id": "QmRuGcpVC3vE7aEoB6fhUdq9uzdHbyweCnn1sDBSjfmcbM", - "version": "unknown" - }, - { - "addresses": [], - "node_id": "QmUddxwRqgTmT6tFujXbYPMLGLAE2Tciyv6uHGfdYFyDVa", - "version": "unknown" - } - ], - "target": [ - { - "addresses": [ - { - "address": "/ip4/192.168.0.3/tcp/8115", - "score": "1" - } - ], - "nodeId": "QmaaaLB4uPyDpZwTQGhV63zuYrKm4reyN2tF1j2ain4oE7", - "version": "unknown" - }, - { - "addresses": [ - { - "address": "/ip4/192.168.0.4/tcp/8113", - "score": "255" - } - ], - "nodeId": "QmRuGcpVC3vE7aEoB6fhUdq9uzdHbyweCnn1sDBSjfmcbM", - "version": "unknown" - }, - { - "addresses": [], - "nodeId": "QmUddxwRqgTmT6tFujXbYPMLGLAE2Tciyv6uHGfdYFyDVa", - "version": "unknown" - } - ] - } - ], - "toPeersState": [ - { - "source": null, - "target": null - }, - { - "source": { - "last_updated": "1557289448237", - "blocks_in_flight": "86", - "peer": "1" - }, - "target": { - "lastUpdated": "1557289448237", - "blocksInFlight": "86", - "peer": "1" - } - } - ], - "toDepType": [ - { - "source": "dep_group", - "target": "depGroup" - }, - { - "source": "code", - "target": "code" - } - ], - "toCell": [ - { - "source": null, - "target": null - }, - { - "source": { - "capacity": "5000000000000", - "lock": { - "args": [], - "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", - "hash_type": "data" - }, - "type": { - "args": [], - "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", - "hash_type": "type" - } - }, - "target": { - "capacity": "5000000000000", - "lock": { - "args": [], - "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", - "hashType": "data" - }, - "type": { - "args": [], - "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", - "hashType": "type" - } - } - } - ], - "toCellWithStatus": [ - { - "source": null, - "target": null - }, - { - "source": { - "cell": { - "capacity": "5000000000000", - "lock": { - "args": [], - "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", - "hash_type": "data" - }, - "type": null - }, - "status": "live" - }, - "target": { - "cell": { - "capacity": "5000000000000", - "lock": { - "args": [], - "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", - "hashType": "data" - }, - "type": null - }, - "status": "live" - } - } - ], - "toCellIncludingOutPoint": [ - { - "source": null, - "target": null - }, - { - "source": { - "lock": { - "code_hash": "0x9e3b3557f11b2b3532ce352bfe8017e9fd11d154c4c7f9b7aaaa1e621b539a08", - "args": ["0x7f52f0fccdd1d11391c441adfb174f87bca612b0"], - "hash_type": "data" - }, - "type": null, - "capacity": "5000000000000", - "out_point": { - "index": "0", - "tx_hash": "0xecd3917b7d9833a34d30da39b943b1811163f30771aae3165f60529955afb37f" - } - }, - "target": { - "lock": { - "codeHash": "0x9e3b3557f11b2b3532ce352bfe8017e9fd11d154c4c7f9b7aaaa1e621b539a08", - "args": ["0x7f52f0fccdd1d11391c441adfb174f87bca612b0"], - "hashType": "data" - }, - "type": null, - "capacity": "5000000000000", - "outPoint": { - "index": "0", - "txHash": "0xecd3917b7d9833a34d30da39b943b1811163f30771aae3165f60529955afb37f" - } - } - } - ], - "toCells": [ - { - "source": null, - "target": [] - }, - { - "source": [ - { - "capacity": "5000000000000", - - "lock": { - "args": [], - "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", - "hash_type": "data" - }, - "type": null - } - ], - "target": [ - { - "capacity": "5000000000000", - - "lock": { - "args": [], - "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", - "hashType": "data" - }, - "type": null - } - ] - } - ], - "toCellsIncludingOutPoint": [ - { - "source": null, - "target": [] - }, - { - "source": [ - { - "lock": { - "codeHash": "0x9e3b3557f11b2b3532ce352bfe8017e9fd11d154c4c7f9b7aaaa1e621b539a08", - "args": ["0x7f52f0fccdd1d11391c441adfb174f87bca612b0"], - "hashType": "data" - }, - "type": null, - "capacity": "5000000000000", - "out_point": { - "index": "0", - "tx_hash": "0xecd3917b7d9833a34d30da39b943b1811163f30771aae3165f60529955afb37f" - } - } - ], - "target": [ - { - "lock": { - "codeHash": "0x9e3b3557f11b2b3532ce352bfe8017e9fd11d154c4c7f9b7aaaa1e621b539a08", - "args": ["0x7f52f0fccdd1d11391c441adfb174f87bca612b0"], - "hashType": "data" - }, - "type": null, - "capacity": "5000000000000", - "outPoint": { - "index": "0", - "txHash": "0xecd3917b7d9833a34d30da39b943b1811163f30771aae3165f60529955afb37f" - } - } - ] - } - ], - "toHeader": [ - { - "source": null, - "target": null - }, - { - "source": { - "dao": "0x01000000000000000000c16ff286230000203d88792d0000000961f400000000", - "difficulty": "0x3e8", - "epoch": "0", - "hash": "0xba0d878d2c3711d38b5ddc2bc917312ca3898cad98457cc7960e28ec31f26e7f", - "number": "1024", - "parent_hash": "0x3533d5f0882a60d3b25b7dd57002a5d9eb591e89a98231e8abc5bf48f7ee0592", - "proposals_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "nonce": "0", - "timestamp": "1557311767", - "transactions_root": "0x81389ffabda2d1658c75a81e390a82b335d4cb849b2269d134b042fea9cb9513", - "uncles_count": "0", - "uncles_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "version": "0", - "witnesses_root": "0xb36423f72fd5cdbf6297c189b9d74e970bf0b971a537f41b8334088afe27900a" - }, - "target": { - "dao": "0x01000000000000000000c16ff286230000203d88792d0000000961f400000000", - "difficulty": "0x3e8", - "epoch": "0", - "hash": "0xba0d878d2c3711d38b5ddc2bc917312ca3898cad98457cc7960e28ec31f26e7f", - "number": "1024", - "parentHash": "0x3533d5f0882a60d3b25b7dd57002a5d9eb591e89a98231e8abc5bf48f7ee0592", - "proposalsHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "nonce": "0", - "timestamp": "1557311767", - "transactionsRoot": "0x81389ffabda2d1658c75a81e390a82b335d4cb849b2269d134b042fea9cb9513", - "unclesCount": "0", - "unclesHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "version": "0", - "witnessesRoot": "0xb36423f72fd5cdbf6297c189b9d74e970bf0b971a537f41b8334088afe27900a" - } - } - ], - "toTransactionWithStatus": [ - { - "source": null, - "target": null - }, - { - "source": { - "transaction": { - "cell_deps": [], - "header_deps": [], - "hash": "0x8027376875e45318ed469bed6314408e8f1986de246cbd03a786b69073c948b8", - "inputs": [ - { - "previous_output": { - "tx_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" - }, - "since": "0" - } - ], - "outputs": [ - { - "capacity": "5000000000000", - "lock": { - "args": [], - "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", - "hash_type": "data" - }, - "type": null - } - ], - "version": "0", - "witnesses": [], - "outputs_data": ["0x"] - }, - "tx_status": { - "status": "committed", - "block_hash": "0xef285e5da29247ce39385cbd8dc36535f7ea1b5b0379db26e9d459a8b47d0d71" - } - }, - "target": { - "transaction": { - "cellDeps": [], - "headerDeps": [], - "hash": "0x8027376875e45318ed469bed6314408e8f1986de246cbd03a786b69073c948b8", - "inputs": [ - { - "previousOutput": { - "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" - }, - "since": "0" - } - ], - "outputs": [ - { - "capacity": "5000000000000", - "lock": { - "args": [], - "codeHash": "0x0000000000000000000000000000000000000000000000000000000000000001", - "hashType": "data" - }, - "type": null - } - ], - "version": "0", - "witnesses": [], - "outputsData": ["0x"] - }, - "txStatus": { - "status": "committed", - "blockHash": "0xef285e5da29247ce39385cbd8dc36535f7ea1b5b0379db26e9d459a8b47d0d71" - } - } - } - ], - "toEpoch": [ - { - "source": null, - "target": null - }, - { - "source": { - "difficulty": "0x100", - "length": "1000", - "number": "0", - "start_number": "0" - }, - "target": { - "difficulty": "0x100", - "length": "1000", - "number": "0", - "startNumber": "0" - } - } - ], - "toTransactionPoint": [ - { - "source": null, - "target": null - }, - { - "source": { - "block_number": "1", - "index": "0", - "tx_hash": "0x41524669872de0ce874f926a9799b6944198571094fe94dc7ffa623a97c4f19f" - }, - "target": { - "blockNumber": "1", - "index": "0", - "txHash": "0x41524669872de0ce874f926a9799b6944198571094fe94dc7ffa623a97c4f19f" - } - } - ], - "toTransactionsByLockHash": [ - { - "source": null, - "target": null - }, - { - "source": [ - { - "consumed_by": null, - "created_by": { - "block_number": "1", - "index": "0", - "tx_hash": "0x41524669872de0ce874f926a9799b6944198571094fe94dc7ffa623a97c4f19f" - } - }, - { - "consumed_by": null, - "created_by": { - "block_number": "2", - "index": "0", - "tx_hash": "0x46ab01ddbbabef1af701f0843e11c7cfc0ce53f9aa9b554af74cadf8e3257d89" - } - } - ], - "target": [ - { - "consumedBy": null, - "createdBy": { - "blockNumber": "1", - "index": "0", - "txHash": "0x41524669872de0ce874f926a9799b6944198571094fe94dc7ffa623a97c4f19f" - } - }, - { - "consumedBy": null, - "createdBy": { - "blockNumber": "2", - "index": "0", - "txHash": "0x46ab01ddbbabef1af701f0843e11c7cfc0ce53f9aa9b554af74cadf8e3257d89" - } - } - ] - } - ], - "toLiveCellsByLockHash": [ - { - "source": null, - "target": null - }, - { - "source": [ - { - "cell_output": { - "capacity": "50000000000000", - "lock": { - "args": [], - "code_hash": "0x28e83a1277d48add8e72fadaa9248559e1b632bab2bd60b27955ebc4c03800a5" - }, - "type": null - }, - "created_by": { - "block_number": "1", - "index": "0", - "tx_hash": "0x41524669872de0ce874f926a9799b6944198571094fe94dc7ffa623a97c4f19f" - } - }, - { - "cell_output": { - "capacity": "50000000000000", - "lock": { - "args": [], - "code_hash": "0x28e83a1277d48add8e72fadaa9248559e1b632bab2bd60b27955ebc4c03800a5" - }, - "type": null - }, - "created_by": { - "block_number": "2", - "index": "0", - "tx_hash": "0x46ab01ddbbabef1af701f0843e11c7cfc0ce53f9aa9b554af74cadf8e3257d89" - } - } - ], - "target": [ - { - "cellOutput": { - "capacity": "50000000000000", - "lock": { - "args": [], - "codeHash": "0x28e83a1277d48add8e72fadaa9248559e1b632bab2bd60b27955ebc4c03800a5" - }, - "type": null - }, - "createdBy": { - "blockNumber": "1", - "index": "0", - "txHash": "0x41524669872de0ce874f926a9799b6944198571094fe94dc7ffa623a97c4f19f" - } - }, - { - "cellOutput": { - "capacity": "50000000000000", - - "lock": { - "args": [], - "codeHash": "0x28e83a1277d48add8e72fadaa9248559e1b632bab2bd60b27955ebc4c03800a5" - }, - "type": null - }, - "createdBy": { - "blockNumber": "2", - "index": "0", - "txHash": "0x46ab01ddbbabef1af701f0843e11c7cfc0ce53f9aa9b554af74cadf8e3257d89" - } - } - ] - } - ], - "toLockHashIndexState": [ - { - "source": null, - "target": null - }, - { - "source": { - "block_hash": "0xf35168c2e2e0c494ec97233091d5de51b7e5af7376bbc3d7572fc6438e2bb032", - "block_number": "1024", - "lock_hash": "0x9a9a6bdbc38d4905eace1822f85237e3a1e238bb3f277aa7b7c8903441123510" - }, - "target": { - "blockHash": "0xf35168c2e2e0c494ec97233091d5de51b7e5af7376bbc3d7572fc6438e2bb032", - "blockNumber": "1024", - "lockHash": "0x9a9a6bdbc38d4905eace1822f85237e3a1e238bb3f277aa7b7c8903441123510" - } - } - ], - "toLockHashIndexStates": [ - { - "source": null, - "target": null - }, - { - "source": [ - { - "block_hash": "0xf35168c2e2e0c494ec97233091d5de51b7e5af7376bbc3d7572fc6438e2bb032", - "block_number": "1024", - "lock_hash": "0x9a9a6bdbc38d4905eace1822f85237e3a1e238bb3f277aa7b7c8903441123510" - } - ], - "target": [ - { - "blockHash": "0xf35168c2e2e0c494ec97233091d5de51b7e5af7376bbc3d7572fc6438e2bb032", - "blockNumber": "1024", - "lockHash": "0x9a9a6bdbc38d4905eace1822f85237e3a1e238bb3f277aa7b7c8903441123510" - } - ] - } - ], - "toBannedAddress": [ - { - "source": null, - "target": null - }, - { - "source": { - "address": "192.168.0.2/32", - "ban_reason": "", - "ban_until": "1840546800000", - "created_at": "1562803123000" - }, - "target": { - "address": "192.168.0.2/32", - "banReason": "", - "banUntil": "1840546800000", - "createdAt": "1562803123000" - } - } - ], - "toBannedAddresses": [ - { - "source": null, - "target": null - }, - { - "source": [ - { - "address": "192.168.0.2/32", - "ban_reason": "", - "ban_until": "1840546800000", - "created_at": "1562803123000" - } - ], - "target": [ - { - "address": "192.168.0.2/32", - "banReason": "", - "banUntil": "1840546800000", - "createdAt": "1562803123000" - } - ] - } - ], - "toCellbaseOutputCapacityDetails": [ - { - "source": null, - "target": null - }, - { - "source": { - "primary": "100000000000", - "proposal_reward": "0", - "secondary": "1346505683", - "total": "101346505683", - "tx_fee": "0" - }, - "target": { - "primary": "100000000000", - "proposalReward": "0", - "secondary": "1346505683", - "total": "101346505683", - "txFee": "0" - } - } - ] - }, - "failure": {} -} diff --git a/packages/ckb-sdk-rpc/__tests__/formatters/result.test.js b/packages/ckb-sdk-rpc/__tests__/formatters/result.test.js index b5f5512c..5f9596c5 100644 --- a/packages/ckb-sdk-rpc/__tests__/formatters/result.test.js +++ b/packages/ckb-sdk-rpc/__tests__/formatters/result.test.js @@ -1,13 +1,21 @@ -const resultFmt = require('../../lib/resultFormatter').default -const fixtures = require('./result.json') +const { default: resultFmt } = require('../../lib/resultFormatter') +const fixtures = require('./result.fixtures.json') -const { success } = fixtures - -describe('result formatter success', () => { - test.each(Object.keys(success))('%s', methodName => { - success[methodName].forEach(fixture => { - const formatted = resultFmt[methodName](fixture.source) - expect(formatted).toEqual(fixture.target) +describe('result formatter', () => { + describe.each(Object.keys(fixtures))('%s', methodName => { + const fixtureTable = Object.values(fixtures[methodName]).map(({ result, expected, exception }) => [ + result, + expected, + exception, + ]) + test.each(fixtureTable)('%j => %j', (result, expected, exception) => { + if (undefined !== expected) { + const formatted = resultFmt[methodName](result) + expect(formatted).toEqual(expected) + } + if (undefined !== exception) { + expect(resultFmt[methodName](result)).toThrow(new Error(exception)) + } }) }) }) diff --git a/packages/ckb-sdk-rpc/package.json b/packages/ckb-sdk-rpc/package.json index 9ce55d29..078a8c12 100644 --- a/packages/ckb-sdk-rpc/package.json +++ b/packages/ckb-sdk-rpc/package.json @@ -1,6 +1,6 @@ { "name": "@nervosnetwork/ckb-sdk-rpc", - "version": "0.20.0", + "version": "0.21.0", "description": "RPC module of @nervosnetwork/ckb-sdk-core", "author": "Nervos ", "homepage": "https://github.com/nervosnetwork/ckb-sdk-js/packages/ckb-rpc#readme", @@ -32,11 +32,12 @@ "url": "https://github.com/nervosnetwork/ckb-sdk-js/issues" }, "dependencies": { - "@nervosnetwork/ckb-sdk-utils": "0.20.0", + "@nervosnetwork/ckb-sdk-utils": "0.21.0", "axios": "0.19.0" }, "devDependencies": { - "@nervosnetwork/ckb-types": "0.20.0" + "@nervosnetwork/ckb-types": "0.21.0", + "dotenv": "8.1.0" }, - "gitHead": "478433630dd40501f1f67dc259bf9d252c56fcd3" + "gitHead": "5a1aaff6006c91e45e8ba39ceb6ef7c2f870e6cd" } diff --git a/packages/ckb-sdk-rpc/src/defaultRPC.ts b/packages/ckb-sdk-rpc/src/defaultRPC.ts index fb8ca683..5ca1b96c 100644 --- a/packages/ckb-sdk-rpc/src/defaultRPC.ts +++ b/packages/ckb-sdk-rpc/src/defaultRPC.ts @@ -41,7 +41,7 @@ const defaultRPC: CKBComponents.Method[] = [ name: 'getLiveCell', method: 'get_live_cell', paramsFormatters: [paramsFmts.toOutPoint], - resultFormatters: resultFmts.toCellWithStatus, + resultFormatters: resultFmts.toLiveCellWithStatus, }, { name: 'getTipBlockNumber', @@ -231,10 +231,12 @@ export class DefaultRPC { * @description rpc to get a cell by outPoint, the meaning of outPoint could be found in ckb-types, * please distinguish outPoint and cellOutPoint * @param {object} outPoint - cell's outPoint + * @param {boolean} withData - set withData to true to return cell data and data hash if the cell is live * @return {Promise} cellWithStatus */ public getLiveCell!: ( - outPoint: CKBComponents.OutPoint + outPoint: CKBComponents.OutPoint, + withData: boolean ) => Promise<{ cell: CKBComponents.Cell status: CKBComponents.CellStatus diff --git a/packages/ckb-sdk-rpc/src/paramsFormatter.ts b/packages/ckb-sdk-rpc/src/paramsFormatter.ts index c3b42036..2ee835fa 100644 --- a/packages/ckb-sdk-rpc/src/paramsFormatter.ts +++ b/packages/ckb-sdk-rpc/src/paramsFormatter.ts @@ -1,35 +1,54 @@ /* eslint-disable camelcase */ const formatter = { + toHash: (hash: string): CKB_RPC.Hash256 => { + if (typeof hash !== 'string') { + throw new TypeError(`Hash ${hash} should be type of string`) + } + return hash.startsWith('0x') ? hash : `0x${hash}` + }, + toNumber: (number: CKBComponents.Number | number): CKB_RPC.Number => { + if (typeof number === 'number') { + return `0x${number.toString(16)}` + } + if (typeof number !== 'string') { + throw new TypeError(`The number ${number} should be a number or a hex string`) + } + if (!number.startsWith('0x')) { + throw new Error(`If the number ${number} is a hex string, please prefix it with 0x`) + } + return number + }, toScript: (script: CKBComponents.Script): CKB_RPC.Script => { - const { codeHash: code_hash, hashType: hash_type, ...rest } = script + const { codeHash, hashType: hash_type, ...rest } = script return { - code_hash, + code_hash: formatter.toHash(codeHash), hash_type, ...rest, } }, - toHash: (hash: string): CKB_RPC.Hash256 => (hash.startsWith('0x') ? hash : `0x${hash}`), toOutPoint: (outPoint: CKBComponents.OutPoint | null): CKB_RPC.OutPoint | null => { if (!outPoint) return outPoint - const { txHash: tx_hash, ...rest } = outPoint + const { txHash, index, ...rest } = outPoint return { - tx_hash, + tx_hash: formatter.toHash(txHash), + index: formatter.toNumber(index), ...rest, } }, - toNumber: (number: CKBComponents.BlockNumber): CKB_RPC.BlockNumber => number.toString(), toInput: (input: CKBComponents.CellInput): CKB_RPC.CellInput => { if (!input) return input - const { previousOutput, ...rest } = input + const { previousOutput, since, ...rest } = input return { previous_output: formatter.toOutPoint(previousOutput), + since: formatter.toNumber(since), ...rest, } }, toOutput: (output: CKBComponents.CellOutput): CKB_RPC.CellOutput => { if (!output) return output - const { lock, type = null, ...rest } = output + const { capacity, lock, type = null, ...rest } = output return { + capacity: formatter.toNumber(capacity), lock: formatter.toScript(lock), type: type ? formatter.toScript(type) : type, ...rest, @@ -65,7 +84,7 @@ const formatter = { const formattedOutputs = outputs.map(output => formatter.toOutput(output)) const formattedCellDeps = cellDeps.map(cellDep => formatter.toCellDep(cellDep)) const tx = { - version, + version: formatter.toNumber(version), cell_deps: formattedCellDeps, inputs: formattedInputs, outputs: formattedOutputs, @@ -75,12 +94,12 @@ const formatter = { } return tx }, - toPageNumber: (pageNo: string | number = '1') => pageNo.toString(), + toPageNumber: (pageNo: string | number = '0x1') => formatter.toNumber(pageNo), toPageSize: (pageSize: string | number = 50) => { const size = +pageSize || 50 if (size > 50) throw new Error('Page size is up to 50') if (size < 0) throw new Error('Page size is expected to be positive') - return `${size}` + return formatter.toNumber(size) }, toReverseOrder: (reverse: boolean = false) => !!reverse, } diff --git a/packages/ckb-sdk-rpc/src/resultFormatter.ts b/packages/ckb-sdk-rpc/src/resultFormatter.ts index a09190d4..87c4b4ad 100644 --- a/packages/ckb-sdk-rpc/src/resultFormatter.ts +++ b/packages/ckb-sdk-rpc/src/resultFormatter.ts @@ -153,7 +153,7 @@ const formatter = { ...rest, } }, - toPeers: (nodes: CKB_RPC.NodeInfo[] = []): CKBComponents.NodeInfo[] => { + toPeers: (nodes: CKB_RPC.NodeInfo[]): CKBComponents.NodeInfo[] => { if (!Array.isArray(nodes)) return [] return nodes.map(formatter.toNodeInfo) }, @@ -175,15 +175,24 @@ const formatter = { ...rest, } }, - toCellWithStatus: (cellWithStatus: { cell: CKB_RPC.Cell; status: string }) => { + toLiveCell: (liveCell: CKB_RPC.LiveCell): CKBComponents.LiveCell => { + if (!liveCell) return liveCell + const { data, output, ...rest } = liveCell + return { + data, + output: formatter.toOutput(output), + ...rest, + } + }, + toLiveCellWithStatus: (cellWithStatus: { cell: CKB_RPC.LiveCell; status: string }) => { if (!cellWithStatus) return cellWithStatus const { cell, ...rest } = cellWithStatus return { - cell: formatter.toCell(cell), + cell: formatter.toLiveCell(cell), ...rest, } }, - toCells: (cells: CKB_RPC.Cell[] = []): CKBComponents.Cell[] => { + toCells: (cells: CKB_RPC.Cell[]): CKBComponents.Cell[] => { if (!Array.isArray(cells)) return [] return cells.map(formatter.toCell) }, @@ -196,7 +205,7 @@ const formatter = { ...rest, } }, - toCellsIncludingOutPoint: (cells: CKB_RPC.CellIncludingOutPoint[] = []): CKBComponents.CellIncludingOutPoint[] => { + toCellsIncludingOutPoint: (cells: CKB_RPC.CellIncludingOutPoint[]): CKBComponents.CellIncludingOutPoint[] => { if (!Array.isArray(cells)) return [] return cells.map(formatter.toCellIncludingOutPoint) }, diff --git a/packages/ckb-sdk-rpc/types/CKB_RPC/index.d.ts b/packages/ckb-sdk-rpc/types/CKB_RPC/index.d.ts index f9106eea..b39c8e1a 100644 --- a/packages/ckb-sdk-rpc/types/CKB_RPC/index.d.ts +++ b/packages/ckb-sdk-rpc/types/CKB_RPC/index.d.ts @@ -5,6 +5,7 @@ /* eslint-disable camelcase */ declare module CKB_RPC { export type ProposalShortId = CKBComponents.ProposalShortId + export type Number = CKBComponents.Number export type UInt32 = CKBComponents.UInt32 export type Count = CKBComponents.Count export type Hash256 = CKBComponents.Hash256 @@ -51,6 +52,14 @@ declare module CKB_RPC { export type Cell = CellOutput + export interface LiveCell { + data?: { + content: Hash + hash: Hash256 + } + output: CellOutput + } + export interface CellDep { out_point: OutPoint | null dep_type: DepType diff --git a/packages/ckb-sdk-utils/CHANGELOG.md b/packages/ckb-sdk-utils/CHANGELOG.md index c8558c89..87bdb8a9 100644 --- a/packages/ckb-sdk-utils/CHANGELOG.md +++ b/packages/ckb-sdk-utils/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [0.21.0](https://github.com/nervosnetwork/ckb-sdk-js/compare/v0.20.0...v0.21.0) (2019-09-21) + + +### Code Refactoring + +* **address** rename public key identifier to publicKeyHash ([b33c096](https://github.com/nervosnetwork/ckb-sdk-js/commit/b33c096)) + + +### Features + +* **utils:** format the outputs of the utils module ([a30071c](https://github.com/nervosnetwork/ckb-sdk-js/commit/a30071c)) + + +### BREAKING CHANGES + +* **address** rename public key identifier to publicKeyHash +* **utils:** hexilize the outputs of the utils module + + + + + # [0.20.0](https://github.com/nervosnetwork/ckb-sdk-js/compare/v0.19.1...v0.20.0) (2019-09-07) diff --git a/packages/ckb-sdk-utils/__tests__/ecpair.test.js b/packages/ckb-sdk-utils/__tests__/ecpair.test.js deleted file mode 100644 index 88ca097f..00000000 --- a/packages/ckb-sdk-utils/__tests__/ecpair.test.js +++ /dev/null @@ -1,70 +0,0 @@ -const ECPair = require('../lib/ecpair').default -const { sigFixtures, signRecoverableFixtures } = require('./signature-fixtures.json') -const { hexToBytes } = require('../lib') - -describe('ECPair', () => { - it('new ecpair', () => { - const fixture = { - privateKey: 'e79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3', - compressed: true, - publicKey: '024a501efd328e062c8675f2365970728c859c592beeefd6be8ead3d901330bc01', - } - - const ecpair = new ECPair(hexToBytes(fixture.privateKey), { - compressed: fixture.compressed, - }) - expect(ecpair.compressed).toBe(fixture.compressed) - expect(ecpair.privateKey).toBe(fixture.privateKey) - expect(ecpair.getPrivateKey('hex')).toBe(fixture.privateKey) - expect(ecpair.publicKey).toBe(fixture.publicKey) - expect(ecpair.getPublicKey('hex')).toBe(fixture.publicKey) - }) - - it('new ecpair with empty options, default compressed should be true', () => { - const fixture = { - privateKey: 'e79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3', - compressed: true, - publicKey: '024a501efd328e062c8675f2365970728c859c592beeefd6be8ead3d901330bc01', - } - - const ecpair = new ECPair(hexToBytes(fixture.privateKey), {}) - expect(ecpair.compressed).toBe(fixture.compressed) - expect(ecpair.privateKey).toEqual(fixture.privateKey) - expect(ecpair.publicKey).toBe(fixture.publicKey) - }) - - it('new ecpair with default options which should be { compressed: true }', () => { - const fixture = { - privateKey: 'e79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3', - compressed: true, - publicKey: '024a501efd328e062c8675f2365970728c859c592beeefd6be8ead3d901330bc01', - } - - const ecpair = new ECPair(hexToBytes(fixture.privateKey)) - expect(ecpair.compressed).toBe(fixture.compressed) - expect(ecpair.privateKey).toEqual(fixture.privateKey) - expect(ecpair.publicKey).toBe(fixture.publicKey) - }) - - it('sign and verify message', () => { - sigFixtures.forEach(fixture => { - const ecpair = new ECPair(fixture.privkey) - const sig = ecpair.sign(fixture.msg) - // slice sig from 0, -2 to ignore the recovery param - expect(sig).toBe(fixture.sig.slice(0, -2)) - expect(ecpair.verify(fixture.msg, fixture.sig.slice(0, -2))).toBe(true) - }) - }) - - it('signRecoverable', () => { - signRecoverableFixtures.forEach(fixture => { - const ecpair = new ECPair(fixture.privKey) - const sig = ecpair.signRecoverable(fixture.msg) - expect(sig).toBe(fixture.sig) - }) - }) - - it('throw error if private key is absent', () => { - expect(() => new ECPair()).toThrow('Private key is required') - }) -}) diff --git a/packages/ckb-sdk-utils/__tests__/ecpair/ecpare.fixtures.json b/packages/ckb-sdk-utils/__tests__/ecpair/ecpare.fixtures.json new file mode 100644 index 00000000..9cfa6021 --- /dev/null +++ b/packages/ckb-sdk-utils/__tests__/ecpair/ecpare.fixtures.json @@ -0,0 +1,67 @@ +{ + "instantiate": { + "basic": { + "privateKey": "0xe79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3", + "compressed": true, + "publicKey": "0x024a501efd328e062c8675f2365970728c859c592beeefd6be8ead3d901330bc01", + "privateKeyWords": [ + 4965603, + 51553698, + 33661175, + 21402603, + 30321735, + 23384210, + 24745325, + 33742843, + 34073161, + 3794892, + 0 + ], + "publicKeyBytes": [ + 2, + 74, + 80, + 30, + 253, + 50, + 142, + 6, + 44, + 134, + 117, + 242, + 54, + 89, + 112, + 114, + 140, + 133, + 156, + 89, + 43, + 238, + 239, + 214, + 190, + 142, + 173, + 61, + 144, + 19, + 48, + 188, + 1 + ] + }, + "withEmptyOption": { + "privateKey": "0xe79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3", + "compressed": true, + "publicKey": "0x024a501efd328e062c8675f2365970728c859c592beeefd6be8ead3d901330bc01" + }, + "withDefaultOption": { + "privateKey": "0xe79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3", + "compressed": true, + "publicKey": "0x024a501efd328e062c8675f2365970728c859c592beeefd6be8ead3d901330bc01" + } + } +} diff --git a/packages/ckb-sdk-utils/__tests__/ecpair/index.test.js b/packages/ckb-sdk-utils/__tests__/ecpair/index.test.js new file mode 100644 index 00000000..022d9447 --- /dev/null +++ b/packages/ckb-sdk-utils/__tests__/ecpair/index.test.js @@ -0,0 +1,68 @@ +const { default: ECPair } = require('../../lib/ecpair') +const { HexStringShouldStartWith0x } = require('../../lib/exceptions') +const { instantiate: instantiateFixtures } = require('./ecpare.fixtures.json') +const { sigFixtures, signRecoverableFixtures } = require('./signature.fixtures.json') +const { hexToBytes } = require('../../lib') +const { ArgumentRequired } = require('../../lib/exceptions') + +describe('ECPair', () => { + it('new ecpair', () => { + const fixture = instantiateFixtures.basic + + const ecpair = new ECPair(hexToBytes(fixture.privateKey), { + compressed: fixture.compressed, + }) + expect(ecpair.compressed).toBe(fixture.compressed) + expect(ecpair.privateKey).toBe(fixture.privateKey) + expect(ecpair.getPrivateKey('hex')).toBe(fixture.privateKey) + expect(ecpair.getPrivateKey('words').words).toEqual(fixture.privateKeyWords) + expect(ecpair.publicKey).toBe(fixture.publicKey) + expect(ecpair.getPublicKey('hex')).toBe(fixture.publicKey) + expect(ecpair.getPublicKey('bytes')).toEqual(fixture.publicKeyBytes) + }) + + it('new ecpair with empty options, default compressed should be true', () => { + const fixture = instantiateFixtures.withEmptyOption + + const ecpair = new ECPair(hexToBytes(fixture.privateKey), {}) + expect(ecpair.compressed).toBe(fixture.compressed) + expect(ecpair.privateKey).toEqual(fixture.privateKey) + expect(ecpair.publicKey).toBe(fixture.publicKey) + }) + + it('new ecpair with default options which should be { compressed: true }', () => { + const fixture = instantiateFixtures.withDefaultOption + + const ecpair = new ECPair(hexToBytes(fixture.privateKey)) + expect(ecpair.compressed).toBe(fixture.compressed) + expect(ecpair.privateKey).toEqual(fixture.privateKey) + expect(ecpair.publicKey).toBe(fixture.publicKey) + }) + + it('Instantiate with an empty private key should throw an error', () => { + expect(() => new ECPair()).toThrow(new ArgumentRequired('Private key')) + }) + + it('Instantiate with a private key without 0x should throw an error', () => { + const privateKey = 'e79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3' + expect(() => new ECPair(privateKey, {})).toThrow(new HexStringShouldStartWith0x(privateKey)) + }) + + it('sign and verify message', () => { + sigFixtures.forEach(fixture => { + const ecpair = new ECPair(`0x${fixture.privkey}`) + const sig = ecpair.sign(`0x${fixture.msg}`) + // slice sig from 0, -2 to ignore the recovery param + expect(sig).toBe(`0x${fixture.sig.slice(0, -2)}`) + expect(ecpair.verify(`0x${fixture.msg}`, `0x${fixture.sig.slice(0, -2)}`)).toBe(true) + }) + }) + + it('signRecoverable', () => { + signRecoverableFixtures.forEach(fixture => { + const ecpair = new ECPair(`0x${fixture.privKey}`) + const sig = ecpair.signRecoverable(`0x${fixture.msg}`) + expect(sig).toBe(`0x${fixture.sig}`) + }) + }) +}) diff --git a/packages/ckb-sdk-utils/__tests__/signature-fixtures.json b/packages/ckb-sdk-utils/__tests__/ecpair/signature.fixtures.json similarity index 100% rename from packages/ckb-sdk-utils/__tests__/signature-fixtures.json rename to packages/ckb-sdk-utils/__tests__/ecpair/signature.fixtures.json diff --git a/packages/ckb-sdk-utils/__tests__/serialization/index/fixtures.json b/packages/ckb-sdk-utils/__tests__/serialization/index/fixtures.json index 796b25cb..6255395f 100644 --- a/packages/ckb-sdk-utils/__tests__/serialization/index/fixtures.json +++ b/packages/ckb-sdk-utils/__tests__/serialization/index/fixtures.json @@ -1,14 +1,10 @@ { - "serializeArray": [ - { + "serializeArray": { + "basic array in hex string": { "array": "0x68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88", - "expected": "68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88" + "expected": "0x68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88" }, - { - "array": "68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88", - "expected": "68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88" - }, - { + "basic array in bytes": { "array": [ 104, 213, @@ -43,65 +39,86 @@ 142, 136 ], - "expected": "68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88" + "expected": "0x68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88" + }, + "invalid array should throw an error": { + "exception": "The array to be serialized should by type of string or bytes" + }, + "hex string without 0x should throw an error": { + "array": "ffffff", + "exception": "Hex string ffffff should start with 0x" } - ], - "serializeStruct": [ - { - "struct": [["f1", "ab"]], - "expected": "ab" + }, + "serializeStruct": { + "basic struct": { + "struct": [["f1", "0xab"], ["f2", "0x030201"]], + "expected": "0xab030201" }, - { + "invalid struct": { "struct": [["f1", "ab"], ["f2", "0x030201"]], - "expected": "ab030201" + "exception": "Hex string ab should start with 0x" } - ], - "serializeFixVec": [ - { + }, + "serializeFixVec": { + "empty vector": { "fixvec": [], - "expected": "00000000" + "expected": "0x00000000" }, - { + "hex string in vector": { "fixvec": ["0x12"], - "expected": "0100000012" + "expected": "0x0100000012" }, - { + "bytes in vector": { "fixvec": [[18]], - "expected": "0100000012" + "expected": "0x0100000012" }, - { + "vector in hex string": { "fixvec": "0x1234567890abcdef", - "expected": "080000001234567890abcdef" + "expected": "0x080000001234567890abcdef" + }, + "invalid vector": { + "exception": "The fixed vector to be serialized should be a string or an array of bytes" } - ], - "serializeDynVec": [ - { + }, + "serializeDynVec": { + "empty vector": { "dynvec": [], - "expected": "04000000" + "expected": "0x04000000" }, - { - "dynvec": ["020000001234"], - "expected": "0e00000008000000020000001234" + "vector has one item": { + "dynvec": ["0x020000001234"], + "expected": "0x0e00000008000000020000001234" }, - { - "dynvec": ["020000001234", "00000000", "020000000567", "0x0100000089", "03000000abcdef"], - "expected": "34000000180000001e00000022000000280000002d00000002000000123400000000020000000567010000008903000000abcdef" + "vector has multiple items": { + "dynvec": ["0x020000001234", "0x00000000", "0x020000000567", "0x0100000089", "0x03000000abcdef"], + "expected": "0x34000000180000001e00000022000000280000002d00000002000000123400000000020000000567010000008903000000abcdef" + }, + "vector in invalid format should throw an error": { + "exception": "The dynamic vector to be serialized should be an array of bytes" + }, + "vector has invalid item should throw an error": { + "dynvec": ["020000001234", "0x00000000", "0x020000000567", "0x0100000089", "0x03000000abcdef"], + "exception": "Hex string 020000001234 should start with 0x" } - ], - "serializeTable": [ - { + }, + "serializeTable": { + "basic table": { + "table": [["f1", "0xab"], ["f2", "0x030201"]], + "expected": "0x100000000c0000000d000000ab030201" + }, + "table has invalid field should throw an error": { "table": [["f1", "ab"], ["f2", "0x030201"]], - "expected": "100000000c0000000d000000ab030201" + "exception": "Hex string ab should start with 0x" } - ], - "serializeOption": [ - { + }, + "serializeOption": { + "empty option": { "option": "", "expected": "" }, - { - "option": "0c0000000800000000000000", - "expected": "0c0000000800000000000000" + "basic option": { + "option": "0x0c0000000800000000000000", + "expected": "0x0c0000000800000000000000" } - ] + } } diff --git a/packages/ckb-sdk-utils/__tests__/serialization/index/index.test.js b/packages/ckb-sdk-utils/__tests__/serialization/index/index.test.js index 2dbb59a6..a70d93b7 100644 --- a/packages/ckb-sdk-utils/__tests__/serialization/index/index.test.js +++ b/packages/ckb-sdk-utils/__tests__/serialization/index/index.test.js @@ -10,61 +10,104 @@ const fixtures = require('./fixtures.json') describe('Test General Serialization', () => { describe('Serialize Array', () => { - const fixtureTable = fixtures.serializeArray.map(({ array, expected }) => [array, expected]) - test.each(fixtureTable)('%s => %s', (array, expected) => { - expect(serializeArray(array)).toBe(expected) - }) - it('thorw errors if the array is not type of string or bytes', () => { - expect(() => serializeArray(undefined)).toThrow( - new TypeError('The array to be serialized should by type of string or bytes') - ) + const fixtureTable = Object.entries(fixtures.serializeArray).map(([title, { array, expected, exception }]) => [ + title, + array, + expected, + exception, + ]) + test.each(fixtureTable)('%s', (_title, array, expected, exception) => { + if (undefined !== expected) { + expect(serializeArray(array)).toBe(expected) + } + if (undefined !== exception) { + expect(() => serializeArray(array)).toThrow(new Error(exception)) + } }) }) describe('Serialize Struct', () => { - const fixtureTable = fixtures.serializeStruct.map(({ struct, expected }) => [new Map(struct), expected]) - test.each(fixtureTable)('%s => %s', (struct, expected) => { - expect(serializeStruct(struct)).toBe(expected) + const fixtureTable = Object.entries(fixtures.serializeStruct).map(([title, { struct, expected, exception }]) => [ + title, + new Map(struct), + expected, + exception, + ]) + test.each(fixtureTable)('%s', (_title, struct, expected, exception) => { + if (undefined !== expected) { + expect(serializeStruct(struct)).toBe(expected) + } + if (undefined !== exception) { + expect(() => serializeStruct(struct)).toThrow(new Error(exception)) + } }) }) describe('Serialize Fixed Vector', () => { - const fixtureTable = fixtures.serializeFixVec.map(({ fixvec, expected }) => [fixvec, expected]) - test.each(fixtureTable)('%s => %s', (fixvec, expected) => { - expect(serializeFixVec(fixvec)).toBe(expected) - }) - - it('throw errors if the fixed vector is not an array of bytes', () => { - expect(() => serializeFixVec(undefined)).toThrow( - new TypeError('The fixed vector to be serialized should be a string or an array of bytes') - ) + const fixtureTable = Object.entries(fixtures.serializeFixVec).map(([title, { fixvec, expected, exception }]) => [ + title, + fixvec, + expected, + exception, + ]) + test.each(fixtureTable)('%s', (_title, fixvec, expected, exception) => { + if (undefined !== expected) { + expect(serializeFixVec(fixvec)).toBe(expected) + } + if (undefined !== exception) { + expect(() => serializeFixVec(fixvec)).toThrow(new Error(exception)) + } }) }) describe('Serialize Dynamic Vector', () => { - const fixtureTable = fixtures.serializeDynVec.map(({ dynvec, expected }) => [dynvec, expected]) - test.each(fixtureTable)('%s => %s', (dynvec, expected) => { - expect(serializeDynVec(dynvec)).toBe(expected) - }) - - it('throw errors if the dynamic vector is not an array of bytes', () => { - expect(() => serializeDynVec(undefined)).toThrow( - new TypeError('The dynamic vector to be serialized should be an array of bytes') - ) + const fixtureTable = Object.entries(fixtures.serializeDynVec).map(([title, { dynvec, expected, exception }]) => [ + title, + dynvec, + expected, + exception, + ]) + test.each(fixtureTable)('%s', (_title, dynvec, expected, exception) => { + if (undefined !== expected) { + expect(serializeDynVec(dynvec)).toBe(expected) + } + if (undefined !== exception) { + expect(() => serializeDynVec(dynvec)).toThrow(new Error(exception)) + } }) }) describe('Serialize Table', () => { - const fixtureTable = fixtures.serializeTable.map(({ table, expected }) => [new Map(table), expected]) - test.each(fixtureTable)('%s => %s', (table, expected) => { - expect(serializeTable(table)).toBe(expected) + const fixtureTable = Object.entries(fixtures.serializeTable).map(([title, { table, expected, exception }]) => [ + title, + new Map(table), + expected, + exception, + ]) + test.each(fixtureTable)('%s', (_title, table, expected, exception) => { + if (undefined !== expected) { + expect(serializeTable(table)).toBe(expected) + } + if (undefined !== exception) { + expect(() => serializeTable(table)).toThrow(new Error(exception)) + } }) }) describe('Serialize Option', () => { - const fixtureTable = fixtures.serializeOption.map(({ option, expected }) => [option, expected]) - test.each(fixtureTable)('%s => %s', (option, expected) => { - expect(serializeOption(option)).toBe(expected) + const fixtureTable = Object.entries(fixtures.serializeOption).map(([title, { option, expected, exception }]) => [ + title, + option, + expected, + exception, + ]) + test.each(fixtureTable)('%s', (_title, option, expected, exception) => { + if (undefined !== expected) { + expect(serializeOption(option)).toBe(expected) + } + if (undefined !== exception) { + expect(() => serializeOption(option)).toThrow(exception) + } }) }) }) diff --git a/packages/ckb-sdk-utils/__tests__/serialization/script/fixtures.json b/packages/ckb-sdk-utils/__tests__/serialization/script/fixtures.json index 4c79b830..30761728 100644 --- a/packages/ckb-sdk-utils/__tests__/serialization/script/fixtures.json +++ b/packages/ckb-sdk-utils/__tests__/serialization/script/fixtures.json @@ -1,46 +1,57 @@ { - "serializeArgs": [ - { + "serializeArgs": { + "empty args": { "args": [], - "expected": "04000000" + "expected": "0x04000000" }, - { + "args has multiple items": { "args": ["0x10", "0x01"], - "expected": "160000000c0000001100000001000000100100000001" + "expected": "0x160000000c0000001100000001000000100100000001" }, - { + "args has one item": { "args": ["0x3954acece65096bfa81258983ddb83915fc56bd8"], - "expected": "2000000008000000140000003954acece65096bfa81258983ddb83915fc56bd8" + "expected": "0x2000000008000000140000003954acece65096bfa81258983ddb83915fc56bd8" } - ], - "serializeCodeHash": [ - { + }, + "serializeCodeHash": { + "basic code hash": { "codeHash": "0x68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88", - "expected": "68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88" - }, - { - "codeHash": "68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88", - "expected": "68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88" + "expected": "0x68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88" } - ], - "serializeHashType": [ - { + }, + "serializeHashType": { + "type of data": { "hashType": "data", - "expected": "00" + "expected": "0x00" }, - { + "type of type": { "hashType": "type", - "expected": "01" + "expected": "0x01" + }, + "neither data nor type should throw an error": { + "hashType": "unknown", + "exception": "Hash type must be either of 'data' or 'type'" } - ], - "serializeScript": [ - { + }, + "serializeScript": { + "basic script": { "script": { "codeHash": "0x68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88", "args": ["0x3954acece65096bfa81258983ddb83915fc56bd8"], "hashType": "type" }, - "expected": "5100000010000000300000003100000068d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88012000000008000000140000003954acece65096bfa81258983ddb83915fc56bd8" + "expected": "0x5100000010000000300000003100000068d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88012000000008000000140000003954acece65096bfa81258983ddb83915fc56bd8" + }, + "default args should be an empty arary": { + "script": { + "codeHash": "0x68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88", + "hashType": "type" + }, + "expected": "0x3500000010000000300000003100000068d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e880104000000" + }, + "undefined script should throw an error": { + "script": null, + "exception": "Script is required" } - ] + } } diff --git a/packages/ckb-sdk-utils/__tests__/serialization/script/index.test.js b/packages/ckb-sdk-utils/__tests__/serialization/script/index.test.js index e6b741f1..74d00934 100644 --- a/packages/ckb-sdk-utils/__tests__/serialization/script/index.test.js +++ b/packages/ckb-sdk-utils/__tests__/serialization/script/index.test.js @@ -8,38 +8,64 @@ const fixtures = require('./fixtures.json') describe('Test Script Serialization', () => { describe('Serialize Args', () => { - const fixtureTable = fixtures.serializeArgs.map(({ args, expected }) => [args, expected]) - test.each(fixtureTable)('%j => %s', (args, expected) => { - expect(serializeArgs(args)).toBe(expected) + const fixtureTable = Object.entries(fixtures.serializeArgs).map(([title, { args, expected, exception }]) => [ + title, + args, + expected, + exception, + ]) + test.each(fixtureTable)('%s', (_title, args, expected, exception) => { + if (undefined !== expected) { + expect(serializeArgs(args)).toBe(expected) + } + if (undefined !== exception) { + expect(() => serializeArgs(args)).toThrow(new Error(exception)) + } }) }) describe('Serialize CodeHash', () => { - const fixtureTable = fixtures.serializeCodeHash.map(({ codeHash, expected }) => [codeHash, expected]) - test.each(fixtureTable)('%s => %s', (codeHash, expected) => { - expect(serializeCodeHash(codeHash)).toBe(expected) + const fixtureTable = Object.entries(fixtures.serializeCodeHash).map( + ([title, { codeHash, expected, exception }]) => [title, codeHash, expected, exception] + ) + test.each(fixtureTable)('%s', (_title, codeHash, expected, exception) => { + if (undefined !== expected) { + expect(serializeCodeHash(codeHash)).toBe(expected) + } + if (undefined !== exception) { + expect(() => serializeCodeHash(codeHash)).toThrow(new Error(exception)) + } }) }) describe('Serialize HashType', () => { - const fixtureTable = fixtures.serializeHashType.map(({ hashType, expected }) => [hashType, expected]) - test.each(fixtureTable)('%s => %s', (hashType, expected) => { - expect(serializeHashType(hashType)).toBe(expected) - }) - - it('throw errors if hash type is neither data nor type', () => { - expect(() => serializeHashType('unknown')).toThrow(new TypeError("Hash type must be either of 'data' or 'type'")) + const fixtureTable = Object.entries(fixtures.serializeHashType).map( + ([title, { hashType, expected, exception }]) => [title, hashType, expected, exception] + ) + test.each(fixtureTable)('%s', (_title, hashType, expected, exception) => { + if (undefined !== expected) { + expect(serializeHashType(hashType)).toBe(expected) + } + if (undefined !== exception) { + expect(() => serializeHashType(hashType)).toThrow(new Error(exception)) + } }) }) describe('Serialize Script', () => { - const fixtureTable = fixtures.serializeScript.map(({ script, expected }) => [script, expected]) - test.each(fixtureTable)('%j => %s', (script, expected) => { - expect(serializeScript(script)).toBe(expected) - }) - - it('throw errors if the script is not passed into the method', () => { - expect(() => serializeScript()).toThrow(new Error('Script is required')) + const fixtureTable = Object.entries(fixtures.serializeScript).map(([title, { script, expected, exception }]) => [ + title, + script, + expected, + exception, + ]) + test.each(fixtureTable)('%s', (_title, script, expected, exception) => { + if (undefined !== expected) { + expect(serializeScript(script)).toBe(expected) + } + if (undefined !== exception) { + expect(() => serializeScript(script)).toThrow(new Error(exception)) + } }) }) }) diff --git a/packages/ckb-sdk-utils/__tests__/serialization/transaction/fixtures.json b/packages/ckb-sdk-utils/__tests__/serialization/transaction/fixtures.json index a1083c5c..85b439f8 100644 --- a/packages/ckb-sdk-utils/__tests__/serialization/transaction/fixtures.json +++ b/packages/ckb-sdk-utils/__tests__/serialization/transaction/fixtures.json @@ -1,105 +1,120 @@ { - "serializeVersion": [ - { - "version": "0", - "expected": "00000000" + "serializeVersion": { + "0x0": { + "version": "0x0", + "expected": "0x00000000" }, - { - "version": "1", - "expected": "01000000" + "0x1": { + "version": "0x1", + "expected": "0x01000000" + }, + "1": { + "version": 1, + "expected": "0x01000000" + }, + "0xabcd": { + "version": "0xabcd", + "expected": "0xcdab0000" }, - { - "version": "20", - "expected": "14000000" + "cannot converted to number": { + "exception": "undefined is an invalid hex string" + }, + "hex string without 0x should throw an error": { + "version": "1", + "exception": "Hex string 1 should start with 0x" } - ], - "serializeOutPoint": [ - { + }, + "serializeOutPoint": { + "empty": { "outPoint": null, "expected": "" }, - { + "basic out point": { "outPoint": { "txHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "index": "4294967295" + "index": "0xffffffff" }, - "expected": "0000000000000000000000000000000000000000000000000000000000000000ffffffff" + "expected": "0x0000000000000000000000000000000000000000000000000000000000000000ffffffff" } - ], - "serializeDepType": [ - { + }, + "serializeDepType": { + "code": { "depType": "code", - "expected": "00" + "expected": "0x00" }, - { + "dep group": { "depType": "depGroup", - "expected": "01" + "expected": "0x01" + }, + "neither code nor depGroup should throw an error": { + "depType": "unknown type", + "exception": "Dep type must be either of 'code' or 'depGroup'" } - ], - "serializeCellDep": [ - { + }, + "serializeCellDep": { + "basic cell dep": { "cellDep": { "outPoint": { "txHash": "0xc12386705b5cbb312b693874f3edf45c43a274482e27b8df0fd80c8d3f5feb8b", - "index": "0" + "index": "0x0" }, "depType": "depGroup" }, - "expected": "c12386705b5cbb312b693874f3edf45c43a274482e27b8df0fd80c8d3f5feb8b0000000001" + "expected": "0xc12386705b5cbb312b693874f3edf45c43a274482e27b8df0fd80c8d3f5feb8b0000000001" } - ], - "serializeCellDeps": [ - { + }, + "serializeCellDeps": { + "basic cell deps": { "cellDeps": [ { "outPoint": { "txHash": "0xc12386705b5cbb312b693874f3edf45c43a274482e27b8df0fd80c8d3f5feb8b", - "index": "0" + "index": "0x0" }, "depType": "depGroup" }, { "outPoint": { "txHash": "0x0fb4945d52baf91e0dee2a686cdd9d84cad95b566a1d7409b970ee0a0f364f60", - "index": "2" + "index": "0x2" }, "depType": "code" } ], - "expected": "02000000c12386705b5cbb312b693874f3edf45c43a274482e27b8df0fd80c8d3f5feb8b00000000010fb4945d52baf91e0dee2a686cdd9d84cad95b566a1d7409b970ee0a0f364f600200000000" + "expected": "0x02000000c12386705b5cbb312b693874f3edf45c43a274482e27b8df0fd80c8d3f5feb8b00000000010fb4945d52baf91e0dee2a686cdd9d84cad95b566a1d7409b970ee0a0f364f600200000000" } - ], - "serializeHeaderDeps": [ - { + }, + "serializeHeaderDeps": { + "empty deps": { "headerDeps": [], - "expected": "00000000" + "expected": "0x00000000" }, - { + "basic deps": { "headerDeps": [ "0xc12386705b5cbb312b693874f3edf45c43a274482e27b8df0fd80c8d3f5feb8b", "0x0fb4945d52baf91e0dee2a686cdd9d84cad95b566a1d7409b970ee0a0f364f60" ], - "expected": "02000000c12386705b5cbb312b693874f3edf45c43a274482e27b8df0fd80c8d3f5feb8b0fb4945d52baf91e0dee2a686cdd9d84cad95b566a1d7409b970ee0a0f364f60" + "expected": "0x02000000c12386705b5cbb312b693874f3edf45c43a274482e27b8df0fd80c8d3f5feb8b0fb4945d52baf91e0dee2a686cdd9d84cad95b566a1d7409b970ee0a0f364f60" } - ], - "serializeInputs": [ - { + }, + "serializeInputs": { + "basic inputs": { "inputs": [ { "previousOutput": { "txHash": "0x31f695263423a4b05045dd25ce6692bb55d7bba2965d8be16b036e138e72cc65", - "index": "1" + "index": "0x1" }, - "since": "0" + "since": "0x0" } ], - "expected": "01000000000000000000000031f695263423a4b05045dd25ce6692bb55d7bba2965d8be16b036e138e72cc6501000000" + "expected": "0x01000000000000000000000031f695263423a4b05045dd25ce6692bb55d7bba2965d8be16b036e138e72cc6501000000" } - ], - "serializeOutput": [ - { + }, + "serializeOutput": { + "basic output": { "output": { - "capacity": "100000000000", + "capacity": "0x174876e800", "lock": { "codeHash": "0x68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88", "args": ["0x59a27ef3ba84f061517d13f42cf44ed020610061"], @@ -111,14 +126,14 @@ "hashType": "data" } }, - "expected": "9e00000010000000180000006900000000e87648170000005100000010000000300000003100000068d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e880120000000080000001400000059a27ef3ba84f061517d13f42cf44ed02061006135000000100000003000000031000000ece45e0979030e2f8909f76258631c42333b1e906fd9701ec3600a464a90b8f60004000000" + "expected": "0x9e00000010000000180000006900000000e87648170000005100000010000000300000003100000068d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e880120000000080000001400000059a27ef3ba84f061517d13f42cf44ed02061006135000000100000003000000031000000ece45e0979030e2f8909f76258631c42333b1e906fd9701ec3600a464a90b8f60004000000" } - ], - "serializeOutputs": [ - { + }, + "serializeOutputs": { + "basic outputs": { "outputs": [ { - "capacity": "100000000000", + "capacity": "0x174876e800", "lock": { "codeHash": "0x68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88", "args": ["0x59a27ef3ba84f061517d13f42cf44ed020610061"], @@ -131,7 +146,7 @@ } }, { - "capacity": "98824000000000", + "capacity": "0x59e1416a5000", "lock": { "codeHash": "0x68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88", "args": ["0x59a27ef3ba84f061517d13f42cf44ed020610061"], @@ -140,31 +155,31 @@ "type": null } ], - "expected": "130100000c000000aa0000009e00000010000000180000006900000000e87648170000005100000010000000300000003100000068d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e880120000000080000001400000059a27ef3ba84f061517d13f42cf44ed02061006135000000100000003000000031000000ece45e0979030e2f8909f76258631c42333b1e906fd9701ec3600a464a90b8f600040000006900000010000000180000006900000000506a41e15900005100000010000000300000003100000068d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e880120000000080000001400000059a27ef3ba84f061517d13f42cf44ed020610061" + "expected": "0x130100000c000000aa0000009e00000010000000180000006900000000e87648170000005100000010000000300000003100000068d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e880120000000080000001400000059a27ef3ba84f061517d13f42cf44ed02061006135000000100000003000000031000000ece45e0979030e2f8909f76258631c42333b1e906fd9701ec3600a464a90b8f600040000006900000010000000180000006900000000506a41e15900005100000010000000300000003100000068d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e880120000000080000001400000059a27ef3ba84f061517d13f42cf44ed020610061" } - ], - "serializeOutputsData": [ - { + }, + "serializeOutputsData": { + "basic outputs data": { "outputsData": ["0x", "0x"], - "expected": "140000000c000000100000000000000000000000" + "expected": "0x140000000c000000100000000000000000000000" } - ], - "serializeRawTransaction": [ - { + }, + "serializeRawTransaction": { + "basic raw transaction": { "rawTransaction": { - "version": "0", + "version": "0x0", "cellDeps": [ { "outPoint": { "txHash": "0xc12386705b5cbb312b693874f3edf45c43a274482e27b8df0fd80c8d3f5feb8b", - "index": "0" + "index": "0x0" }, "depType": "depGroup" }, { "outPoint": { "txHash": "0x0fb4945d52baf91e0dee2a686cdd9d84cad95b566a1d7409b970ee0a0f364f60", - "index": "2" + "index": "0x2" }, "depType": "code" } @@ -174,14 +189,14 @@ { "previousOutput": { "txHash": "0x31f695263423a4b05045dd25ce6692bb55d7bba2965d8be16b036e138e72cc65", - "index": "1" + "index": "0x1" }, - "since": "0" + "since": "0x0" } ], "outputs": [ { - "capacity": "100000000000", + "capacity": "0x174876e800", "lock": { "codeHash": "0x68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88", "args": ["0x59a27ef3ba84f061517d13f42cf44ed020610061"], @@ -194,7 +209,7 @@ } }, { - "capacity": "98824000000000", + "capacity": "0x59e1416a5000", "lock": { "codeHash": "0x68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88", "args": ["0x59a27ef3ba84f061517d13f42cf44ed020610061"], @@ -213,7 +228,7 @@ ], "hash": "0x9d1bf801b235ce62812844f01381a070c0cc72876364861e00492eac1d8b54e7" }, - "expected": "c90100001c000000200000006e00000072000000a2000000b50100000000000002000000c12386705b5cbb312b693874f3edf45c43a274482e27b8df0fd80c8d3f5feb8b00000000010fb4945d52baf91e0dee2a686cdd9d84cad95b566a1d7409b970ee0a0f364f6002000000000000000001000000000000000000000031f695263423a4b05045dd25ce6692bb55d7bba2965d8be16b036e138e72cc6501000000130100000c000000aa0000009e00000010000000180000006900000000e87648170000005100000010000000300000003100000068d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e880120000000080000001400000059a27ef3ba84f061517d13f42cf44ed02061006135000000100000003000000031000000ece45e0979030e2f8909f76258631c42333b1e906fd9701ec3600a464a90b8f600040000006900000010000000180000006900000000506a41e15900005100000010000000300000003100000068d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e880120000000080000001400000059a27ef3ba84f061517d13f42cf44ed020610061140000000c000000100000000000000000000000" + "expected": "0xc90100001c000000200000006e00000072000000a2000000b50100000000000002000000c12386705b5cbb312b693874f3edf45c43a274482e27b8df0fd80c8d3f5feb8b00000000010fb4945d52baf91e0dee2a686cdd9d84cad95b566a1d7409b970ee0a0f364f6002000000000000000001000000000000000000000031f695263423a4b05045dd25ce6692bb55d7bba2965d8be16b036e138e72cc6501000000130100000c000000aa0000009e00000010000000180000006900000000e87648170000005100000010000000300000003100000068d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e880120000000080000001400000059a27ef3ba84f061517d13f42cf44ed02061006135000000100000003000000031000000ece45e0979030e2f8909f76258631c42333b1e906fd9701ec3600a464a90b8f600040000006900000010000000180000006900000000506a41e15900005100000010000000300000003100000068d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e880120000000080000001400000059a27ef3ba84f061517d13f42cf44ed020610061140000000c000000100000000000000000000000" } - ] + } } diff --git a/packages/ckb-sdk-utils/__tests__/serialization/transaction/index.test.js b/packages/ckb-sdk-utils/__tests__/serialization/transaction/index.test.js index 2b78f3ac..ecfb5596 100644 --- a/packages/ckb-sdk-utils/__tests__/serialization/transaction/index.test.js +++ b/packages/ckb-sdk-utils/__tests__/serialization/transaction/index.test.js @@ -15,105 +15,175 @@ const fixtures = require('./fixtures.json') describe('Test Transaction Serialization', () => { describe('Serialize Version', () => { - const fixtureTable = fixtures.serializeVersion.map(({ version, expected }) => [version, expected]) - test.each(fixtureTable)('%s => %s', (version, expected) => { - expect(serializeVersion(version)).toBe(expected) - }) - - it('throw an error if the version is not a string', () => { - expect(() => serializeVersion(undefined)).toThrow( - new TypeError('The version to be serialized should be the type of string') - ) - }) - - it('throw an error if the version is a hex string', () => { - expect(() => serializeVersion('0x10')).toThrow( - new Error('The value of the version should be the type of integer') - ) - }) - - it('throw an error if the version is unable to be converted to a integer', () => { - expect(() => serializeVersion('xxx')).toThrow(new Error('The value of the version should be the type of integer')) + const fixtureTable = Object.entries(fixtures.serializeVersion).map(([title, { version, expected, exception }]) => [ + title, + version, + expected, + exception, + ]) + test.each(fixtureTable)('%s', (_title, version, expected, exception) => { + if (undefined !== expected) { + expect(serializeVersion(version)).toBe(expected) + } + if (undefined !== exception) { + expect(() => serializeVersion(version)).toThrow(new Error(exception)) + } }) }) describe('Serialize OutPoint', () => { - const fixtureTable = fixtures.serializeOutPoint.map(({ outPoint, expected }) => [outPoint, expected]) - - test.each(fixtureTable)('%s => %s', (outPoint, expected) => { - expect(serializeOutPoint(outPoint)).toBe(expected) + const fixtureTable = Object.entries(fixtures.serializeOutPoint).map( + ([title, { outPoint, expected, exception }]) => [title, outPoint, expected, exception] + ) + + test.each(fixtureTable)('%s', (_title, outPoint, expected, exception) => { + if (undefined !== expected) { + expect(serializeOutPoint(outPoint)).toBe(expected) + } + if (undefined !== exception) { + expect(() => serializeOutPoint(outPoint)).toThrow(new Error(exception)) + } }) }) describe('Serialize DepType', () => { - const fixtureTable = fixtures.serializeDepType.map(({ depType, expected }) => [depType, expected]) - test.each(fixtureTable)('%s => %s', (depType, expected) => { - expect(serializeDepType(depType)).toBe(expected) - }) - - it("throw an error if the dep type is neither of 'data' nor 'depGroup'", () => { - expect(() => serializeDepType('unknown type')).toThrow( - new TypeError("Dep type must be either of 'code' or 'depGroup'") - ) + const fixtureTable = Object.entries(fixtures.serializeDepType).map(([title, { depType, expected, exception }]) => [ + title, + depType, + expected, + exception, + ]) + test.each(fixtureTable)('%s', (_title, depType, expected, exception) => { + if (undefined !== expected) { + expect(serializeDepType(depType)).toBe(expected) + } + if (undefined !== exception) { + expect(() => serializeDepType(depType)).toThrow(new Error(exception)) + } }) }) describe('Serialize CellDep', () => { - const fixtureTable = fixtures.serializeCellDep.map(({ cellDep, expected }) => [cellDep, expected]) - test.each(fixtureTable)('%s => %s', (cellDep, expected) => { - expect(serializeCellDep(cellDep)).toBe(expected) + const fixtureTable = Object.entries(fixtures.serializeCellDep).map(([title, { cellDep, expected, exception }]) => [ + title, + cellDep, + expected, + exception, + ]) + test.each(fixtureTable)('%s', (_title, cellDep, expected, exception) => { + if (undefined !== expected) { + expect(serializeCellDep(cellDep)).toBe(expected) + } + if (undefined !== exception) { + expect(() => serializeCellDep(cellDep)).toThrow(new Error(exception)) + } }) }) describe('Serialize CellDeps', () => { - const fixtureTable = fixtures.serializeCellDeps.map(({ cellDeps, expected }) => [cellDeps, expected]) - test.each(fixtureTable)('%j => %s', (cellDeps, expected) => { - expect(serializeCellDeps(cellDeps)).toBe(expected) + const fixtureTable = Object.entries(fixtures.serializeCellDeps).map( + ([title, { cellDeps, expected, exception }]) => [title, cellDeps, expected, exception] + ) + test.each(fixtureTable)('%j', (_title, cellDeps, expected, exception) => { + if (undefined !== expected) { + expect(serializeCellDeps(cellDeps)).toBe(expected) + } + if (undefined !== exception) { + expect(() => serializeCellDeps(cellDeps)).toThrow(new Error(exception)) + } }) }) describe('Serialize HeaderDeps', () => { - const fixtureTable = fixtures.serializeHeaderDeps.map(({ headerDeps, expected }) => [headerDeps, expected]) - test.each(fixtureTable)('%j => %s', (headerDeps, expected) => { - expect(serializeHeaderDeps(headerDeps)).toBe(expected) + const fixtureTable = Object.entries(fixtures.serializeHeaderDeps).map( + ([title, { headerDeps, expected, exception }]) => [title, headerDeps, expected, exception] + ) + test.each(fixtureTable)('%j', (_title, headerDeps, expected, exception) => { + if (undefined !== expected) { + expect(serializeHeaderDeps(headerDeps)).toBe(expected) + } + if (undefined !== exception) { + expect(() => serializeHeaderDeps(headerDeps)).toThrow(new Error(exception)) + } }) }) describe('Serialize Inputs', () => { - const fixtureTable = fixtures.serializeInputs.map(({ inputs, expected }) => [inputs, expected]) - test.each(fixtureTable)('%j => %s', (inputs, expected) => { - expect(serializeInputs(inputs)).toBe(expected) + const fixtureTable = Object.entries(fixtures.serializeInputs).map(([title, { inputs, expected, exception }]) => [ + title, + inputs, + expected, + exception, + ]) + test.each(fixtureTable)('%j', (_title, inputs, expected, exception) => { + if (undefined !== expected) { + expect(serializeInputs(inputs)).toBe(expected) + } + if (undefined !== exception) { + expect(() => serializeInputs(inputs)).toThrow(new Error(exception)) + } }) }) describe('Serialize Output', () => { - const fixtureTable = fixtures.serializeOutput.map(({ output, expected }) => [output, expected]) - test.each(fixtureTable)('%j => %s', (output, expected) => { - expect(serializeOutput(output)).toBe(expected) + const fixtureTable = Object.entries(fixtures.serializeOutput).map(([title, { output, expected, exception }]) => [ + title, + output, + expected, + exception, + ]) + test.each(fixtureTable)('%j', (_title, output, expected, exception) => { + if (undefined !== expected) { + expect(serializeOutput(output)).toBe(expected) + } + if (undefined !== exception) { + expect(() => serializeOutput(output)).toThrow(new Error(exception)) + } }) }) describe('Serialize Outputs', () => { - const fixtureTable = fixtures.serializeOutputs.map(({ outputs, expected }) => [outputs, expected]) - test.each(fixtureTable)('%j => %s', (outputs, expected) => { - expect(serializeOutputs(outputs)).toBe(expected) + const fixtureTable = Object.entries(fixtures.serializeOutputs).map(([title, { outputs, expected, exception }]) => [ + title, + outputs, + expected, + exception, + ]) + test.each(fixtureTable)('%j', (_title, outputs, expected, exception) => { + if (undefined !== expected) { + expect(serializeOutputs(outputs)).toBe(expected) + } + if (undefined !== exception) { + expect(() => serializeOutputs(outputs)).toThrow(new Error(exception)) + } }) }) describe('Serialize OutputsData', () => { - const fixtureTable = fixtures.serializeOutputsData.map(({ outputsData, expected }) => [outputsData, expected]) - test.each(fixtureTable)('%j => %s', (outputsData, expected) => { - expect(serializeOutputsData(outputsData)).toBe(expected) + const fixtureTable = Object.entries(fixtures.serializeOutputsData).map( + ([title, { outputsData, expected, exception }]) => [title, outputsData, expected, exception] + ) + test.each(fixtureTable)('%j', (_title, outputsData, expected, exception) => { + if (undefined !== expected) { + expect(serializeOutputsData(outputsData)).toBe(expected) + } + if (undefined !== exception) { + expect(() => serializeOutputsData(outputsData)).toThrow(new Error(exception)) + } }) }) describe('Serialize RawTransaction', () => { - const fixtureTable = fixtures.serializeRawTransaction.map(({ rawTransaction, expected }) => [ - rawTransaction, - expected, - ]) - test.each(fixtureTable)('%j => %s', (rawTransaction, expected) => { - expect(serializeRawTransaction(rawTransaction)).toBe(expected) + const fixtureTable = Object.entries(fixtures.serializeRawTransaction).map( + ([title, { rawTransaction, expected, exception }]) => [title, rawTransaction, expected, exception] + ) + test.each(fixtureTable)('%j', (_title, rawTransaction, expected, exception) => { + if (undefined !== expected) { + expect(serializeRawTransaction(rawTransaction)).toBe(expected) + } + if (undefined !== exception) { + expect(() => serializeRawTransaction(rawTransaction)).toThrow(new Error(exception)) + } }) }) }) diff --git a/packages/ckb-sdk-utils/__tests__/utils/bech32-fixtures.json b/packages/ckb-sdk-utils/__tests__/utils/bech32.fixtures.json similarity index 100% rename from packages/ckb-sdk-utils/__tests__/utils/bech32-fixtures.json rename to packages/ckb-sdk-utils/__tests__/utils/bech32.fixtures.json diff --git a/packages/ckb-sdk-utils/__tests__/utils/ckb-utils.test.js b/packages/ckb-sdk-utils/__tests__/utils/index.test.js similarity index 62% rename from packages/ckb-sdk-utils/__tests__/utils/ckb-utils.test.js rename to packages/ckb-sdk-utils/__tests__/utils/index.test.js index a28aeeef..1a25a281 100644 --- a/packages/ckb-sdk-utils/__tests__/utils/ckb-utils.test.js +++ b/packages/ckb-sdk-utils/__tests__/utils/index.test.js @@ -1,6 +1,9 @@ const ckbUtils = require('../../lib') -const bech32Fixtures = require('./bech32-fixtures.json') +const exceptions = require('../../lib/exceptions') +const bech32Fixtures = require('./bech32.fixtures.json') const rawTransactionToHashFixtures = require('./rawTransactionToHash.fixtures.json') +const transformerFixtures = require('./transformer.fixtures.json') +const { ArgumentRequired } = require('../../lib/exceptions') const { blake2b, @@ -20,58 +23,57 @@ const { toHexInLittleEndian, } = ckbUtils -describe('format', () => { - it('hex to bytes', () => { - const fixture = { - hex: 'abcd12', - bytes: [171, 205, 18], - } - const bytes = hexToBytes(fixture.hex) - expect(bytes.join(',')).toBe(fixture.bytes.join(',')) - }) +const { HexStringShouldStartWith0x, InvalidHexString } = exceptions - it('bytes to hex', () => { - const fixture = { - bytes: [171, 205, 18], - hex: 'abcd12', - } - const hex = bytesToHex(fixture.bytes) - expect(hex).toBe(fixture.hex) +describe('transformer', () => { + describe('hex to bytes', () => { + const fixtureTable = transformerFixtures.hexToBytes.map(({ hex, expected }) => [hex, expected]) + test.each(fixtureTable)('%s => %j', (hex, exptected) => { + expect(hexToBytes(hex).join(',')).toBe(exptected.join(',')) + }) + + it('hex string without 0x should throw an error', () => { + expect(() => hexToBytes('abcd12')).toThrow(new HexStringShouldStartWith0x('abcd12')) + }) }) - /* eslint-disable max-len */ - it('utf8 to hex', () => { - const utf8Str = - 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.' + describe('bytes to hex', () => { + const fixtureTable = transformerFixtures.bytesToHex.map(({ bytes, expected }) => [bytes, expected]) + test.each(fixtureTable)('%j => %s', (bytes, expected) => { + expect(bytesToHex(bytes)).toEqual(expected) + }) + }) - const byBuffer = Buffer.from(utf8Str, 'utf8').toString('hex') - const byUtils = utf8ToHex(utf8Str) - expect(byUtils).toBe(byBuffer) + describe('utf8 to hex', () => { + const fixtureTable = transformerFixtures.utf8ToHex.map(({ utf8, expected }) => [utf8, expected]) + test.each(fixtureTable)('%s => %s', (utf8, expected) => { + expect(utf8ToHex(utf8)).toBe(expected) + }) }) - it('hex to utf8', () => { - const hexStr = - '4c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e7365637465747572206164697069736963696e6720656c69742c2073656420646f20656975736d6f642074656d706f7220696e6369646964756e74207574206c61626f726520657420646f6c6f7265206d61676e6120616c697175612e20557420656e696d206164206d696e696d2076656e69616d2c2071756973206e6f737472756420657865726369746174696f6e20756c6c616d636f206c61626f726973206e69736920757420616c697175697020657820656120636f6d6d6f646f20636f6e7365717561742e2044756973206175746520697275726520646f6c6f7220696e20726570726568656e646572697420696e20766f6c7570746174652076656c697420657373652063696c6c756d20646f6c6f726520657520667567696174206e756c6c612070617269617475722e204578636570746575722073696e74206f6363616563617420637570696461746174206e6f6e2070726f6964656e742c2073756e7420696e2063756c706120717569206f666669636961206465736572756e74206d6f6c6c697420616e696d20696420657374206c61626f72756d2e' - const byBuffer = Buffer.from(hexStr, 'hex').toString('utf8') - const byUtils = hexToUtf8(hexStr) - expect(byUtils).toBe(byBuffer) + describe('hex to utf8', () => { + const fixtureTable = transformerFixtures.hexToUtf8.map(({ hex, expected }) => [hex, expected]) + test.each(fixtureTable)('%s => %s', (hex, expected) => { + expect(hexToUtf8(hex)).toBe(expected) + }) + + it('hex string without 0x should throw an error', () => { + expect(() => hexToBytes('abcd')).toThrow(new HexStringShouldStartWith0x('abcd')) + }) }) describe('Test toHexInLittleEndian', () => { - it('convert number to hex in little endian', () => { - expect(toHexInLittleEndian('0x3e8')).toBe('e8030000') + const fixtureTable = transformerFixtures.toHexInLittleEndian.map(({ value, expected }) => [value, expected]) + test.each(fixtureTable)('%s => %s', (value, expected) => { + expect(toHexInLittleEndian(value)).toBe(expected) }) - - it('convert number to hex in little endian', () => { - expect(toHexInLittleEndian(0x3e8)).toBe('e8030000') + it('hex string without 0x should throw an error', () => { + expect(() => toHexInLittleEndian('123')).toThrow(new HexStringShouldStartWith0x('123')) }) it('throw an error when received a input unable to be converted into a number', () => { - expect(() => toHexInLittleEndian('invalid number')).toThrow( - new TypeError('The input cannot be converted to a number') - ) + expect(() => toHexInLittleEndian('invalid number')).toThrow(new InvalidHexString('invalid number')) }) }) - /* eslint-enable max-len */ }) describe('blake', () => { @@ -148,7 +150,7 @@ describe('scriptToHash', () => { args: [], hashType: 'data', }, - scriptHash: 'bd7e6000ffb8e983a6023809037e0c4cedbc983637c46d74621fd28e5f15fe4f', + scriptHash: '0xbd7e6000ffb8e983a6023809037e0c4cedbc983637c46d74621fd28e5f15fe4f', }, 'Script with hash type of data': { script: { @@ -156,7 +158,7 @@ describe('scriptToHash', () => { args: ['0x01'], hashType: 'data', }, - scriptHash: '5a2b913dfb1b79136fc72a575fd8e93ae080b504463c0066fea086482bfc3a94', + scriptHash: '0x5a2b913dfb1b79136fc72a575fd8e93ae080b504463c0066fea086482bfc3a94', }, 'Script with hash type of type': { script: { @@ -164,7 +166,7 @@ describe('scriptToHash', () => { args: ['0x01'], hashType: 'type', }, - scriptHash: '3d7e565f3831955f0f5cfecdadddeef7e0d106af84ceb0c2f4dbb6ddff88c9bc', + scriptHash: '0x3d7e565f3831955f0f5cfecdadddeef7e0d106af84ceb0c2f4dbb6ddff88c9bc', }, } test.each(Object.keys(fixtures))('%s', fixtureName => { @@ -172,6 +174,10 @@ describe('scriptToHash', () => { const scriptHash = scriptToHash(fixture.script) expect(scriptHash).toBe(fixture.scriptHash) }) + + it('empty input should throw an error', () => { + expect(() => scriptToHash()).toThrow(new ArgumentRequired('Script')) + }) }) describe('rawTransactionToHash', () => { @@ -189,72 +195,77 @@ describe('rawTransactionToHash', () => { }) describe('address', () => { - it('identifier to address payload', () => { + it('publicKeyHash to address payload', () => { const fixture = { - identifier: '36c329ed630d6ce750712a477543672adab57f4c', - payload: '010036c329ed630d6ce750712a477543672adab57f4c', + publicKeyHash: '0x36c329ed630d6ce750712a477543672adab57f4c', + payload: '0x010036c329ed630d6ce750712a477543672adab57f4c', } - const payload = bytesToHex(toAddressPayload(fixture.identifier)) + const payload = bytesToHex(toAddressPayload(fixture.publicKeyHash)) expect(payload).toBe(fixture.payload) }) - it('identifier to address with prefix of ckt', () => { + it('publicKeyHash to address with prefix of ckt', () => { const fixture = { - identifier: '36c329ed630d6ce750712a477543672adab57f4c', + publicKeyHash: '0x36c329ed630d6ce750712a477543672adab57f4c', prefix: 'ckt', address: 'ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83', } - const address = bech32Address(fixture.identifier, { + const address = bech32Address(fixture.publicKeyHash, { prefix: fixture.prefix, }) expect(address).toBe(fixture.address) }) - it('identifier to address with prefix of ckb', () => { + it('publicKeyHash to address with prefix of ckb', () => { const fixture = { - identifier: '36c329ed630d6ce750712a477543672adab57f4c', + publicKeyHash: '0x36c329ed630d6ce750712a477543672adab57f4c', prefix: 'ckb', address: 'ckb1qyqrdsefa43s6m882pcj53m4gdnj4k440axqdt9rtd', } - const address = bech32Address(fixture.identifier, { + const address = bech32Address(fixture.publicKeyHash, { prefix: fixture.prefix, }) expect(address).toBe(fixture.address) }) + it('publicKeyHash without 0x should throw an error', () => { + const publicKeyHash = '36c329ed630d6ce750712a477543672adab57f4c' + expect(() => toAddressPayload(publicKeyHash)).toThrow(new HexStringShouldStartWith0x(publicKeyHash)) + }) + it('bech32Address with empty options', () => { const fixture = { - identifier: '36c329ed630d6ce750712a477543672adab57f4c', + publicKeyHash: '0x36c329ed630d6ce750712a477543672adab57f4c', address: 'ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83', } - const address = bech32Address(fixture.identifier, {}) + const address = bech32Address(fixture.publicKeyHash, {}) expect(address).toBe(fixture.address) }) it('bech32Address with default options which should be prefix: ckb, type: binIndx, code hash index: 0x00', () => { const fixture = { - identifier: '36c329ed630d6ce750712a477543672adab57f4c', + publicKeyHash: '0x36c329ed630d6ce750712a477543672adab57f4c', address: 'ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83', } - const address = bech32Address(fixture.identifier) + const address = bech32Address(fixture.publicKeyHash) expect(address).toBe(fixture.address) }) const pubkeyToAddressFixtures = { 'with configuration of { prefix: ckt }': { - pubkey: '024a501efd328e062c8675f2365970728c859c592beeefd6be8ead3d901330bc01', + pubkey: '0x024a501efd328e062c8675f2365970728c859c592beeefd6be8ead3d901330bc01', config: { prefix: 'ckt', }, address: 'ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83', }, 'with empty configuration': { - pubkey: '024a501efd328e062c8675f2365970728c859c592beeefd6be8ead3d901330bc01', + pubkey: '0x024a501efd328e062c8675f2365970728c859c592beeefd6be8ead3d901330bc01', config: {}, address: 'ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83', }, 'with undefined configuration': { - pubkey: '024a501efd328e062c8675f2365970728c859c592beeefd6be8ead3d901330bc01', + pubkey: '0x024a501efd328e062c8675f2365970728c859c592beeefd6be8ead3d901330bc01', config: undefined, address: 'ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83', }, @@ -273,9 +284,9 @@ describe('address', () => { blake160Pubkey: '36c329ed630d6ce750712a477543672adab57f4c', } const parsedHex = parseAddress(fixture.addr, fixture.prefix, 'hex') - expect(parsedHex).toBe(fixture.hrp + fixture.blake160Pubkey) + expect(parsedHex).toBe(`0x${fixture.hrp}${fixture.blake160Pubkey}`) const parsedBytes = parseAddress(fixture.addr, fixture.prefix) - expect(bytesToHex(parsedBytes)).toBe(fixture.hrp + fixture.blake160Pubkey) + expect(bytesToHex(parsedBytes)).toBe(`0x${fixture.hrp}${fixture.blake160Pubkey}`) }) it('parse address with default options prefix: ckt, encode: binary', () => { @@ -286,9 +297,9 @@ describe('address', () => { blake160Pubkey: '36c329ed630d6ce750712a477543672adab57f4c', } const parsedHex = bytesToHex(parseAddress(fixture.addr)) - expect(parsedHex).toBe(fixture.hrp + fixture.blake160Pubkey) + expect(parsedHex).toBe(`0x${fixture.hrp}${fixture.blake160Pubkey}`) const parsedBytes = parseAddress(fixture.addr, fixture.prefix) - expect(bytesToHex(parsedBytes)).toBe(fixture.hrp + fixture.blake160Pubkey) + expect(bytesToHex(parsedBytes)).toBe(`0x${fixture.hrp}${fixture.blake160Pubkey}`) }) it('parser incorrect address', () => { diff --git a/packages/ckb-sdk-utils/__tests__/utils/rawTransactionToHash.fixtures.json b/packages/ckb-sdk-utils/__tests__/utils/rawTransactionToHash.fixtures.json index 593e4451..b2676c24 100644 --- a/packages/ckb-sdk-utils/__tests__/utils/rawTransactionToHash.fixtures.json +++ b/packages/ckb-sdk-utils/__tests__/utils/rawTransactionToHash.fixtures.json @@ -2,19 +2,19 @@ "rawTransactionToHash": [ { "rawTransaction": { - "version": "0", + "version": "0x0", "cellDeps": [ { "outPoint": { "txHash": "0xc12386705b5cbb312b693874f3edf45c43a274482e27b8df0fd80c8d3f5feb8b", - "index": "0" + "index": "0x0" }, "depType": "depGroup" }, { "outPoint": { "txHash": "0x0fb4945d52baf91e0dee2a686cdd9d84cad95b566a1d7409b970ee0a0f364f60", - "index": "2" + "index": "0x2" }, "depType": "code" } @@ -24,14 +24,14 @@ { "previousOutput": { "txHash": "0x31f695263423a4b05045dd25ce6692bb55d7bba2965d8be16b036e138e72cc65", - "index": "1" + "index": "0x1" }, - "since": "0" + "since": "0x0" } ], "outputs": [ { - "capacity": "100000000000", + "capacity": "0x174876e800", "lock": { "codeHash": "0x68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88", "args": ["0x59a27ef3ba84f061517d13f42cf44ed020610061"], @@ -44,7 +44,7 @@ } }, { - "capacity": "98824000000000", + "capacity": "0x59e1416a5000", "lock": { "codeHash": "0x68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88", "args": ["0x59a27ef3ba84f061517d13f42cf44ed020610061"], @@ -63,7 +63,7 @@ ], "hash": "0x9d1bf801b235ce62812844f01381a070c0cc72876364861e00492eac1d8b54e7" }, - "expected": "09ce2223304a5f48d5ce2b6ee2777d96503591279671460fa39ae894ea9e2b87" + "expected": "0x09ce2223304a5f48d5ce2b6ee2777d96503591279671460fa39ae894ea9e2b87" } ] } diff --git a/packages/ckb-sdk-utils/__tests__/utils/transformer.fixtures.json b/packages/ckb-sdk-utils/__tests__/utils/transformer.fixtures.json new file mode 100644 index 00000000..622d806e --- /dev/null +++ b/packages/ckb-sdk-utils/__tests__/utils/transformer.fixtures.json @@ -0,0 +1,44 @@ +{ + "hexToBytes": [ + { + "hex": "", + "expected": [] + }, + { + "hex": "0xabcd12", + "expected": [171, 205, 18] + }, + { + "hex": 11259154, + "expected": [171, 205, 18] + } + ], + "bytesToHex": [ + { + "bytes": [171, 205, 18], + "expected": "0xabcd12" + } + ], + "utf8ToHex": [ + { + "utf8": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + "expected": "0x4c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e7365637465747572206164697069736963696e6720656c69742c2073656420646f20656975736d6f642074656d706f7220696e6369646964756e74207574206c61626f726520657420646f6c6f7265206d61676e6120616c697175612e20557420656e696d206164206d696e696d2076656e69616d2c2071756973206e6f737472756420657865726369746174696f6e20756c6c616d636f206c61626f726973206e69736920757420616c697175697020657820656120636f6d6d6f646f20636f6e7365717561742e2044756973206175746520697275726520646f6c6f7220696e20726570726568656e646572697420696e20766f6c7570746174652076656c697420657373652063696c6c756d20646f6c6f726520657520667567696174206e756c6c612070617269617475722e204578636570746575722073696e74206f6363616563617420637570696461746174206e6f6e2070726f6964656e742c2073756e7420696e2063756c706120717569206f666669636961206465736572756e74206d6f6c6c697420616e696d20696420657374206c61626f72756d2e" + } + ], + "hexToUtf8": [ + { + "hex": "0x4c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e7365637465747572206164697069736963696e6720656c69742c2073656420646f20656975736d6f642074656d706f7220696e6369646964756e74207574206c61626f726520657420646f6c6f7265206d61676e6120616c697175612e20557420656e696d206164206d696e696d2076656e69616d2c2071756973206e6f737472756420657865726369746174696f6e20756c6c616d636f206c61626f726973206e69736920757420616c697175697020657820656120636f6d6d6f646f20636f6e7365717561742e2044756973206175746520697275726520646f6c6f7220696e20726570726568656e646572697420696e20766f6c7570746174652076656c697420657373652063696c6c756d20646f6c6f726520657520667567696174206e756c6c612070617269617475722e204578636570746575722073696e74206f6363616563617420637570696461746174206e6f6e2070726f6964656e742c2073756e7420696e2063756c706120717569206f666669636961206465736572756e74206d6f6c6c697420616e696d20696420657374206c61626f72756d2e", + "expected": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." + } + ], + "toHexInLittleEndian": [ + { + "value": "0x3e8", + "expected": "0xe8030000" + }, + { + "value": 1000, + "expected": "0xe8030000" + } + ] +} diff --git a/packages/ckb-sdk-utils/package.json b/packages/ckb-sdk-utils/package.json index 79634bc9..92f53944 100644 --- a/packages/ckb-sdk-utils/package.json +++ b/packages/ckb-sdk-utils/package.json @@ -1,6 +1,6 @@ { "name": "@nervosnetwork/ckb-sdk-utils", - "version": "0.20.0", + "version": "0.21.0", "description": "Utils module of @nervosnetwork/ckb-sdk-core", "author": "Nervos ", "homepage": "https://github.com/nervosnetwork/ckb-sdk-js#readme", @@ -30,14 +30,14 @@ "url": "https://github.com/nervosnetwork/ckb-sdk-js/issues" }, "dependencies": { - "@nervosnetwork/ckb-types": "0.20.0", + "@nervosnetwork/ckb-types": "0.21.0", "blake2b-wasm": "1.1.7", - "elliptic": "6.4.1" + "elliptic": "6.5.1" }, "devDependencies": { "@types/bitcoinjs-lib": "4.0.1", "@types/elliptic": "6.4.8", "@types/utf8": "2.1.6" }, - "gitHead": "478433630dd40501f1f67dc259bf9d252c56fcd3" + "gitHead": "5a1aaff6006c91e45e8ba39ceb6ef7c2f870e6cd" } diff --git a/packages/ckb-sdk-utils/src/address/index.ts b/packages/ckb-sdk-utils/src/address/index.ts index 892f3414..053bc0fd 100644 --- a/packages/ckb-sdk-utils/src/address/index.ts +++ b/packages/ckb-sdk-utils/src/address/index.ts @@ -1,4 +1,5 @@ import { bech32, blake160, hexToBytes, bytesToHex } from '..' +import { HexStringShouldStartWith0x } from '../exceptions' export enum AddressPrefix { Mainnet = 'ckb', @@ -29,24 +30,27 @@ export const defaultAddressOptions = { * @see https://github.com/nervosnetwork/ckb/wiki/Common-Address-Format */ export const toAddressPayload = ( - identifier: string | Uint8Array, + publicKeyHash: string | Uint8Array, type: AddressType = AddressType.HashIdx, params: CodeHashIndex = '0x00' ): Uint8Array => { - if (typeof identifier === 'string') { - return new Uint8Array([...hexToBytes(type), ...hexToBytes(params), ...hexToBytes(identifier)]) + if (typeof publicKeyHash === 'string') { + if (!publicKeyHash.startsWith('0x')) { + throw new HexStringShouldStartWith0x(publicKeyHash) + } + return new Uint8Array([...hexToBytes(type), ...hexToBytes(params), ...hexToBytes(publicKeyHash)]) } - return new Uint8Array([...hexToBytes(type), ...hexToBytes(params), ...identifier]) + return new Uint8Array([...hexToBytes(type), ...hexToBytes(params), ...publicKeyHash]) } export const bech32Address = ( - identifier: Uint8Array | string, + publicKeyHash: Uint8Array | string, { prefix = AddressPrefix.Testnet, type = AddressType.HashIdx, codeHashIndex = '0x00', }: AddressOptions = defaultAddressOptions -) => bech32.encode(prefix, bech32.toWords(toAddressPayload(identifier, type, codeHashIndex))) +) => bech32.encode(prefix, bech32.toWords(toAddressPayload(publicKeyHash, type, codeHashIndex))) export const pubkeyToAddress = ( pubkey: Uint8Array | string, @@ -56,8 +60,8 @@ export const pubkeyToAddress = ( codeHashIndex = '0x00' as CodeHashIndex, }: AddressOptions = defaultAddressOptions ) => { - const identifier = blake160(pubkey) - return bech32Address(identifier, { + const publicKeyHash = blake160(pubkey) + return bech32Address(publicKeyHash, { prefix, type, codeHashIndex, diff --git a/packages/ckb-sdk-utils/src/ecpair.ts b/packages/ckb-sdk-utils/src/ecpair.ts index 4476a910..602555ef 100644 --- a/packages/ckb-sdk-utils/src/ecpair.ts +++ b/packages/ckb-sdk-utils/src/ecpair.ts @@ -1,6 +1,7 @@ import { ec as EC } from 'elliptic' import { hexToBytes } from '.' +import { HexStringShouldStartWith0x, ArgumentRequired } from './exceptions' const ec = new EC('secp256k1') @@ -19,30 +20,43 @@ class ECPair { compressed: true, } ) { - if (typeof sk === 'undefined') throw new Error('Private key is required') - this.key = ec.keyFromPrivate(sk) + if (sk === undefined) throw new ArgumentRequired('Private key') + if (typeof sk === 'string' && !sk.startsWith('0x')) { + throw new HexStringShouldStartWith0x(sk) + } + this.key = ec.keyFromPrivate(typeof sk === 'string' ? sk.replace(/^0x/, '') : sk) this.compressed = compressed } get privateKey() { - return this.key.getPrivate('hex') + return `0x${this.key.getPrivate('hex')}` } get publicKey() { - return this.key.getPublic(this.compressed, 'hex') as string + return `0x${this.key.getPublic(this.compressed, 'hex') as string}` } - public getPrivateKey = (enc: 'hex' = 'hex') => this.key.getPrivate(enc) + public getPrivateKey = (enc: 'hex' = 'hex') => { + if (enc === 'hex') { + return this.privateKey + } + return this.key.getPrivate(enc) + } - public getPublicKey = (enc: 'hex' | 'array') => this.key.getPublic(this.compressed, enc) + public getPublicKey = (enc: 'hex' | 'array') => { + if (enc === 'hex') { + return this.publicKey + } + return this.key.getPublic(this.compressed, enc) + } public sign = (message: string | Uint8Array): string => { const msg = typeof message === 'string' ? hexToBytes(message) : message - return this.key + return `0x${this.key .sign(msg, { canonical: true, }) - .toDER('hex') + .toDER('hex')}` } public verify = (message: string | Buffer, sig: string | Buffer) => { @@ -59,7 +73,7 @@ class ECPair { if (recoveryParam === null) throw new Error('Fail to sign the message') const fmtR = r.toString(16).padStart(64, '0') const fmtS = s.toString(16).padStart(64, '0') - return `${fmtR}${fmtS}0${recoveryParam}` + return `0x${fmtR}${fmtS}0${recoveryParam}` } } diff --git a/packages/ckb-sdk-utils/src/exceptions/argumentRequired.ts b/packages/ckb-sdk-utils/src/exceptions/argumentRequired.ts new file mode 100644 index 00000000..3d69b648 --- /dev/null +++ b/packages/ckb-sdk-utils/src/exceptions/argumentRequired.ts @@ -0,0 +1,5 @@ +export default class extends Error { + constructor(name: string) { + super(`${name} is required`) + } +} diff --git a/packages/ckb-sdk-utils/src/exceptions/hexStringShouldStartWith0x.ts b/packages/ckb-sdk-utils/src/exceptions/hexStringShouldStartWith0x.ts new file mode 100644 index 00000000..f66c721f --- /dev/null +++ b/packages/ckb-sdk-utils/src/exceptions/hexStringShouldStartWith0x.ts @@ -0,0 +1,5 @@ +export default class extends Error { + constructor(hex: string) { + super(`Hex string ${hex} should start with 0x`) + } +} diff --git a/packages/ckb-sdk-utils/src/exceptions/index.ts b/packages/ckb-sdk-utils/src/exceptions/index.ts new file mode 100644 index 00000000..7675dace --- /dev/null +++ b/packages/ckb-sdk-utils/src/exceptions/index.ts @@ -0,0 +1,11 @@ +import HexStringShouldStartWith0x from './hexStringShouldStartWith0x' +import ArgumentRequired from './argumentRequired' +import InvalidHexString from './invalidHexString' + +export { HexStringShouldStartWith0x, ArgumentRequired, InvalidHexString } + +export default { + HexStringShouldStartWith0x, + ArgumentRequired, + InvalidHexString, +} diff --git a/packages/ckb-sdk-utils/src/exceptions/invalidHexString.ts b/packages/ckb-sdk-utils/src/exceptions/invalidHexString.ts new file mode 100644 index 00000000..e26f1bde --- /dev/null +++ b/packages/ckb-sdk-utils/src/exceptions/invalidHexString.ts @@ -0,0 +1,5 @@ +export default class extends Error { + constructor(hex: string) { + super(`${hex} is an invalid hex string`) + } +} diff --git a/packages/ckb-sdk-utils/src/index.ts b/packages/ckb-sdk-utils/src/index.ts index db9f7fe2..12130166 100644 --- a/packages/ckb-sdk-utils/src/index.ts +++ b/packages/ckb-sdk-utils/src/index.ts @@ -1,4 +1,5 @@ import * as util from 'util' +import { HexStringShouldStartWith0x, ArgumentRequired, InvalidHexString } from './exceptions' import crypto from './crypto' import { serializeScript } from './serialization/script' import { serializeRawTransaction } from './serialization/transaction' @@ -15,7 +16,11 @@ const textEncoder = new (typeof TextEncoder !== 'undefined' ? TextEncoder : util const textDecoder = new (typeof TextDecoder !== 'undefined' ? TextDecoder : util.TextDecoder)() export const PERSONAL = textEncoder.encode('ckb-default-hash') -export const hexToBytes = (rawhex: any) => { +export const hexToBytes = (rawhex: string | number) => { + if (rawhex === '') return new Uint8Array() + if (typeof rawhex === 'string' && !rawhex.startsWith('0x')) { + throw new HexStringShouldStartWith0x(rawhex) + } let hex = rawhex.toString(16) hex = hex.replace(/^0x/i, '') @@ -37,7 +42,7 @@ export const bytesToHex = (bytes: Uint8Array): string => { hex.push((bytes[i] & 0xf).toString(16)) } /* eslint-enabled */ - return hex.join('') + return `0x${hex.join('')}` } export const bytesToUtf8 = (bytes: Uint8Array) => textDecoder.decode(bytes) @@ -49,21 +54,21 @@ export const utf8ToBytes = (str: string) => textEncoder.encode(str) export const utf8ToHex = (str: string) => bytesToHex(utf8ToBytes(str)) export const scriptToHash = (script: CKBComponents.Script) => { - if (!script) throw new Error('Script is required') + if (!script) throw new ArgumentRequired('Script') const serializedScript = serializeScript(script) const s = blake2b(32, null, null, PERSONAL) s.update(hexToBytes(serializedScript)) const digest = s.digest('hex') - return digest as string + return `0x${digest}` as string } export const rawTransactionToHash = (rawTransaction: CKBComponents.RawTransaction) => { - if (!rawTransaction) throw new Error('Raw transaction is required') + if (!rawTransaction) throw new ArgumentRequired('Raw transaction') const serializedRawTransaction = serializeRawTransaction(rawTransaction) const s = blake2b(32, null, null, PERSONAL) s.update(hexToBytes(serializedRawTransaction)) const digest = s.digest('hex') - return digest as string + return `0x${digest}` as string } const reverseString = (str: string) => @@ -71,15 +76,20 @@ const reverseString = (str: string) => .split('') .reverse() .join('') + export const toHexInLittleEndian = (int: number | string, paddingBytes: number = 4) => { if (Number.isNaN(+int)) { - throw new TypeError('The input cannot be converted to a number') + throw new InvalidHexString(`${int}`) + } + if (typeof int === 'string' && !int.startsWith('0x')) { + throw new HexStringShouldStartWith0x(int) } const hex = (+int).toString(16) const reversedHex = reverseString(hex) const frags = reversedHex.match(/\w{1,2}/g) || [] - return frags + const hexInLittleEndian = frags .map(frag => reverseString(frag.padEnd(2, '0'))) .join('') .padEnd(paddingBytes * 2, '0') + return `0x${hexInLittleEndian}` } diff --git a/packages/ckb-sdk-utils/src/serialization/index.ts b/packages/ckb-sdk-utils/src/serialization/index.ts index 883d8e2c..fa8a9d79 100644 --- a/packages/ckb-sdk-utils/src/serialization/index.ts +++ b/packages/ckb-sdk-utils/src/serialization/index.ts @@ -45,9 +45,9 @@ export const serializeArray = (array: string | Uint8Array) => { export const serializeStruct = (struct: Map) => { let res = '' struct.forEach(value => { - res += serializeArray(value) + res += serializeArray(value).slice(2) }) - return res + return `0x${res}` } /** @@ -62,9 +62,9 @@ export const serializeFixVec = (fixVec: string | (string | Uint8Array)[]) => { throw new TypeError('The fixed vector to be serialized should be a string or an array of bytes') } const vec = typeof fixVec === 'string' ? [...hexToBytes(fixVec)].map(b => `0x${b.toString(16)}`) : fixVec - const serializedItemVec = vec.map(item => serializeArray(item)) - const header = toHexInLittleEndian(serializedItemVec.length) - return `${header}${serializedItemVec.join('')}` + const serializedItemVec = vec.map(item => serializeArray(item).slice(2)) + const header = toHexInLittleEndian(serializedItemVec.length).slice(2) + return `0x${header}${serializedItemVec.join('')}` } /** @@ -79,17 +79,17 @@ export const serializeDynVec = (dynVec: (string | Uint8Array)[]) => { if (!Array.isArray(dynVec)) { throw new TypeError('The dynamic vector to be serialized should be an array of bytes') } - const serializedItemVec = dynVec.map(item => serializeArray(item)) + const serializedItemVec = dynVec.map(item => serializeArray(item).slice(2)) const body = serializedItemVec.join('') let offsets = '' if (serializedItemVec.length) { offsets = getOffsets(serializedItemVec.map(item => item.length / 2)) - .map(offset => toHexInLittleEndian(offset)) + .map(offset => toHexInLittleEndian(offset).slice(2)) .join('') } const headerLength = fullLengthSize + offsetSize * serializedItemVec.length - const fullLength = toHexInLittleEndian(headerLength + body.length / 2) - return `${fullLength}${offsets}${body}` + const fullLength = toHexInLittleEndian(headerLength + body.length / 2).slice(2) + return `0x${fullLength}${offsets}${body}` } // TODO: add tests @@ -100,15 +100,15 @@ export const serializeDynVec = (dynVec: (string | Uint8Array)[]) => { export const serializeTable = (table: Map) => { const bodyElms: string[] = [] table.forEach(value => { - bodyElms.push(serializeArray(value)) + bodyElms.push(serializeArray(value).slice(2)) }) const body = bodyElms.join('') const headerLength = fullLengthSize + offsetSize * table.size - const fullLength = toHexInLittleEndian(headerLength + body.length / 2) + const fullLength = toHexInLittleEndian(headerLength + body.length / 2).slice(2) const offsets = getOffsets(bodyElms.map(arg => arg.length / 2)) - .map(offset => toHexInLittleEndian(offset)) + .map(offset => toHexInLittleEndian(offset).slice(2)) .join('') - return `${fullLength}${offsets}${body}` + return `0x${fullLength}${offsets}${body}` } /** diff --git a/packages/ckb-sdk-utils/src/serialization/script.ts b/packages/ckb-sdk-utils/src/serialization/script.ts index a78dd3d0..b09cf04c 100644 --- a/packages/ckb-sdk-utils/src/serialization/script.ts +++ b/packages/ckb-sdk-utils/src/serialization/script.ts @@ -1,17 +1,18 @@ import { serializeDynVec, serializeArray, serializeTable, serializeFixVec } from '.' +import { ArgumentRequired } from '../exceptions' export const serializeCodeHash = (codeHash: CKBComponents.Hash256) => serializeArray(codeHash) export const serializeHashType = (hashType: CKBComponents.ScriptHashType) => { - if (hashType === 'data') return '00' - if (hashType === 'type') return '01' + if (hashType === 'data') return '0x00' + if (hashType === 'type') return '0x01' throw new TypeError("Hash type must be either of 'data' or 'type'") } export const serializeArgs = (args: string[]) => serializeDynVec(args.map(arg => serializeFixVec(arg))) export const serializeScript = (script: CKBComponents.Script) => { - if (!script) throw new Error('Script is required') + if (!script) throw new ArgumentRequired('Script') const { codeHash = '', hashType, args = [] } = script const serializedCodeHash = serializeCodeHash(codeHash) const serializedHashType = serializeHashType(hashType) diff --git a/packages/ckb-sdk-utils/src/serialization/transaction.ts b/packages/ckb-sdk-utils/src/serialization/transaction.ts index fd53e27e..25a55673 100644 --- a/packages/ckb-sdk-utils/src/serialization/transaction.ts +++ b/packages/ckb-sdk-utils/src/serialization/transaction.ts @@ -2,15 +2,7 @@ import { serializeScript } from './script' import { toHexInLittleEndian } from '..' import { serializeArray, serializeStruct, serializeTable, serializeDynVec, serializeFixVec } from '.' -export const serializeVersion = (version: CKBComponents.Version) => { - if (typeof version !== 'string') { - throw new TypeError('The version to be serialized should be the type of string') - } - if (version.startsWith('0x') || Number.isNaN(+version)) { - throw new Error('The value of the version should be the type of integer') - } - return toHexInLittleEndian(version) -} +export const serializeVersion = (version: CKBComponents.Version) => toHexInLittleEndian(version) export const serializeOutPoint = (outPoint: CKBComponents.OutPoint | null) => { if (!outPoint) return '' @@ -19,8 +11,8 @@ export const serializeOutPoint = (outPoint: CKBComponents.OutPoint | null) => { } export const serializeDepType = (type: CKBComponents.DepType) => { - if (type === 'code') return '00' - if (type === 'depGroup') return '01' + if (type === 'code') return '0x00' + if (type === 'depGroup') return '0x01' throw new TypeError("Dep type must be either of 'code' or 'depGroup'") } diff --git a/packages/ckb-types/CHANGELOG.md b/packages/ckb-types/CHANGELOG.md index 4ebd2b63..42900165 100644 --- a/packages/ckb-types/CHANGELOG.md +++ b/packages/ckb-types/CHANGELOG.md @@ -3,6 +3,24 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [0.21.0](https://github.com/nervosnetwork/ckb-sdk-js/compare/v0.20.0...v0.21.0) (2019-09-21) + + +### Features + +* **rpc:** format the outputs of the params formatter ([740b403](https://github.com/nervosnetwork/ckb-sdk-js/commit/740b403)) +* **rpc:** update the interface of getLiveCell ([0280d7f](https://github.com/nervosnetwork/ckb-sdk-js/commit/0280d7f)) + + +### BREAKING CHANGES + +* **rpc:** update the interface of getLiveCell +* **rpc:** hexilize the outputs of the params formatter + + + + + # [0.20.0](https://github.com/nervosnetwork/ckb-sdk-js/compare/v0.19.1...v0.20.0) (2019-09-07) **Note:** Version bump only for package @nervosnetwork/ckb-types diff --git a/packages/ckb-types/index.d.ts b/packages/ckb-types/index.d.ts index fc68baa2..3ebab294 100644 --- a/packages/ckb-types/index.d.ts +++ b/packages/ckb-types/index.d.ts @@ -5,6 +5,7 @@ declare namespace CKBComponents { export type DAO = string export type Hash = string + export type Number = string export type Hash256 = string export type UInt32 = number export type Index = string @@ -240,6 +241,22 @@ declare namespace CKBComponents { */ export interface Cell extends CellOutput {} + /** + * @typeof Live Cell + * @property lock, the lock script of the live cell + * @property type, the type script of the live cell + * @property data, the data and data hash of the live cell + * @property output, the previous cell the live cell derives from + */ + + export interface LiveCell { + data?: { + content: Hash + hash: Hash256 + } + output: CellOutput + } + /** * @typedef Cell, cell object * @property capacty, cell capacity diff --git a/packages/ckb-types/package.json b/packages/ckb-types/package.json index 132fc1a9..62da258a 100644 --- a/packages/ckb-types/package.json +++ b/packages/ckb-types/package.json @@ -1,6 +1,6 @@ { "name": "@nervosnetwork/ckb-types", - "version": "0.20.0", + "version": "0.21.0", "description": "Type module of @nervosnetwork/ckb-sdk-core", "author": "Nervos ", "homepage": "https://github.com/nervosnetwork/ckb-sdk-js#readme", @@ -23,5 +23,5 @@ "scripts": { "doc": "../../node_modules/.bin/typedoc --out docs ./index.d.ts --mode modules --includeDeclarations --excludeExternals --ignoreCompilerErrors --theme default --readme README.md" }, - "gitHead": "478433630dd40501f1f67dc259bf9d252c56fcd3" + "gitHead": "5a1aaff6006c91e45e8ba39ceb6ef7c2f870e6cd" }