mirror of
https://github.com/bigchaindb/js-bigchaindb-driver.git
synced 2024-11-22 09:46:58 +01:00
commit
0b0ea0a97e
@ -4,7 +4,7 @@ node_js: node
|
|||||||
install: npm install
|
install: npm install
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- npm run clean
|
- npm test
|
||||||
- npm run build
|
- npm run build
|
||||||
|
|
||||||
cache:
|
cache:
|
||||||
|
@ -18,11 +18,12 @@
|
|||||||
"build:cjs": "cross-env BABEL_ENV=cjs babel ./src -d dist/node",
|
"build:cjs": "cross-env BABEL_ENV=cjs babel ./src -d dist/node",
|
||||||
"build:dist": "cross-env NODE_ENV=production webpack -p",
|
"build:dist": "cross-env NODE_ENV=production webpack -p",
|
||||||
"clean": "rimraf dist/bundle dist/node",
|
"clean": "rimraf dist/bundle dist/node",
|
||||||
"test": "echo \"Error: no test specified AWWWW YEAHHH\" && exit 1",
|
"test": "npm run lint",
|
||||||
"release": "./node_modules/release-it/bin/release.js --src.tagName='v%s' --github.release --npm.publish --non-interactive",
|
"release": "./node_modules/release-it/bin/release.js --src.tagName='v%s' --github.release --npm.publish --non-interactive",
|
||||||
"release-minor": "./node_modules/release-it/bin/release.js minor --src.tagName='v%s' --github.release --npm.publish --non-interactive",
|
"release-minor": "./node_modules/release-it/bin/release.js minor --src.tagName='v%s' --github.release --npm.publish --non-interactive",
|
||||||
"release-major": "./node_modules/release-it/bin/release.js major --src.tagName='v%s' --github.release --npm.publish --non-interactive",
|
"release-major": "./node_modules/release-it/bin/release.js major --src.tagName='v%s' --github.release --npm.publish --non-interactive",
|
||||||
"postinstall": "npm run build"
|
"postinstall": "npm run build",
|
||||||
|
"precommit": "npm run lint"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-cli": "^6.22.2",
|
"babel-cli": "^6.22.2",
|
||||||
@ -41,6 +42,7 @@
|
|||||||
"eslint": "^3.14.1",
|
"eslint": "^3.14.1",
|
||||||
"eslint-config-ascribe": "^3.0.1",
|
"eslint-config-ascribe": "^3.0.1",
|
||||||
"eslint-plugin-import": "^2.2.0",
|
"eslint-plugin-import": "^2.2.0",
|
||||||
|
"husky": "^0.13.4",
|
||||||
"release-it": "^2.7.3",
|
"release-it": "^2.7.3",
|
||||||
"rimraf": "^2.5.4",
|
"rimraf": "^2.5.4",
|
||||||
"webpack": "^2.2.1"
|
"webpack": "^2.2.1"
|
||||||
@ -58,6 +60,7 @@
|
|||||||
"js-sha3": "^0.5.7",
|
"js-sha3": "^0.5.7",
|
||||||
"js-utility-belt": "^1.5.0",
|
"js-utility-belt": "^1.5.0",
|
||||||
"json-stable-stringify": "^1.0.1",
|
"json-stable-stringify": "^1.0.1",
|
||||||
|
"query-string": "^4.3.4",
|
||||||
"sprintf-js": "^1.0.3",
|
"sprintf-js": "^1.0.3",
|
||||||
"tweetnacl": "^1.0.0"
|
"tweetnacl": "^1.0.0"
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import base58 from 'bs58';
|
import base58 from 'bs58'
|
||||||
import nacl from 'tweetnacl';
|
import nacl from 'tweetnacl'
|
||||||
import sha3 from 'js-sha3';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
@ -11,8 +10,8 @@ import sha3 from 'js-sha3';
|
|||||||
* @property {string} privateKey
|
* @property {string} privateKey
|
||||||
*/
|
*/
|
||||||
export default function Ed25519Keypair(seed) {
|
export default function Ed25519Keypair(seed) {
|
||||||
const keyPair = seed ? nacl.sign.keyPair.fromSeed(seed) : nacl.sign.keyPair();
|
const keyPair = seed ? nacl.sign.keyPair.fromSeed(seed) : nacl.sign.keyPair()
|
||||||
this.publicKey = base58.encode(keyPair.publicKey);
|
this.publicKey = base58.encode(keyPair.publicKey)
|
||||||
// tweetnacl's generated secret key is the secret key + public key (resulting in a 64-byte buffer)
|
// tweetnacl's generated secret key is the secret key + public key (resulting in a 64-byte buffer)
|
||||||
this.privateKey = base58.encode(keyPair.secretKey.slice(0, 32));
|
this.privateKey = base58.encode(keyPair.secretKey.slice(0, 32))
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import { Promise } from 'es6-promise';
|
import { Promise } from 'es6-promise'
|
||||||
import fetchPonyfill from 'fetch-ponyfill';
|
import fetchPonyfill from 'fetch-ponyfill'
|
||||||
import { vsprintf } from 'sprintf-js';
|
import { vsprintf } from 'sprintf-js'
|
||||||
|
|
||||||
import formatText from './format_text';
|
import formatText from './format_text'
|
||||||
|
|
||||||
import stringifyAsQueryParam from './stringify_as_query_param';
|
import stringifyAsQueryParam from './stringify_as_query_param'
|
||||||
|
|
||||||
|
|
||||||
const fetch = fetchPonyfill(Promise);
|
const fetch = fetchPonyfill(Promise)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -38,35 +38,35 @@ const fetch = fetchPonyfill(Promise);
|
|||||||
* otherwise rejects with the response
|
* otherwise rejects with the response
|
||||||
*/
|
*/
|
||||||
export default function baseRequest(url, { jsonBody, query, urlTemplateSpec, ...fetchConfig } = {}) {
|
export default function baseRequest(url, { jsonBody, query, urlTemplateSpec, ...fetchConfig } = {}) {
|
||||||
let expandedUrl = url;
|
let expandedUrl = url
|
||||||
|
|
||||||
if (urlTemplateSpec != null) {
|
if (urlTemplateSpec != null) {
|
||||||
if (Array.isArray(urlTemplateSpec) && urlTemplateSpec.length) {
|
if (Array.isArray(urlTemplateSpec) && urlTemplateSpec.length) {
|
||||||
// Use vsprintf for the array call signature
|
// Use vsprintf for the array call signature
|
||||||
expandedUrl = vsprintf(url, urlTemplateSpec);
|
expandedUrl = vsprintf(url, urlTemplateSpec)
|
||||||
} else if (urlTemplateSpec &&
|
} else if (urlTemplateSpec &&
|
||||||
typeof urlTemplateSpec === 'object' &&
|
typeof urlTemplateSpec === 'object' &&
|
||||||
Object.keys(urlTemplateSpec).length) {
|
Object.keys(urlTemplateSpec).length) {
|
||||||
expandedUrl = formatText(url, urlTemplateSpec);
|
expandedUrl = formatText(url, urlTemplateSpec)
|
||||||
} else if (process.env.NODE_ENV !== 'production') {
|
} else if (process.env.NODE_ENV !== 'production') {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.warn('Supplied urlTemplateSpec was not an array or object. Ignoring...');
|
console.warn('Supplied urlTemplateSpec was not an array or object. Ignoring...')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query != null) {
|
if (query != null) {
|
||||||
if (typeof query === 'string') {
|
if (typeof query === 'string') {
|
||||||
expandedUrl += query;
|
expandedUrl += query
|
||||||
} else if (query && typeof query === 'object') {
|
} else if (query && typeof query === 'object') {
|
||||||
expandedUrl += stringifyAsQueryParam(query);
|
expandedUrl += stringifyAsQueryParam(query)
|
||||||
} else if (process.env.NODE_ENV !== 'production') {
|
} else if (process.env.NODE_ENV !== 'production') {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.warn('Supplied query was not a string or object. Ignoring...');
|
console.warn('Supplied query was not a string or object. Ignoring...')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (jsonBody != null) {
|
if (jsonBody != null) {
|
||||||
fetchConfig.body = JSON.stringify(jsonBody);
|
fetchConfig.body = JSON.stringify(jsonBody)
|
||||||
}
|
}
|
||||||
|
|
||||||
return fetch.fetch(expandedUrl, fetchConfig)
|
return fetch.fetch(expandedUrl, fetchConfig)
|
||||||
@ -74,8 +74,8 @@ export default function baseRequest(url, { jsonBody, query, urlTemplateSpec, ...
|
|||||||
// If status is not a 2xx (based on Response.ok), assume it's an error
|
// If status is not a 2xx (based on Response.ok), assume it's an error
|
||||||
// See https://developer.mozilla.org/en-US/docs/Web/API/GlobalFetch/fetch
|
// See https://developer.mozilla.org/en-US/docs/Web/API/GlobalFetch/fetch
|
||||||
if (!(res && res.ok)) {
|
if (!(res && res.ok)) {
|
||||||
throw res;
|
throw res
|
||||||
}
|
}
|
||||||
return res;
|
return res
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,27 +1,27 @@
|
|||||||
import request from '../request';
|
import request from '../request'
|
||||||
|
|
||||||
|
|
||||||
export default class Connection {
|
export default class Connection {
|
||||||
constructor(path, headers) {
|
constructor(path, headers) {
|
||||||
this.path = path;
|
this.path = path
|
||||||
this.headers = headers;
|
this.headers = headers
|
||||||
}
|
}
|
||||||
|
|
||||||
getApiUrls(endpoints) {
|
getApiUrls(endpoints) {
|
||||||
// TODO: Use camel case
|
// TODO: Use camel case
|
||||||
return {
|
return {
|
||||||
'blocks': this.path + 'blocks',
|
'blocks': `${this.path}blocks`,
|
||||||
'blocks_detail': this.path + 'blocks/%(blockId)s',
|
'blocks_detail': `${this.path}blocks/%(blockId)s`,
|
||||||
'outputs': this.path + 'outputs',
|
'outputs': `${this.path}outputs`,
|
||||||
'statuses': this.path + 'statuses',
|
'statuses': `${this.path}statuses`,
|
||||||
'transactions': this.path + 'transactions',
|
'transactions': `${this.path}transactions`,
|
||||||
'transactions_detail': this.path + 'transactions/%(txId)s',
|
'transactions_detail': `${this.path}transactions/%(txId)s`,
|
||||||
'search_assets': this.path + 'assets',
|
'search_assets': `${this.path}assets`,
|
||||||
'votes': this.path + 'votes'
|
'votes': `${this.path}votes`
|
||||||
}[endpoints];
|
}[endpoints]
|
||||||
}
|
}
|
||||||
|
|
||||||
_req(path, options={}) {
|
_req(path, options = {}) {
|
||||||
// NOTE: `options.headers` could be undefined, but that's OK.
|
// NOTE: `options.headers` could be undefined, but that's OK.
|
||||||
options.headers = Object.assign({}, options.headers, this.headers)
|
options.headers = Object.assign({}, options.headers, this.headers)
|
||||||
return request(path, options)
|
return request(path, options)
|
||||||
@ -33,22 +33,22 @@ export default class Connection {
|
|||||||
*/
|
*/
|
||||||
getBlock(blockId) {
|
getBlock(blockId) {
|
||||||
return this._req(this.getApiUrls('blocks_detail'), {
|
return this._req(this.getApiUrls('blocks_detail'), {
|
||||||
urlTemplateSpec: {
|
urlTemplateSpec: {
|
||||||
blockId
|
blockId
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
* @param tx_id
|
* @param tx_id
|
||||||
*/
|
*/
|
||||||
getStatus(tx_id) {
|
getStatus(tx_id) { // eslint-disable-line camelcase
|
||||||
return this._req(this.getApiUrls('statuses'), {
|
return this._req(this.getApiUrls('statuses'), {
|
||||||
query: {
|
query: {
|
||||||
tx_id
|
tx_id
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -57,10 +57,10 @@ export default class Connection {
|
|||||||
*/
|
*/
|
||||||
getTransaction(txId) {
|
getTransaction(txId) {
|
||||||
return this._req(this.getApiUrls('transactions_detail'), {
|
return this._req(this.getApiUrls('transactions_detail'), {
|
||||||
urlTemplateSpec: {
|
urlTemplateSpec: {
|
||||||
txId
|
txId
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -70,11 +70,11 @@ export default class Connection {
|
|||||||
*/
|
*/
|
||||||
listBlocks({ tx_id, status }) {
|
listBlocks({ tx_id, status }) {
|
||||||
return this._req(this.getApiUrls('blocks'), {
|
return this._req(this.getApiUrls('blocks'), {
|
||||||
query: {
|
query: {
|
||||||
tx_id,
|
tx_id,
|
||||||
status
|
status
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -83,7 +83,7 @@ export default class Connection {
|
|||||||
* @param unspent
|
* @param unspent
|
||||||
* @param onlyJsonResponse
|
* @param onlyJsonResponse
|
||||||
*/
|
*/
|
||||||
listOutputs({ public_key, unspent }, onlyJsonResponse=true) {
|
listOutputs({ public_key, unspent }, onlyJsonResponse = true) {
|
||||||
return this._req(this.getApiUrls('outputs'), {
|
return this._req(this.getApiUrls('outputs'), {
|
||||||
query: {
|
query: {
|
||||||
public_key,
|
public_key,
|
||||||
@ -110,38 +110,38 @@ export default class Connection {
|
|||||||
* @public
|
* @public
|
||||||
* @param block_id
|
* @param block_id
|
||||||
*/
|
*/
|
||||||
listVotes(block_id) {
|
listVotes(block_id) { // eslint-disable-line camelcase
|
||||||
return this._req(this.getApiUrls('votes'), {
|
return this._req(this.getApiUrls('votes'), {
|
||||||
query: {
|
query: {
|
||||||
block_id
|
block_id
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
* @param tx_id
|
* @param txId
|
||||||
* @return {Promise}
|
* @return {Promise}
|
||||||
*/
|
*/
|
||||||
pollStatusAndFetchTransaction(tx_id) {
|
pollStatusAndFetchTransaction(txId) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const timer = setInterval(() => {
|
const timer = setInterval(() => {
|
||||||
this.getStatus(tx_id)
|
this.getStatus(txId)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
console.log('Fetched transaction status:', res);
|
console.log('Fetched transaction status:', res) // eslint-disable-line no-console
|
||||||
if (res.status === 'valid') {
|
if (res.status === 'valid') {
|
||||||
clearInterval(timer);
|
clearInterval(timer)
|
||||||
this.getTransaction(tx_id)
|
this.getTransaction(txId)
|
||||||
.then((res) => {
|
.then((res_) => {
|
||||||
console.log('Fetched transaction:', res);
|
console.log('Fetched transaction:', res_) // eslint-disable-line no-console
|
||||||
resolve(res);
|
resolve(res_)
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
clearInterval(timer);
|
clearInterval(timer)
|
||||||
reject(err);
|
reject(err)
|
||||||
});
|
})
|
||||||
}, 500)
|
}, 500)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import { sprintf } from 'sprintf-js';
|
import { sprintf } from 'sprintf-js'
|
||||||
|
|
||||||
|
|
||||||
// Regexes taken from or inspired by sprintf-js
|
// Regexes taken from or inspired by sprintf-js
|
||||||
const Regex = {
|
const Regex = {
|
||||||
TEMPLATE_LITERAL: /\${([^\)]+?)}/g,
|
TEMPLATE_LITERAL: /\${([^)]+?)}/g,
|
||||||
KEY: /^([a-z_][a-z_\d]*)/i,
|
KEY: /^([a-z_][a-z_\d]*)/i,
|
||||||
KEY_ACCESS: /^\.([a-z_][a-z_\d]*)/i,
|
KEY_ACCESS: /^\.([a-z_][a-z_\d]*)/i,
|
||||||
INDEX_ACCESS: /^\[(\d+)\]/
|
INDEX_ACCESS: /^\[(\d+)\]/
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* imported from https://github.com/bigchaindb/js-utility-belt/
|
* imported from https://github.com/bigchaindb/js-utility-belt/
|
||||||
@ -37,14 +37,14 @@ const Regex = {
|
|||||||
* => 'Berlin is best known for its Currywurst'
|
* => 'Berlin is best known for its Currywurst'
|
||||||
*/
|
*/
|
||||||
export default function formatText(s, ...argv) {
|
export default function formatText(s, ...argv) {
|
||||||
let expandedFormatStr = s;
|
let expandedFormatStr = s
|
||||||
|
|
||||||
// Try to replace formats of the form '${...}' if named replacement fields are used
|
// Try to replace formats of the form '${...}' if named replacement fields are used
|
||||||
if (s && argv.length === 1 && typeof argv[0] === 'object') {
|
if (s && argv.length === 1 && typeof argv[0] === 'object') {
|
||||||
const templateSpecObj = argv[0];
|
const templateSpecObj = argv[0]
|
||||||
|
|
||||||
expandedFormatStr = s.replace(Regex.TEMPLATE_LITERAL, (match, replacement) => {
|
expandedFormatStr = s.replace(Regex.TEMPLATE_LITERAL, (match, replacement) => {
|
||||||
let interpolationLeft = replacement;
|
let interpolationLeft = replacement
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interpolation algorithm inspired by sprintf-js.
|
* Interpolation algorithm inspired by sprintf-js.
|
||||||
@ -61,21 +61,21 @@ export default function formatText(s, ...argv) {
|
|||||||
* And that in the regexes defined, the first matching group always corresponds to the
|
* And that in the regexes defined, the first matching group always corresponds to the
|
||||||
* property matched.
|
* property matched.
|
||||||
*/
|
*/
|
||||||
let value;
|
let value
|
||||||
let curMatch = Regex.KEY.exec(interpolationLeft);
|
let curMatch = Regex.KEY.exec(interpolationLeft)
|
||||||
if (curMatch !== null) {
|
if (curMatch !== null) {
|
||||||
value = templateSpecObj[curMatch[1]];
|
value = templateSpecObj[curMatch[1]]
|
||||||
|
|
||||||
// Assigning in the conditionals here makes the code less bloated
|
// Assigning in the conditionals here makes the code less bloated
|
||||||
/* eslint-disable no-cond-assign */
|
/* eslint-disable no-cond-assign */
|
||||||
while ((interpolationLeft = interpolationLeft.substring(curMatch[0].length)) &&
|
while ((interpolationLeft = interpolationLeft.substring(curMatch[0].length)) &&
|
||||||
value != null) {
|
value != null) {
|
||||||
if ((curMatch = Regex.KEY_ACCESS.exec(interpolationLeft))) {
|
if ((curMatch = Regex.KEY_ACCESS.exec(interpolationLeft))) {
|
||||||
value = value[curMatch[1]];
|
value = value[curMatch[1]]
|
||||||
} else if ((curMatch = Regex.INDEX_ACCESS.exec(interpolationLeft))) {
|
} else if ((curMatch = Regex.INDEX_ACCESS.exec(interpolationLeft))) {
|
||||||
value = value[curMatch[1]];
|
value = value[curMatch[1]]
|
||||||
} else {
|
} else {
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* eslint-enable no-cond-assign */
|
/* eslint-enable no-cond-assign */
|
||||||
@ -86,12 +86,12 @@ export default function formatText(s, ...argv) {
|
|||||||
if (interpolationLeft.length) {
|
if (interpolationLeft.length) {
|
||||||
throw new SyntaxError(
|
throw new SyntaxError(
|
||||||
`[formatText] failed to parse named argument key: ${replacement}`
|
`[formatText] failed to parse named argument key: ${replacement}`
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return value
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return sprintf(expandedFormatStr, ...argv);
|
return sprintf(expandedFormatStr, ...argv)
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
export Ed25519Keypair from './Ed25519Keypair';
|
export Ed25519Keypair from './Ed25519Keypair'
|
||||||
|
|
||||||
export * as Transaction from './transaction';
|
export * as Transaction from './transaction'
|
||||||
export Connection from './connection';
|
export Connection from './connection'
|
||||||
|
@ -1,43 +1,41 @@
|
|||||||
import baseRequest from './baseRequest';
|
import baseRequest from './baseRequest'
|
||||||
import sanitize from './sanitize';
|
import sanitize from './sanitize'
|
||||||
|
|
||||||
|
|
||||||
const DEFAULT_REQUEST_CONFIG = {
|
const DEFAULT_REQUEST_CONFIG = {
|
||||||
headers: {
|
headers: {
|
||||||
'Accept': 'application/json'
|
'Accept': 'application/json'
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Small wrapper around js-utility-belt's request that provides url resolving,
|
* Small wrapper around js-utility-belt's request that provides url resolving,
|
||||||
* default settings, and response handling.
|
* default settings, and response handling.
|
||||||
*/
|
*/
|
||||||
export default function request(url, config = {}, onlyJsonResponse=true) {
|
export default function request(url, config = {}, onlyJsonResponse = true) {
|
||||||
// Load default fetch configuration and remove any falsy query parameters
|
// Load default fetch configuration and remove any falsy query parameters
|
||||||
const requestConfig = Object.assign({}, DEFAULT_REQUEST_CONFIG, config, {
|
const requestConfig = Object.assign({}, DEFAULT_REQUEST_CONFIG, config, {
|
||||||
query: config.query && sanitize(config.query)
|
query: config.query && sanitize(config.query)
|
||||||
});
|
})
|
||||||
let apiUrl = url;
|
const apiUrl = url
|
||||||
|
|
||||||
if (requestConfig.jsonBody) {
|
if (requestConfig.jsonBody) {
|
||||||
requestConfig.headers = Object.assign({}, requestConfig.headers, {
|
requestConfig.headers = Object.assign({}, requestConfig.headers, {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
if (!url) {
|
if (!url) {
|
||||||
return Promise.reject(new Error('Request was not given a url.'));
|
return Promise.reject(new Error('Request was not given a url.'))
|
||||||
}
|
}
|
||||||
|
|
||||||
return baseRequest(apiUrl, requestConfig)
|
return baseRequest(apiUrl, requestConfig)
|
||||||
.then((res) => {
|
.then((res) => onlyJsonResponse ? res.json() : // eslint-disable-line no-confusing-arrow
|
||||||
return onlyJsonResponse ? res.json() :
|
{
|
||||||
{
|
json: res.json(),
|
||||||
json: res.json(),
|
url: res.url
|
||||||
url: res.url
|
|
||||||
};
|
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error(err);
|
console.error(err)
|
||||||
throw err;
|
throw err
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import coreIncludes from 'core-js/library/fn/array/includes';
|
import coreIncludes from 'core-js/library/fn/array/includes'
|
||||||
import coreObjectEntries from 'core-js/library/fn/object/entries';
|
import coreObjectEntries from 'core-js/library/fn/object/entries'
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -10,13 +10,13 @@ import coreObjectEntries from 'core-js/library/fn/object/entries';
|
|||||||
function filterFromObject(obj, filter, { isInclusion = true } = {}) {
|
function filterFromObject(obj, filter, { isInclusion = true } = {}) {
|
||||||
if (filter && Array.isArray(filter)) {
|
if (filter && Array.isArray(filter)) {
|
||||||
return applyFilterOnObject(obj, isInclusion ? ((_, key) => coreIncludes(filter, key))
|
return applyFilterOnObject(obj, isInclusion ? ((_, key) => coreIncludes(filter, key))
|
||||||
: ((_, key) => !coreIncludes(filter, key)));
|
: ((_, key) => !coreIncludes(filter, key)))
|
||||||
} else if (filter && typeof filter === 'function') {
|
} else if (filter && typeof filter === 'function') {
|
||||||
// Flip the filter fn's return if it's for inclusion
|
// Flip the filter fn's return if it's for inclusion
|
||||||
return applyFilterOnObject(obj, isInclusion ? filter
|
return applyFilterOnObject(obj, isInclusion ? filter
|
||||||
: (...args) => !filter(...args));
|
: (...args) => !filter(...args))
|
||||||
} else {
|
} else {
|
||||||
throw new Error('The given filter is not an array or function. Exclude aborted');
|
throw new Error('The given filter is not an array or function. Exclude aborted')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,17 +26,17 @@ function filterFromObject(obj, filter, { isInclusion = true } = {}) {
|
|||||||
*/
|
*/
|
||||||
function applyFilterOnObject(obj, filterFn) {
|
function applyFilterOnObject(obj, filterFn) {
|
||||||
if (filterFn == null) {
|
if (filterFn == null) {
|
||||||
return Object.assign({}, obj);
|
return Object.assign({}, obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
const filteredObj = {};
|
const filteredObj = {}
|
||||||
coreObjectEntries(obj).forEach(([key, val]) => {
|
coreObjectEntries(obj).forEach(([key, val]) => {
|
||||||
if (filterFn(val, key)) {
|
if (filterFn(val, key)) {
|
||||||
filteredObj[key] = val;
|
filteredObj[key] = val
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
return filteredObj;
|
return filteredObj
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -48,7 +48,7 @@ function applyFilterOnObject(obj, filterFn) {
|
|||||||
* @return {object} The new object
|
* @return {object} The new object
|
||||||
*/
|
*/
|
||||||
function selectFromObject(obj, filter) {
|
function selectFromObject(obj, filter) {
|
||||||
return filterFromObject(obj, filter);
|
return filterFromObject(obj, filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,5 +60,5 @@ function selectFromObject(obj, filter) {
|
|||||||
* @return {object} Sanitized Javascript object
|
* @return {object} Sanitized Javascript object
|
||||||
*/
|
*/
|
||||||
export default function sanitize(obj) {
|
export default function sanitize(obj) {
|
||||||
return selectFromObject(obj, (val) => !!val);
|
return selectFromObject(obj, (val) => !!val)
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import sha3 from 'js-sha3';
|
import sha3 from 'js-sha3'
|
||||||
|
|
||||||
export default function sha256Hash(data) {
|
export default function sha256Hash(data) {
|
||||||
return sha3.sha3_256
|
return sha3.sha3_256
|
||||||
.create()
|
.create()
|
||||||
.update(data)
|
.update(data)
|
||||||
.hex();
|
.hex()
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import coreObjectEntries from 'core-js/library/fn/object/entries';
|
import coreObjectEntries from 'core-js/library/fn/object/entries'
|
||||||
import decamelize from 'decamelize';
|
import decamelize from 'decamelize'
|
||||||
import queryString from 'query-string';
|
import queryString from 'query-string'
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -30,13 +30,13 @@ import queryString from 'query-string';
|
|||||||
*/
|
*/
|
||||||
export default function stringifyAsQueryParam(obj, transform = decamelize) {
|
export default function stringifyAsQueryParam(obj, transform = decamelize) {
|
||||||
if (!obj || typeof obj !== 'object' || !Object.keys(obj).length) {
|
if (!obj || typeof obj !== 'object' || !Object.keys(obj).length) {
|
||||||
return '';
|
return ''
|
||||||
}
|
}
|
||||||
|
|
||||||
const transformedKeysObj = coreObjectEntries(obj).reduce((paramsObj, [key, value]) => {
|
const transformedKeysObj = coreObjectEntries(obj).reduce((paramsObj, [key, value]) => {
|
||||||
paramsObj[transform(key)] = value;
|
paramsObj[transform(key)] = value
|
||||||
return paramsObj;
|
return paramsObj
|
||||||
}, {});
|
}, {})
|
||||||
|
|
||||||
return `?${queryString.stringify(transformedKeysObj)}`;
|
return `?${queryString.stringify(transformedKeysObj)}`
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import serializeTransactionIntoCanonicalString from './serializeTransactionIntoCanonicalString';
|
import serializeTransactionIntoCanonicalString from './serializeTransactionIntoCanonicalString'
|
||||||
import sha256Hash from '../sha256Hash';
|
import sha256Hash from '../sha256Hash'
|
||||||
|
|
||||||
export default function hashTransaction(transaction) {
|
export default function hashTransaction(transaction) {
|
||||||
// Safely remove any tx id from the given transaction for hashing
|
// Safely remove any tx id from the given transaction for hashing
|
||||||
const tx = { ...transaction };
|
const tx = { ...transaction }
|
||||||
delete tx.id;
|
delete tx.id
|
||||||
|
|
||||||
return sha256Hash(serializeTransactionIntoCanonicalString(tx));
|
return sha256Hash(serializeTransactionIntoCanonicalString(tx))
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
export makeEd25519Condition from './makeEd25519Condition';
|
export makeEd25519Condition from './makeEd25519Condition'
|
||||||
export makeSha256Condition from './makeSha256Condition';
|
export makeSha256Condition from './makeSha256Condition'
|
||||||
export makeThresholdCondition from './makeThresholdCondition';
|
export makeThresholdCondition from './makeThresholdCondition'
|
||||||
export makeCreateTransaction from './makeCreateTransaction';
|
export makeCreateTransaction from './makeCreateTransaction'
|
||||||
export makeOutput from './makeOutput';
|
export makeOutput from './makeOutput'
|
||||||
export makeTransaction from './makeTransaction';
|
export makeTransaction from './makeTransaction'
|
||||||
export makeTransferTransaction from './makeTransferTransaction';
|
export makeTransferTransaction from './makeTransferTransaction'
|
||||||
export serializeTransactionIntoCanonicalString from './serializeTransactionIntoCanonicalString';
|
export serializeTransactionIntoCanonicalString from './serializeTransactionIntoCanonicalString'
|
||||||
export signTransaction from './signTransaction';
|
export signTransaction from './signTransaction'
|
||||||
export ccJsonLoad from './utils/ccJsonLoad';
|
export ccJsonLoad from './utils/ccJsonLoad'
|
||||||
export ccJsonify from './utils/ccJsonify';
|
export ccJsonify from './utils/ccJsonify'
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import makeInputTemplate from './makeInputTemplate';
|
import makeInputTemplate from './makeInputTemplate'
|
||||||
import makeTransaction from './makeTransaction';
|
import makeTransaction from './makeTransaction'
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -24,8 +24,8 @@ import makeTransaction from './makeTransaction';
|
|||||||
export default function makeCreateTransaction(asset, metadata, outputs, ...issuers) {
|
export default function makeCreateTransaction(asset, metadata, outputs, ...issuers) {
|
||||||
const assetDefinition = {
|
const assetDefinition = {
|
||||||
'data': asset || null,
|
'data': asset || null,
|
||||||
};
|
}
|
||||||
const inputs = issuers.map((issuer) => makeInputTemplate([issuer]));
|
const inputs = issuers.map((issuer) => makeInputTemplate([issuer]))
|
||||||
|
|
||||||
return makeTransaction('CREATE', assetDefinition, metadata, outputs, inputs);
|
return makeTransaction('CREATE', assetDefinition, metadata, outputs, inputs)
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { Buffer } from 'buffer';
|
import { Buffer } from 'buffer'
|
||||||
|
|
||||||
import base58 from 'bs58';
|
import base58 from 'bs58'
|
||||||
import cc from 'five-bells-condition';
|
import cc from 'five-bells-condition'
|
||||||
|
|
||||||
import ccJsonify from './utils/ccJsonify';
|
import ccJsonify from './utils/ccJsonify'
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -13,15 +13,15 @@ import ccJsonify from './utils/ccJsonify';
|
|||||||
* @param {boolean} [json=true] If true returns a json object otherwise a crypto-condition type
|
* @param {boolean} [json=true] If true returns a json object otherwise a crypto-condition type
|
||||||
* @returns {object} Ed25519 Condition (that will need to wrapped in an Output)
|
* @returns {object} Ed25519 Condition (that will need to wrapped in an Output)
|
||||||
*/
|
*/
|
||||||
export default function makeEd25519Condition(publicKey, json=true) {
|
export default function makeEd25519Condition(publicKey, json = true) {
|
||||||
const publicKeyBuffer = new Buffer(base58.decode(publicKey));
|
const publicKeyBuffer = new Buffer(base58.decode(publicKey))
|
||||||
|
|
||||||
const ed25519Fulfillment = new cc.Ed25519();
|
const ed25519Fulfillment = new cc.Ed25519()
|
||||||
ed25519Fulfillment.setPublicKey(publicKeyBuffer);
|
ed25519Fulfillment.setPublicKey(publicKeyBuffer)
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
return ccJsonify(ed25519Fulfillment)
|
return ccJsonify(ed25519Fulfillment)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ed25519Fulfillment;
|
return ed25519Fulfillment
|
||||||
}
|
}
|
||||||
|
@ -3,5 +3,5 @@ export default function makeInputTemplate(publicKeys = [], fulfills = null, fulf
|
|||||||
fulfillment,
|
fulfillment,
|
||||||
fulfills,
|
fulfills,
|
||||||
'owners_before': publicKeys,
|
'owners_before': publicKeys,
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,9 +8,9 @@
|
|||||||
*/
|
*/
|
||||||
export default function makeOutput(condition, amount = 1) {
|
export default function makeOutput(condition, amount = 1) {
|
||||||
return {
|
return {
|
||||||
amount: amount.toString(),
|
'amount': amount.toString(),
|
||||||
condition,
|
condition,
|
||||||
'public_keys': condition.details.hasOwnProperty('public_key') ?
|
'public_keys': condition.details.hasOwnProperty('public_key') ?
|
||||||
[condition.details.public_key] : [],
|
[condition.details.public_key] : [],
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { Buffer } from 'buffer';
|
import { Buffer } from 'buffer'
|
||||||
|
|
||||||
import cc from 'five-bells-condition';
|
import cc from 'five-bells-condition'
|
||||||
|
|
||||||
import ccJsonify from './utils/ccJsonify';
|
import ccJsonify from './utils/ccJsonify'
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -12,12 +12,12 @@ import ccJsonify from './utils/ccJsonify';
|
|||||||
* @param {boolean} [json=true] If true returns a json object otherwise a crypto-condition type
|
* @param {boolean} [json=true] If true returns a json object otherwise a crypto-condition type
|
||||||
* @returns {object} Preimage-Sha256 Condition (that will need to wrapped in an Output)
|
* @returns {object} Preimage-Sha256 Condition (that will need to wrapped in an Output)
|
||||||
*/
|
*/
|
||||||
export default function makeSha256Condition(preimage, json=true) {
|
export default function makeSha256Condition(preimage, json = true) {
|
||||||
const sha256Fulfillment = new cc.PreimageSha256();
|
const sha256Fulfillment = new cc.PreimageSha256()
|
||||||
sha256Fulfillment.preimage = new Buffer(preimage);
|
sha256Fulfillment.preimage = new Buffer(preimage)
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
return ccJsonify(sha256Fulfillment)
|
return ccJsonify(sha256Fulfillment)
|
||||||
}
|
}
|
||||||
return sha256Fulfillment;
|
return sha256Fulfillment
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import cc from 'five-bells-condition';
|
import cc from 'five-bells-condition'
|
||||||
|
|
||||||
import ccJsonify from './utils/ccJsonify';
|
import ccJsonify from './utils/ccJsonify'
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -11,14 +11,14 @@ import ccJsonify from './utils/ccJsonify';
|
|||||||
* @param {boolean} [json=true] If true returns a json object otherwise a crypto-condition type
|
* @param {boolean} [json=true] If true returns a json object otherwise a crypto-condition type
|
||||||
* @returns {object} Sha256 Threshold Condition (that will need to wrapped in an Output)
|
* @returns {object} Sha256 Threshold Condition (that will need to wrapped in an Output)
|
||||||
*/
|
*/
|
||||||
export default function makeThresholdCondition(threshold, subconditions=[], json=true) {
|
export default function makeThresholdCondition(threshold, subconditions = [], json = true) {
|
||||||
const thresholdCondition = new cc.ThresholdSha256();
|
const thresholdCondition = new cc.ThresholdSha256()
|
||||||
thresholdCondition.threshold = threshold;
|
thresholdCondition.threshold = threshold
|
||||||
|
|
||||||
subconditions.forEach((subcondition) => {
|
subconditions.forEach((subcondition) => {
|
||||||
// TODO: add support for Condition and URIs
|
// TODO: add support for Condition and URIs
|
||||||
thresholdCondition.addSubfulfillment(subcondition);
|
thresholdCondition.addSubfulfillment(subcondition)
|
||||||
});
|
})
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
return ccJsonify(thresholdCondition)
|
return ccJsonify(thresholdCondition)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import hashTransaction from './hashTransaction';
|
import hashTransaction from './hashTransaction'
|
||||||
|
|
||||||
|
|
||||||
function makeTransactionTemplate() {
|
function makeTransactionTemplate() {
|
||||||
@ -10,19 +10,19 @@ function makeTransactionTemplate() {
|
|||||||
'metadata': null,
|
'metadata': null,
|
||||||
'asset': null,
|
'asset': null,
|
||||||
'version': '0.9',
|
'version': '0.9',
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default function makeTransaction(operation, asset, metadata = null, outputs = [], inputs = []) {
|
export default function makeTransaction(operation, asset, metadata = null, outputs = [], inputs = []) {
|
||||||
const tx = makeTransactionTemplate();
|
const tx = makeTransactionTemplate()
|
||||||
tx.operation = operation;
|
tx.operation = operation
|
||||||
tx.asset = asset;
|
tx.asset = asset
|
||||||
tx.metadata = metadata;
|
tx.metadata = metadata
|
||||||
tx.inputs = inputs;
|
tx.inputs = inputs
|
||||||
tx.outputs = outputs;
|
tx.outputs = outputs
|
||||||
|
|
||||||
// Hashing must be done after, as the hash is of the Transaction (up to now)
|
// Hashing must be done after, as the hash is of the Transaction (up to now)
|
||||||
tx.id = hashTransaction(tx);
|
tx.id = hashTransaction(tx)
|
||||||
return tx;
|
return tx
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import makeInputTemplate from './makeInputTemplate';
|
import makeInputTemplate from './makeInputTemplate'
|
||||||
import makeTransaction from './makeTransaction';
|
import makeTransaction from './makeTransaction'
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -22,21 +22,26 @@ import makeTransaction from './makeTransaction';
|
|||||||
* @returns {object} Unsigned transaction -- make sure to call signTransaction() on it before
|
* @returns {object} Unsigned transaction -- make sure to call signTransaction() on it before
|
||||||
* sending it off!
|
* sending it off!
|
||||||
*/
|
*/
|
||||||
export default function makeTransferTransaction(unspentTransaction, metadata, outputs, ...fulfilledOutputs) {
|
export default function makeTransferTransaction(
|
||||||
|
unspentTransaction,
|
||||||
|
metadata,
|
||||||
|
outputs,
|
||||||
|
...fulfilledOutputs
|
||||||
|
) {
|
||||||
const inputs = fulfilledOutputs.map((outputIndex) => {
|
const inputs = fulfilledOutputs.map((outputIndex) => {
|
||||||
const fulfilledOutput = unspentTransaction.outputs[outputIndex];
|
const fulfilledOutput = unspentTransaction.outputs[outputIndex]
|
||||||
const transactionLink = {
|
const transactionLink = {
|
||||||
'output': outputIndex,
|
'output': outputIndex,
|
||||||
'txid': unspentTransaction.id,
|
'txid': unspentTransaction.id,
|
||||||
};
|
}
|
||||||
|
|
||||||
return makeInputTemplate(fulfilledOutput.public_keys, transactionLink);
|
return makeInputTemplate(fulfilledOutput.public_keys, transactionLink)
|
||||||
});
|
})
|
||||||
|
|
||||||
const assetLink = {
|
const assetLink = {
|
||||||
'id': unspentTransaction.operation === 'CREATE' ? unspentTransaction.id
|
'id': unspentTransaction.operation === 'CREATE' ? unspentTransaction.id
|
||||||
: unspentTransaction.asset.id
|
: unspentTransaction.asset.id
|
||||||
};
|
}
|
||||||
|
|
||||||
return makeTransaction('TRANSFER', assetLink, metadata, outputs, inputs);
|
return makeTransaction('TRANSFER', assetLink, metadata, outputs, inputs)
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import stableStringify from 'json-stable-stringify';
|
import stableStringify from 'json-stable-stringify'
|
||||||
import clone from 'clone';
|
import clone from 'clone'
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -10,8 +10,8 @@ import clone from 'clone';
|
|||||||
*/
|
*/
|
||||||
export default function serializeTransactionIntoCanonicalString(transaction) {
|
export default function serializeTransactionIntoCanonicalString(transaction) {
|
||||||
// BigchainDB signs fulfillments by serializing transactions into a "canonical" format where
|
// BigchainDB signs fulfillments by serializing transactions into a "canonical" format where
|
||||||
const tx = clone(transaction);
|
const tx = clone(transaction)
|
||||||
// TODO: set fulfillments to null
|
// TODO: set fulfillments to null
|
||||||
// Sort the keys
|
// Sort the keys
|
||||||
return stableStringify(tx, (a, b) => (a.key > b.key ? 1 : -1));
|
return stableStringify(tx, (a, b) => (a.key > b.key ? 1 : -1))
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { Buffer } from 'buffer';
|
import { Buffer } from 'buffer'
|
||||||
import base58 from 'bs58';
|
import base58 from 'bs58'
|
||||||
import cc from 'five-bells-condition';
|
import cc from 'five-bells-condition'
|
||||||
import clone from 'clone';
|
import clone from 'clone'
|
||||||
|
|
||||||
import serializeTransactionIntoCanonicalString from './serializeTransactionIntoCanonicalString';
|
import serializeTransactionIntoCanonicalString from './serializeTransactionIntoCanonicalString'
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -19,17 +19,17 @@ import serializeTransactionIntoCanonicalString from './serializeTransactionIntoC
|
|||||||
* @returns {object} The signed version of `transaction`.
|
* @returns {object} The signed version of `transaction`.
|
||||||
*/
|
*/
|
||||||
export default function signTransaction(transaction, ...privateKeys) {
|
export default function signTransaction(transaction, ...privateKeys) {
|
||||||
const signedTx = clone(transaction);
|
const signedTx = clone(transaction)
|
||||||
signedTx.inputs.forEach((input, index) => {
|
signedTx.inputs.forEach((input, index) => {
|
||||||
const privateKey = privateKeys[index];
|
const privateKey = privateKeys[index]
|
||||||
const privateKeyBuffer = new Buffer(base58.decode(privateKey));
|
const privateKeyBuffer = new Buffer(base58.decode(privateKey))
|
||||||
const serializedTransaction = serializeTransactionIntoCanonicalString(transaction);
|
const serializedTransaction = serializeTransactionIntoCanonicalString(transaction)
|
||||||
const ed25519Fulfillment = new cc.Ed25519();
|
const ed25519Fulfillment = new cc.Ed25519()
|
||||||
ed25519Fulfillment.sign(new Buffer(serializedTransaction), privateKeyBuffer);
|
ed25519Fulfillment.sign(new Buffer(serializedTransaction), privateKeyBuffer)
|
||||||
const fulfillmentUri = ed25519Fulfillment.serializeUri();
|
const fulfillmentUri = ed25519Fulfillment.serializeUri()
|
||||||
|
|
||||||
input.fulfillment = fulfillmentUri;
|
input.fulfillment = fulfillmentUri
|
||||||
});
|
})
|
||||||
|
|
||||||
return signedTx;
|
return signedTx
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import base58 from 'bs58';
|
import { Buffer } from 'buffer'
|
||||||
import cc from 'five-bells-condition';
|
import base58 from 'bs58'
|
||||||
import { Buffer } from 'buffer';
|
import cc from 'five-bells-condition'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
@ -9,41 +9,41 @@ import { Buffer } from 'buffer';
|
|||||||
* @returns {cc.Condition} Ed25519 Condition (that will need to wrapped in an Output)
|
* @returns {cc.Condition} Ed25519 Condition (that will need to wrapped in an Output)
|
||||||
*/
|
*/
|
||||||
export default function ccJsonLoad(conditionJson) {
|
export default function ccJsonLoad(conditionJson) {
|
||||||
|
|
||||||
if ('hash' in conditionJson) {
|
if ('hash' in conditionJson) {
|
||||||
let condition = new cc.Condition();
|
const condition = new cc.Condition()
|
||||||
condition.type = conditionJson.type_id;
|
condition.type = conditionJson.type_id
|
||||||
condition.bitmask = conditionJson.bitmask;
|
condition.bitmask = conditionJson.bitmask
|
||||||
condition.hash = new Buffer(base58.decode(conditionJson.hash));
|
condition.hash = new Buffer(base58.decode(conditionJson.hash))
|
||||||
condition.maxFulfillmentLength = parseInt(conditionJson.max_fulfillment_length, 10);
|
condition.maxFulfillmentLength = parseInt(conditionJson.max_fulfillment_length, 10)
|
||||||
return condition
|
return condition
|
||||||
} else {
|
} else {
|
||||||
let fulfillment;
|
let fulfillment
|
||||||
|
|
||||||
if (conditionJson.type_id === 2) {
|
if (conditionJson.type_id === 2) {
|
||||||
fulfillment = new cc.ThresholdSha256();
|
fulfillment = new cc.ThresholdSha256()
|
||||||
fulfillment.threshold = conditionJson.threshold;
|
fulfillment.threshold = conditionJson.threshold
|
||||||
conditionJson.subfulfillments.forEach((subfulfillment) => {
|
conditionJson.subfulfillments.forEach((subfulfillmentJson) => {
|
||||||
subfulfillment = ccJsonLoad(subfulfillment);
|
const subfulfillment = ccJsonLoad(subfulfillmentJson)
|
||||||
if ('getConditionUri' in subfulfillment)
|
if ('getConditionUri' in subfulfillment) {
|
||||||
fulfillment.addSubfulfillment(subfulfillment);
|
fulfillment.addSubfulfillment(subfulfillment)
|
||||||
else if ('serializeUri' in subfulfillment)
|
} else if ('serializeUri' in subfulfillment) {
|
||||||
fulfillment.addSubcondition(subfulfillment)
|
fulfillment.addSubcondition(subfulfillment)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conditionJson.type_id === 0) {
|
if (conditionJson.type_id === 0) {
|
||||||
fulfillment = new cc.PreimageSha256();
|
fulfillment = new cc.PreimageSha256()
|
||||||
fulfillment.preimage = new Buffer(conditionJson.preimage);
|
fulfillment.preimage = new Buffer(conditionJson.preimage)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conditionJson.type_id === 4) {
|
if (conditionJson.type_id === 4) {
|
||||||
fulfillment = new cc.Ed25519();
|
fulfillment = new cc.Ed25519()
|
||||||
fulfillment.publicKey = new Buffer(base58.decode(conditionJson.public_key));
|
fulfillment.publicKey = new Buffer(base58.decode(conditionJson.public_key))
|
||||||
if (conditionJson.signature)
|
if (conditionJson.signature) {
|
||||||
fulfillment.signature = new Buffer(base58.decode(conditionJson.signature));
|
fulfillment.signature = new Buffer(base58.decode(conditionJson.signature))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return fulfillment;
|
return fulfillment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,36 +1,36 @@
|
|||||||
import base58 from 'bs58';
|
import base58 from 'bs58'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
* Serializes a crypto-condition class (Condition or Fulfillment) into a BigchainDB-compatible JSON
|
* Serializes a crypto-condition class (Condition or Fulfillment) into a BigchainDB-compatible JSON
|
||||||
* @param {cc.Fulfillment} fulfillment base58 encoded Ed25519 public key for the recipient of the Transaction
|
* @param {cc.Fulfillment} fulfillment base58 encoded Ed25519 public key for recipient of the Transaction
|
||||||
* @returns {object} Ed25519 Condition (that will need to wrapped in an Output)
|
* @returns {object} Ed25519 Condition (that will need to wrapped in an Output)
|
||||||
*/
|
*/
|
||||||
export default function ccJsonify(fulfillment) {
|
export default function ccJsonify(fulfillment) {
|
||||||
|
let conditionUri
|
||||||
|
|
||||||
let conditionUri;
|
if ('getConditionUri' in fulfillment) {
|
||||||
|
conditionUri = fulfillment.getConditionUri()
|
||||||
|
} else if ('serializeUri' in fulfillment) {
|
||||||
|
conditionUri = fulfillment.serializeUri()
|
||||||
|
}
|
||||||
|
|
||||||
if ('getConditionUri' in fulfillment)
|
const jsonBody = {
|
||||||
conditionUri = fulfillment.getConditionUri();
|
|
||||||
else if ('serializeUri' in fulfillment)
|
|
||||||
conditionUri = fulfillment.serializeUri();
|
|
||||||
|
|
||||||
let jsonBody = {
|
|
||||||
'details': {},
|
'details': {},
|
||||||
'uri': conditionUri,
|
'uri': conditionUri,
|
||||||
};
|
}
|
||||||
|
|
||||||
if (fulfillment.getTypeId() === 0) {
|
if (fulfillment.getTypeId() === 0) {
|
||||||
jsonBody.details.type_id = 0;
|
jsonBody.details.type_id = 0
|
||||||
jsonBody.details.bitmask = 3;
|
jsonBody.details.bitmask = 3
|
||||||
|
|
||||||
if ('preimage' in fulfillment) {
|
if ('preimage' in fulfillment) {
|
||||||
jsonBody.details.preimage = fulfillment.preimage.toString();
|
jsonBody.details.preimage = fulfillment.preimage.toString()
|
||||||
jsonBody.details.type = 'fulfillment';
|
jsonBody.details.type = 'fulfillment'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fulfillment.getTypeId() === 2)
|
if (fulfillment.getTypeId() === 2) {
|
||||||
return {
|
return {
|
||||||
'details': {
|
'details': {
|
||||||
'type_id': 2,
|
'type_id': 2,
|
||||||
@ -38,30 +38,31 @@ export default function ccJsonify(fulfillment) {
|
|||||||
'bitmask': fulfillment.getBitmask(),
|
'bitmask': fulfillment.getBitmask(),
|
||||||
'threshold': fulfillment.threshold,
|
'threshold': fulfillment.threshold,
|
||||||
'subfulfillments': fulfillment.subconditions.map((subcondition) => {
|
'subfulfillments': fulfillment.subconditions.map((subcondition) => {
|
||||||
const subconditionJson = ccJsonify(subcondition.body);
|
const subconditionJson = ccJsonify(subcondition.body)
|
||||||
subconditionJson.details.weight = 1;
|
subconditionJson.details.weight = 1
|
||||||
return subconditionJson.details;
|
return subconditionJson.details
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
'uri': conditionUri,
|
'uri': conditionUri,
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (fulfillment.getTypeId() === 4) {
|
if (fulfillment.getTypeId() === 4) {
|
||||||
jsonBody.details.type_id = 4;
|
jsonBody.details.type_id = 4
|
||||||
jsonBody.details.bitmask = 32;
|
jsonBody.details.bitmask = 32
|
||||||
|
|
||||||
if ('publicKey' in fulfillment) {
|
if ('publicKey' in fulfillment) {
|
||||||
jsonBody.details.signature = null;
|
jsonBody.details.signature = null
|
||||||
jsonBody.details.public_key = base58.encode(fulfillment.publicKey);
|
jsonBody.details.public_key = base58.encode(fulfillment.publicKey)
|
||||||
jsonBody.details.type = 'fulfillment';
|
jsonBody.details.type = 'fulfillment'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('hash' in fulfillment) {
|
if ('hash' in fulfillment) {
|
||||||
jsonBody.details.hash = base58.encode(fulfillment.hash);
|
jsonBody.details.hash = base58.encode(fulfillment.hash)
|
||||||
jsonBody.details.max_fulfillment_length = fulfillment.maxFulfillmentLength;
|
jsonBody.details.max_fulfillment_length = fulfillment.maxFulfillmentLength
|
||||||
jsonBody.details.type = 'condition';
|
jsonBody.details.type = 'condition'
|
||||||
}
|
}
|
||||||
|
|
||||||
return jsonBody;
|
return jsonBody
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,24 @@
|
|||||||
/* eslint-disable strict, no-console, object-shorthand */
|
/* eslint-disable strict, no-console, object-shorthand */
|
||||||
|
|
||||||
'use strict';
|
'use strict'
|
||||||
|
|
||||||
const path = require('path');
|
const path = require('path')
|
||||||
|
|
||||||
const webpack = require('webpack');
|
const webpack = require('webpack')
|
||||||
|
|
||||||
const PRODUCTION = process.env.NODE_ENV === 'production';
|
const PRODUCTION = process.env.NODE_ENV === 'production'
|
||||||
|
|
||||||
const PATHS = {
|
const PATHS = {
|
||||||
ENTRY: path.resolve(__dirname, './src/index.js'),
|
ENTRY: path.resolve(__dirname, './src/index.js'),
|
||||||
BUNDLE: path.resolve(__dirname, 'dist/bundle'),
|
BUNDLE: path.resolve(__dirname, 'dist/bundle'),
|
||||||
NODE_MODULES: path.resolve(__dirname, 'node_modules'),
|
NODE_MODULES: path.resolve(__dirname, 'node_modules'),
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
/** PLUGINS **/
|
/** PLUGINS **/
|
||||||
const PLUGINS = [
|
const PLUGINS = [
|
||||||
new webpack.NoEmitOnErrorsPlugin(),
|
new webpack.NoEmitOnErrorsPlugin(),
|
||||||
];
|
]
|
||||||
|
|
||||||
const PROD_PLUGINS = [
|
const PROD_PLUGINS = [
|
||||||
new webpack.optimize.UglifyJsPlugin({
|
new webpack.optimize.UglifyJsPlugin({
|
||||||
@ -34,10 +34,10 @@ const PROD_PLUGINS = [
|
|||||||
debug: false,
|
debug: false,
|
||||||
minimize: true,
|
minimize: true,
|
||||||
}),
|
}),
|
||||||
];
|
]
|
||||||
|
|
||||||
if (PRODUCTION) {
|
if (PRODUCTION) {
|
||||||
PLUGINS.push(...PROD_PLUGINS);
|
PLUGINS.push(...PROD_PLUGINS)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -75,6 +75,6 @@ const config = {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
|
|
||||||
module.exports = config;
|
module.exports = config
|
||||||
|
Loading…
Reference in New Issue
Block a user