restructuring

This commit is contained in:
diminator 2017-02-27 12:16:26 +01:00
parent 1c5ec81ed2
commit 1d950855e9
10 changed files with 810 additions and 317 deletions

13
constants/api_urls.js Normal file
View File

@ -0,0 +1,13 @@
/* eslint-disable prefer-template */
import { API_PATH } from './application_constants';
const ApiUrls = {
'transactions': API_PATH + 'transactions',
'transactions_detail': API_PATH + 'transactions/%(txId)s',
'outputs': API_PATH + 'outputs',
'statuses': API_PATH + 'statuses'
};
export default ApiUrls;

View File

@ -0,0 +1,8 @@
export const FLASK_BASE_URL = process.env.FLASK_BASE_URL;
export const BDB_SERVER_URL = process.env.BDB_SERVER_URL;
export const API_PATH = `${BDB_SERVER_URL}/api/v1/`;
export default {
API_PATH,
FLASK_BASE_URL,
};

689
dist/bundle/bundle.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

136
dist/node/index.js vendored
View File

@ -3,6 +3,7 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.BDB_SERVER_URL = undefined;
var _extends2 = require('babel-runtime/helpers/extends');
@ -14,6 +15,7 @@ exports.makeOutput = makeOutput;
exports.makeCreateTransaction = makeCreateTransaction;
exports.makeTransferTransaction = makeTransferTransaction;
exports.signTransaction = signTransaction;
exports.testMe = testMe;
var _buffer = require('buffer');
@ -193,8 +195,7 @@ function signTransaction(transaction) {
signedTx.inputs.forEach(function (input, index) {
var privateKey = privateKeys[index];
var privateKeyBuffer = new _buffer.Buffer(_bs2.default.decode(privateKey));
var serializedTransaction = serializeTransactionIntoCanonicalString(transaction);
var serializedTransaction = serializeTransactionIntoCanonicalString(transaction, input);
var ed25519Fulfillment = new _fiveBellsCondition2.default.Ed25519();
ed25519Fulfillment.sign(new _buffer.Buffer(serializedTransaction), privateKeyBuffer);
var fulfillmentUri = ed25519Fulfillment.serializeUri();
@ -266,16 +267,137 @@ function sha256Hash(data) {
return _jsSha2.default.sha3_256.create().update(data).hex();
}
function serializeTransactionIntoCanonicalString(transaction) {
function serializeTransactionIntoCanonicalString(transaction, input) {
// BigchainDB signs fulfillments by serializing transactions into a "canonical" format where
// each fulfillment URI is removed before sorting the remaining keys
var tx = (0, _clone2.default)(transaction);
tx.inputs.forEach(function (input) {
input.fulfillment = null;
});
var match = void 0;
tx.inputs.forEach(function (_input) {
if (!(_input && input && _input['fulfills'] && input['fulfills'] && !(_input['fulfills']['txid'] === input['fulfills']['txid'] && _input['fulfills']['output'] === input['fulfills']['output']))) {
match = tx.inputs.indexOf(_input);
}
_input.fulfillment = null;
});
if (input && match >= 0 && tx.inputs) {
tx.inputs = [tx.inputs[match]];
}
// Sort the keys
return (0, _jsonStableStringify2.default)(tx, function (a, b) {
return a.key > b.key ? 1 : -1;
});
}
}
var BDB_SERVER_URL = exports.BDB_SERVER_URL = process.env.BDB_SERVER_URL;
function testMe() {
return 'test';
}
// import { request as baseRequest, sanitize } from 'js-utility-belt/es6';
//
// const FLASK_BASE_URL = process.env.FLASK_BASE_URL;
// export const BDB_SERVER_URL = process.env.BDB_SERVER_URL;
// const API_PATH = `${BDB_SERVER_URL}/api/v1/`;
//
//
// const DEFAULT_REQUEST_CONFIG = {
// credentials: 'include',
// headers: {
// 'Accept': 'application/json'
// }
// };
//
// /**
// * Small wrapper around js-utility-belt's request that provides url resolving, default settings, and
// * response handling.
// */
// function request(url, config = {}) {
// // Load default fetch configuration and remove any falsy query parameters
// const requestConfig = Object.assign({}, DEFAULT_REQUEST_CONFIG, config, {
// query: config.query && sanitize(config.query)
// });
// let apiUrl = url;
//
// if (requestConfig.jsonBody) {
// requestConfig.headers = Object.assign({}, requestConfig.headers, {
// 'Content-Type': 'application/json'
// });
// }
// if (!url) {
// return Promise.reject(new Error('Request was not given a url.'));
// } else if (!url.match(/^http/)) {
// apiUrl = ApiUrls[url];
// if (!apiUrl) {
// return Promise.reject(new Error(`Request could not find a url mapping for "${url}"`));
// }
// }
//
// return baseRequest(apiUrl, requestConfig)
// .then((res) => res.json())
// .catch((err) => {
// console.error(err);
// throw err;
// });
// }
//
//
//
// export function requestTransaction(txId) {
// return request(ApiUrls['transactions_detail'], {
// urlTemplateSpec: {
// txId
// }
// });
// }
//
// export function postTransaction(transaction) {
// return request(ApiUrls['transactions'], {
// method: 'POST',
// jsonBody: transaction
// })
// }
//
// export function listTransactions({ asset_id, operation }) {
// return request(ApiUrls['transactions'], {
// query: {
// asset_id,
// operation
// }
// })
// }
//
// export function pollStatusAndFetchTransaction(transaction) {
// return new Promise((resolve, reject) => {
// const timer = setInterval(() => {
// requestStatus(transaction.id)
// .then((res) => {
// console.log('Fetched transaction status:', res);
// if (res.status === 'valid') {
// clearInterval(timer);
// requestTransaction(transaction.id)
// .then((res) => {
// console.log('Fetched transaction:', res);
// resolve();
// });
// }
// });
// }, 500)
// })
// }
//
// export function listOutputs({ public_key, unspent }) {
// return request(ApiUrls['outputs'], {
// query: {
// public_key,
// unspent
// }
// })
// }
//
// export function requestStatus(tx_id) {
// return request(ApiUrls['statuses'], {
// query: {
// tx_id
// }
// });
// }

117
index.js
View File

@ -228,3 +228,120 @@ function serializeTransactionIntoCanonicalString(transaction, input) {
// Sort the keys
return stableStringify(tx, (a, b) => (a.key > b.key ? 1 : -1));
}
import { request as baseRequest, sanitize } from 'js-utility-belt/es6';
// import { request } from 'utils/request';
//
// const FLASK_BASE_URL = process.env.FLASK_BASE_URL;
// export const BDB_SERVER_URL = process.env.BDB_SERVER_URL;
// const API_PATH = `${BDB_SERVER_URL}/api/v1/`;
//
//
const DEFAULT_REQUEST_CONFIG = {
credentials: 'include',
headers: {
'Accept': 'application/json'
}
};
/**
* Small wrapper around js-utility-belt's request that provides url resolving, default settings, and
* response handling.
*/
function request(url, config = {}) {
// Load default fetch configuration and remove any falsy query parameters
const requestConfig = Object.assign({}, DEFAULT_REQUEST_CONFIG, config, {
query: config.query && sanitize(config.query)
});
let apiUrl = url;
if (requestConfig.jsonBody) {
requestConfig.headers = Object.assign({}, requestConfig.headers, {
'Content-Type': 'application/json'
});
}
if (!url) {
return Promise.reject(new Error('Request was not given a url.'));
}
return baseRequest(apiUrl, requestConfig)
.then((res) => res.json())
.catch((err) => {
console.error(err);
throw err;
});
}
export function getApiUrls(API_PATH) {
return {
'transactions': API_PATH + 'transactions',
'transactions_detail': API_PATH + 'transactions/%(txId)s',
'outputs': API_PATH + 'outputs',
'statuses': API_PATH + 'statuses'
};
}
export function getTransaction(txId, API_PATH) {
return request(getApiUrls(API_PATH)['transactions_detail'], {
urlTemplateSpec: {
txId
}
});
}
export function postTransaction(transaction, API_PATH) {
return request(getApiUrls(API_PATH)['transactions'], {
method: 'POST',
jsonBody: transaction
})
}
export function listTransactions({ asset_id, operation }, API_PATH) {
return request(getApiUrls(API_PATH)['transactions'], {
query: {
asset_id,
operation
}
})
}
export function pollStatusAndFetchTransaction(transaction, API_PATH) {
return new Promise((resolve, reject) => {
const timer = setInterval(() => {
getStatus(transaction.id, API_PATH)
.then((res) => {
console.log('Fetched transaction status:', res);
if (res.status === 'valid') {
clearInterval(timer);
getTransaction(transaction.id, API_PATH)
.then((res) => {
console.log('Fetched transaction:', res);
resolve();
});
}
});
}, 500)
})
}
export function listOutputs({ public_key, unspent }, API_PATH) {
return request(getApiUrls(API_PATH)['outputs'], {
query: {
public_key,
unspent
}
})
}
export function getStatus(tx_id, API_PATH) {
return request(getApiUrls(API_PATH)['statuses'], {
query: {
tx_id
}
});
}

View File

@ -39,8 +39,11 @@
"buffer": "^5.0.2",
"clone": "^2.1.0",
"core-js": "^2.4.1",
"es6-promise": "^4.0.5",
"five-bells-condition": "=3.3.1",
"isomorphic-fetch": "^2.2.1",
"js-sha3": "^0.5.7",
"js-utility-belt": "^1.5.0",
"json-stable-stringify": "^1.0.1",
"tweetnacl": "^0.14.5"
},

63
utils/bigchaindb_utils.js Normal file
View File

@ -0,0 +1,63 @@
import request from './request';
import ApiUrls from '../constants/api_urls';
export function requestTransaction(txId) {
return request(ApiUrls['transactions_detail'], {
urlTemplateSpec: {
txId
}
});
}
export function postTransaction(transaction) {
return request(ApiUrls['transactions'], {
method: 'POST',
jsonBody: transaction
})
}
export function listTransactions({ asset_id, operation }) {
return request(ApiUrls['transactions'], {
query: {
asset_id,
operation
}
})
}
export function pollStatusAndFetchTransaction(transaction) {
return new Promise((resolve, reject) => {
const timer = setInterval(() => {
requestStatus(transaction.id)
.then((res) => {
console.log('Fetched transaction status:', res);
if (res.status === 'valid') {
clearInterval(timer);
requestTransaction(transaction.id)
.then((res) => {
console.log('Fetched transaction:', res);
resolve();
});
}
});
}, 500)
})
}
export function listOutputs({ public_key, unspent }) {
return request(ApiUrls['outputs'], {
query: {
public_key,
unspent
}
})
}
export function requestStatus(tx_id) {
return request(ApiUrls['statuses'], {
query: {
tx_id
}
});
}

44
utils/request.js Normal file
View File

@ -0,0 +1,44 @@
import { request as baseRequest, sanitize } from 'js-utility-belt/es6';
import ApiUrls from '../constants/api_urls';
const DEFAULT_REQUEST_CONFIG = {
credentials: 'include',
headers: {
'Accept': 'application/json'
}
};
/**
* Small wrapper around js-utility-belt's request that provides url resolving, default settings, and
* response handling.
*/
export default function request(url, config = {}) {
// Load default fetch configuration and remove any falsy query parameters
const requestConfig = Object.assign({}, DEFAULT_REQUEST_CONFIG, config, {
query: config.query && sanitize(config.query)
});
let apiUrl = url;
if (requestConfig.jsonBody) {
requestConfig.headers = Object.assign({}, requestConfig.headers, {
'Content-Type': 'application/json'
});
}
if (!url) {
return Promise.reject(new Error('Request was not given a url.'));
} else if (!url.match(/^http/)) {
apiUrl = ApiUrls[url];
if (!apiUrl) {
return Promise.reject(new Error(`Request could not find a url mapping for "${url}"`));
}
}
return baseRequest(apiUrl, requestConfig)
.then((res) => res.json())
.catch((err) => {
console.error(err);
throw err;
});
}