Skip to content

Commit

Permalink
Merge pull request #308 from bigchaindb/add-type-defs
Browse files Browse the repository at this point in the history
Add type defs
  • Loading branch information
getlarge authored Mar 10, 2021
2 parents 7fe9040 + 1779f6e commit 6aa5f01
Show file tree
Hide file tree
Showing 15 changed files with 640 additions and 25 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
],
"main": "./dist/node/index.js",
"browser": "./dist/browser/bigchaindb-driver.cjs2.min.js",
"types": "./types/index.d.ts",
"sideEffects": false,
"scripts": {
"lint": "eslint .",
Expand Down
13 changes: 8 additions & 5 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
// SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0)
// Code is Apache-2.0 and docs are CC-BY-4.0

export Ed25519Keypair from './Ed25519Keypair'
import Ed25519Keypair from './Ed25519Keypair'
import Connection from './connection'
import Transaction from './transaction'
import ccJsonLoad from './utils/ccJsonLoad'
import ccJsonify from './utils/ccJsonify'

export Connection from './connection'
export Transaction from './transaction'
export ccJsonLoad from './utils/ccJsonLoad'
export ccJsonify from './utils/ccJsonify'
export {
ccJsonLoad, ccJsonify, Connection, Ed25519Keypair, Transaction
}
18 changes: 9 additions & 9 deletions src/utils/ccJsonLoad.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@
// SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0)
// Code is Apache-2.0 and docs are CC-BY-4.0

import { Buffer } from 'buffer'
import base58 from 'bs58'
import cc from 'crypto-conditions'
import { Condition, Ed25519Sha256, ThresholdSha256 } from 'crypto-conditions'

/**
* Loads a crypto-condition class (Fulfillment or Condition) from a BigchainDB JSON object
Expand All @@ -13,17 +12,18 @@ import cc from 'crypto-conditions'
*/
export default function ccJsonLoad(conditionJson) {
if ('hash' in conditionJson) {
const condition = new cc.Condition()
condition.type = conditionJson.type_id
condition.bitmask = conditionJson.bitmask
condition.hash = Buffer.from(base58.decode(conditionJson.hash))
const condition = new Condition()
condition.setTypeId(conditionJson.type_id)
condition.setSubtypes(conditionJson.bitmask)
condition.setHash(base58.decode(conditionJson.hash))
// TODO: fix this, maxFulfillmentLength cannot be set in CryptoCondition lib
condition.maxFulfillmentLength = parseInt(conditionJson.max_fulfillment_length, 10)
return condition
} else {
let fulfillment

if (conditionJson.type === 'threshold-sha-256') {
fulfillment = new cc.ThresholdSha256()
fulfillment = new ThresholdSha256()
fulfillment.threshold = conditionJson.threshold
conditionJson.subconditions.forEach((subconditionJson) => {
const subcondition = ccJsonLoad(subconditionJson)
Expand All @@ -36,8 +36,8 @@ export default function ccJsonLoad(conditionJson) {
}

if (conditionJson.type === 'ed25519-sha-256') {
fulfillment = new cc.Ed25519Sha256()
fulfillment.publicKey = Buffer.from(base58.decode(conditionJson.public_key))
fulfillment = new Ed25519Sha256()
fulfillment.setPublicKey(base58.decode(conditionJson.public_key))
}
return fulfillment
}
Expand Down
14 changes: 7 additions & 7 deletions src/utils/ccJsonify.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ export default function ccJsonify(fulfillment) {
}

const jsonBody = {
'details': {},
'uri': conditionUri,
details: {},
uri: conditionUri,
}

if (fulfillment.getTypeId() === 0) {
Expand All @@ -35,15 +35,15 @@ export default function ccJsonify(fulfillment) {

if (fulfillment.getTypeId() === 2) {
return {
'details': {
'type': 'threshold-sha-256',
'threshold': fulfillment.threshold,
'subconditions': fulfillment.subconditions.map((subcondition) => {
details: {
type: 'threshold-sha-256',
threshold: fulfillment.threshold,
subconditions: fulfillment.subconditions.map((subcondition) => {
const subconditionJson = ccJsonify(subcondition.body)
return subconditionJson.details
})
},
'uri': conditionUri,
uri: conditionUri,
}
}

Expand Down
11 changes: 7 additions & 4 deletions test/transaction/test_cryptoconditions.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
// SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0)
// Code is Apache-2.0 and docs are CC-BY-4.0

import { createHash } from 'crypto'
import { validateFulfillment } from 'crypto-conditions'
import test from 'ava'
import cc from 'crypto-conditions'
import base58 from 'bs58'
import { Ed25519Keypair, Transaction, ccJsonLoad } from '../../src'
import { delegatedSignTransaction } from '../constants'
import sha256Hash from '../../src/sha256Hash'
Expand Down Expand Up @@ -89,7 +91,7 @@ test('Fulfillment correctly formed', t => {
.concat(txTransfer.inputs[0].fulfills.output_index) : msg
const msgHash = sha256Hash(msgUniqueFulfillment)

t.truthy(cc.validateFulfillment(
t.truthy(validateFulfillment(
txSigned.inputs[0].fulfillment, txCreate.outputs[0].condition.uri,
Buffer.from(msgHash, 'hex')
))
Expand All @@ -114,15 +116,16 @@ test('Delegated signature is correct', t => {
})

test('CryptoConditions JSON load', t => {
const publicKey = '4zvwRjXUKGfvwnParsHAS3HuSVzV5cA4McphgmoCtajS'
const cond = ccJsonLoad({
type: 'threshold-sha-256',
threshold: 1,
subconditions: [{
type: 'ed25519-sha-256',
public_key: 'a'
public_key: publicKey
},
{
hash: 'a'
hash: base58.encode(createHash('sha256').update('a').digest())
}],
})
t.truthy(cond.subconditions.length === 2)
Expand Down
10 changes: 10 additions & 0 deletions types/Ed25519Keypair.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// 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

export default class Ed25519Keypair {
publicKey: string;
privateKey: string;

constructor(seed?: Buffer);
}
31 changes: 31 additions & 0 deletions types/baseRequest.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// 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

export interface RequestConfig {
headers?: Record<string, string | string[]>;
jsonBody?: Record<string, any>;
query?: Record<string, any>;
method?: 'GET' | ' POST' | 'PUT';
urlTemplateSpec?: any[] | Record<string, any>;
[key: string]: any;
}

export function ResponseError(
message: string,
status?: number,
requestURI?: string
): void;

declare function timeout<T = Response>(
ms: number,
promise: Promise<T>
): Promise<T>;

declare function handleResponse(res: Response): Response;

export default function baseRequest(
url: string,
config: RequestConfig = {},
requestTimeout?: number
): Promise<Response>;
162 changes: 162 additions & 0 deletions types/connection.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
// 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

import type { RequestConfig } from './baseRequest';
import type { Node } from './request';
import type Transport from './transport';
import type {
CreateTransaction,
TransactionOperations,
TransferTransaction,
TransactionCommon,
} from './transaction';

declare const HEADER_BLACKLIST = ['content-type'];
declare const DEFAULT_NODE = 'http://localhost:9984/api/v1/';
declare const DEFAULT_TIMEOUT = 20000; // The default value is 20 seconds

export interface InputNode {
endpoint: string;
}

export enum Endpoints {
blocks = 'blocks',
blocksDetail = 'blocksDetail',
outputs = 'outputs',
transactions = 'transactions',
transactionsSync = 'transactionsSync',
transactionsAsync = 'transactionsAsync',
transactionsCommit = 'transactionsCommit',
transactionsDetail = 'transactionsDetail',
assets = 'assets',
metadata = 'metadata',
}

export interface EndpointsUrl {
[Endpoints.blocks]: 'blocks';
[Endpoints.blocksDetail]: 'blocks/%(blockHeight)s';
[Endpoints.outputs]: 'outputs';
[Endpoints.transactions]: 'transactions';
[Endpoints.transactionsSync]: 'transactions?mode=sync';
[Endpoints.transactionsAsync]: 'transactions?mode=async';
[Endpoints.transactionsCommit]: 'transactions?mode=commit';
[Endpoints.transactionsDetail]: 'transactions/%(transactionId)s';
[Endpoints.assets]: 'assets';
[Endpoints.metadata]: 'metadata';
}

export interface EndpointsResponse<
O = TransactionOperations.CREATE,
A = Record<string, any>,
M = Record<string, any>
> {
[Endpoints.blocks]: number[];
[Endpoints.blocksDetail]: {
height: number;
transactions: (CreateTransaction | TransferTransaction)[];
};
[Endpoints.outputs]: {
transaction_id: string;
output_index: number;
}[];
[Endpoints.transactions]: O extends TransactionOperations.CREATE
? CreateTransaction[]
: O extends TransactionOperations.TRANSFER
? TransferTransaction[]
: (CreateTransaction | TransferTransaction)[];
[Endpoints.transactionsSync]: O extends TransactionOperations.CREATE
? CreateTransaction<A, M>
: TransferTransaction<M>;
[Endpoints.transactionsAsync]: O extends TransactionOperations.CREATE
? CreateTransaction<A, M>
: TransferTransaction<M>;
[Endpoints.transactionsCommit]: O extends TransactionOperations.CREATE
? CreateTransaction<A, M>
: TransferTransaction<M>;
[Endpoints.transactionsDetail]: O extends TransactionOperations.CREATE
? CreateTransaction<A, M>
: TransferTransaction<M>;
[Endpoints.assets]: { id: string; data: Record<string, any> }[];
[Endpoints.metadata]: { id: string; metadata: Record<string, any> }[];
}

export default class Connection {
private transport: Transport;
private normalizedNodes: Node[];
private headers: Record<string, string | string[]>;

constructor(
nodes: string | InputNode | (string | InputNode)[],
headers: Record<string, string | string[]> = {},
timeout?: number
);

static normalizeNode(
node: string | InputNode,
headers: Record<string, string | string[]>
): Node;

static getApiUrls<E = Endpoint>(endpoint: E): EndpointsUrl[E];

private _req<E = Endpoint, O = Record<string, any>>(
path: EndpointsUrl[E],
options: RequestConfig = {}
): Promise<O>;

getBlock(
blockHeight: number | string
): Promise<EndpointsResponse[Endpoints.blocksDetail]>;

getTransaction<O = TransactionOperations.CREATE>(
transactionId: string
): Promise<EndpointsResponse<O>[Endpoints.transactionsDetail]>;

listBlocks(transactionId: string): Promise<EndpointsResponse[Endpoints.blocks]>;

listOutputs(
publicKey: string,
spent?: boolean
): Promise<EndpointsResponse[Endpoints.outputs]>;

listTransactions(
assetId: string,
operation?: TransactionOperations
): Promise<EndpointsResponse<typeof operation>[Endpoints.transactions]>;

postTransaction<
O = TransactionOperations.CREATE,
A = Record<string, any>,
M = Record<string, any>
>(
transaction: TransactionCommon<O>
): Promise<EndpointsResponse<O, A, M>[Endpoints.transactionsCommit]>;

postTransactionSync<
O = TransactionOperations.CREATE,
A = Record<string, any>,
M = Record<string, any>
>(
transaction: TransactionCommon<O>
): Promise<EndpointsResponse<O, A, M>[Endpoints.transactionsSync]>;

postTransactionAsync<
O = TransactionOperations.CREATE,
A = Record<string, any>,
M = Record<string, any>
>(
transaction: TransactionCommon<O>
): Promise<EndpointsResponse<O, A, M>[Endpoints.transactionsAsync]>;

postTransactionCommit<
O = TransactionOperations.CREATE,
A = Record<string, any>,
M = Record<string, any>
>(
transaction: TransactionCommon<O>
): Promise<EndpointsResponse<O, A, M>[Endpoints.transactionsCommit]>;

searchAssets(search: string): Promise<EndpointsResponse[Endpoints.assets]>;

searchMetadata(search: string): Promise<EndpointsResponse[Endpoints.metadata]>;
}
11 changes: 11 additions & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// 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

import Ed25519Keypair from './Ed25519Keypair'
import Connection from './connection'
import Transaction from './transaction'
import ccJsonLoad from './utils/ccJsonLoad'
import ccJsonify from './utils/ccJsonify'

export { ccJsonLoad, ccJsonify, Connection, Ed25519Keypair, Transaction }
32 changes: 32 additions & 0 deletions types/request.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// 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

import type { RequestConfig } from './baseRequest';

export interface Node {
endpoint: string;
headers: Record<string, string | string[]>;
}

export default class Request {
private node: Node;
private backoffTime: number;
private retries: number;
private connectionError?: Error;

constructor(node: Node);

async request<O = Record<string, any>>(
urlPath: string,
config: RequestConfig = {},
timeout?: number,
maxBackoffTime?: number
): Promise<O>;

updateBackoffTime(maxBackoffTime: number): void;

getBackoffTimedelta(): number;

static sleep(ms: number): void;
}
Loading

0 comments on commit 6aa5f01

Please sign in to comment.