restructuring
This commit is contained in:
parent
1c5ec81ed2
commit
1d950855e9
|
@ -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;
|
|
@ -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,
|
||||
};
|
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
|
@ -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
117
index.js
|
@ -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
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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"
|
||||
},
|
||||
|
|
|
@ -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
|
||||
}
|
||||
});
|
||||
}
|
|
@ -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;
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue