js-bigchaindb-driver/src/connection.js

202 lines
5.3 KiB
JavaScript
Raw Normal View History

// Copyright BigchainDB GmbH and BigchainDB contributors
// SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0)
// Code is Apache-2.0 and docs are CC-BY-4.0
2018-08-23 17:14:59 +02:00
import Transport from './transport'
2017-05-11 12:45:19 +02:00
2017-06-22 17:19:31 +02:00
const HEADER_BLACKLIST = ['content-type']
2018-08-28 14:09:26 +02:00
const DEFAULT_NODE = 'http://localhost:9984/api/v1/'
2018-08-29 16:39:15 +02:00
const DEFAULT_TIMEOUT = 20000 // The default value is 20 seconds
2017-06-22 17:19:31 +02:00
/**
2018-08-22 10:10:09 +02:00
*
2018-08-28 14:09:26 +02:00
* @param {String, Array} nodes Nodes for the connection. String possible to be backwards compatible
* with version before 4.1.0 version
* @param {Object} headers Common headers for every request
* @param {float} timeout Optional timeout in secs
2018-08-22 10:10:09 +02:00
*
*
*/
2018-08-28 14:09:26 +02:00
2017-05-11 18:51:30 +02:00
export default class Connection {
// This driver implements the BEP-14 https://github.com/bigchaindb/BEPs/tree/master/14
2018-08-29 16:39:15 +02:00
constructor(nodes, headers = {}, timeout = DEFAULT_TIMEOUT) {
2018-08-22 10:10:09 +02:00
// Copy object
this.headers = { ...headers }
2017-06-22 17:19:31 +02:00
2018-08-22 10:10:09 +02:00
// Validate headers
2017-06-22 17:19:31 +02:00
Object.keys(headers).forEach(header => {
if (HEADER_BLACKLIST.includes(header.toLowerCase())) {
throw new Error(`Header ${header} is reserved and cannot be set.`)
}
})
2018-08-22 10:10:09 +02:00
this.normalizedNodes = []
2018-08-28 14:09:26 +02:00
if (!nodes) {
2018-08-22 10:10:09 +02:00
this.normalizedNodes.push(Connection.normalizeNode(DEFAULT_NODE, this.headers))
2018-08-28 14:09:26 +02:00
} else if (Array.isArray(nodes)) {
nodes.forEach(node => {
2018-08-22 10:10:09 +02:00
this.normalizedNodes.push(Connection.normalizeNode(node, this.headers))
})
2018-08-28 14:09:26 +02:00
} else {
this.normalizedNodes.push(Connection.normalizeNode(nodes, this.headers))
2018-08-22 10:10:09 +02:00
}
2018-08-28 14:09:26 +02:00
this.transport = new Transport(this.normalizedNodes, timeout)
2018-08-22 10:10:09 +02:00
}
static normalizeNode(node, headers) {
if (typeof node === 'string') {
return { 'endpoint': node, 'headers': headers }
} else {
const allHeaders = { ...headers, ...node.headers }
2018-08-23 17:14:59 +02:00
return { 'endpoint': node.endpoint, 'headers': allHeaders }
2018-08-22 10:10:09 +02:00
}
2017-05-11 17:19:07 +02:00
}
2017-05-11 12:45:19 +02:00
2018-08-22 10:10:09 +02:00
static getApiUrls(endpoint) {
return {
2017-06-19 14:40:22 +02:00
'blocks': 'blocks',
2018-03-21 11:30:54 +01:00
'blocksDetail': 'blocks/%(blockHeight)s',
2017-06-19 14:40:22 +02:00
'outputs': 'outputs',
'transactions': 'transactions',
2018-03-21 11:30:54 +01:00
'transactionsSync': 'transactions?mode=sync',
2018-06-12 14:42:42 +02:00
'transactionsAsync': 'transactions?mode=async',
2018-03-21 11:30:54 +01:00
'transactionsCommit': 'transactions?mode=commit',
2017-06-19 14:56:00 +02:00
'transactionsDetail': 'transactions/%(transactionId)s',
'assets': 'assets',
2018-08-28 15:38:36 +02:00
'metadata': 'metadata'
2017-06-21 11:17:59 +02:00
}[endpoint]
2017-05-11 17:19:07 +02:00
}
2017-05-11 12:45:19 +02:00
2017-06-12 16:57:29 +02:00
_req(path, options = {}) {
2018-08-29 16:39:15 +02:00
return this.transport.forwardRequest(path, options)
2017-05-11 17:19:07 +02:00
}
2017-05-11 12:45:19 +02:00
2017-05-11 17:19:07 +02:00
/**
2018-03-21 11:30:54 +01:00
* @param blockHeight
2017-05-11 17:19:07 +02:00
*/
2018-03-21 11:30:54 +01:00
getBlock(blockHeight) {
2018-08-22 10:10:09 +02:00
return this._req(Connection.getApiUrls('blocksDetail'), {
2017-06-12 16:57:29 +02:00
urlTemplateSpec: {
2018-03-21 11:30:54 +01:00
blockHeight
2017-06-12 16:57:29 +02:00
}
})
2017-05-11 17:19:07 +02:00
}
2017-05-11 12:45:19 +02:00
2017-05-11 17:19:07 +02:00
/**
2017-06-19 14:40:22 +02:00
* @param transactionId
2017-05-11 17:19:07 +02:00
*/
2017-06-19 14:40:22 +02:00
getTransaction(transactionId) {
2018-08-22 10:10:09 +02:00
return this._req(Connection.getApiUrls('transactionsDetail'), {
2017-06-12 16:57:29 +02:00
urlTemplateSpec: {
2017-06-19 14:56:00 +02:00
transactionId
2017-06-12 16:57:29 +02:00
}
})
2017-05-11 17:19:07 +02:00
}
2017-05-11 12:45:19 +02:00
2017-05-11 17:19:07 +02:00
/**
2017-06-19 14:40:22 +02:00
* @param transactionId
2017-05-11 17:19:07 +02:00
* @param status
*/
2018-03-21 11:30:54 +01:00
listBlocks(transactionId) {
2018-08-22 10:10:09 +02:00
return this._req(Connection.getApiUrls('blocks'), {
2017-06-12 16:57:29 +02:00
query: {
2017-06-19 14:40:22 +02:00
transaction_id: transactionId,
2017-06-12 16:57:29 +02:00
}
})
2017-05-11 17:19:07 +02:00
}
2017-05-11 12:45:19 +02:00
2017-05-11 17:19:07 +02:00
/**
2017-06-20 17:46:25 +02:00
* @param publicKey
* @param spent
2017-05-11 17:19:07 +02:00
*/
listOutputs(publicKey, spent) {
2017-06-20 17:46:25 +02:00
const query = {
public_key: publicKey
}
// NOTE: If `spent` is not defined, it must not be included in the
// query parameters.
if (spent !== undefined) {
query.spent = spent.toString()
2017-06-20 17:46:25 +02:00
}
2018-08-22 10:10:09 +02:00
return this._req(Connection.getApiUrls('outputs'), {
2017-06-20 17:46:25 +02:00
query
})
2017-05-11 17:19:07 +02:00
}
2017-05-11 12:45:19 +02:00
2017-05-11 17:19:07 +02:00
/**
2017-06-21 11:01:28 +02:00
* @param assetId
2017-05-11 17:19:07 +02:00
* @param operation
*/
2017-06-21 11:01:28 +02:00
listTransactions(assetId, operation) {
2018-08-22 10:10:09 +02:00
return this._req(Connection.getApiUrls('transactions'), {
2017-05-11 17:19:07 +02:00
query: {
2017-06-21 11:01:28 +02:00
asset_id: assetId,
2017-05-11 17:19:07 +02:00
operation
}
})
}
/**
2018-03-21 11:30:54 +01:00
* @param transaction
2017-05-11 17:19:07 +02:00
*/
2018-03-21 11:30:54 +01:00
postTransaction(transaction) {
2018-06-19 16:52:23 +02:00
return this.postTransactionCommit(transaction)
2017-05-11 17:19:07 +02:00
}
2017-05-11 12:45:19 +02:00
2017-05-11 17:19:07 +02:00
/**
* @param transaction
*/
2018-03-21 11:30:54 +01:00
postTransactionSync(transaction) {
2018-08-22 10:10:09 +02:00
return this._req(Connection.getApiUrls('transactionsSync'), {
2018-03-21 11:30:54 +01:00
method: 'POST',
jsonBody: transaction
})
}
2018-06-12 14:42:42 +02:00
/**
* @param transaction
*/
postTransactionAsync(transaction) {
2018-08-22 10:10:09 +02:00
return this._req(Connection.getApiUrls('transactionsAsync'), {
2018-06-12 14:42:42 +02:00
method: 'POST',
jsonBody: transaction
})
}
2018-03-21 11:30:54 +01:00
/**
* @param transaction
*/
postTransactionCommit(transaction) {
2018-08-22 10:10:09 +02:00
return this._req(Connection.getApiUrls('transactionsCommit'), {
2017-05-11 17:19:07 +02:00
method: 'POST',
jsonBody: transaction
})
}
2017-05-14 16:35:47 +02:00
/**
* @param search
2017-05-14 16:35:47 +02:00
*/
searchAssets(search, limit = 10) {
2018-08-22 10:10:09 +02:00
return this._req(Connection.getApiUrls('assets'), {
2017-05-14 16:35:47 +02:00
query: {
search,
limit
2017-05-14 16:35:47 +02:00
}
})
}
2017-11-21 16:51:31 +01:00
/**
* @param search
*/
searchMetadata(search, limit = 10) {
2018-08-22 10:10:09 +02:00
return this._req(Connection.getApiUrls('metadata'), {
2017-11-21 16:51:31 +01:00
query: {
search,
limit
2017-11-21 16:51:31 +01:00
}
})
}
2017-05-11 12:45:19 +02:00
}