Skip to content

Commit

Permalink
Merge pull request #20 from gabidi/feature/wasabi
Browse files Browse the repository at this point in the history
Feature/wasabi
  • Loading branch information
gabidi authored May 5, 2020
2 parents 35ae751 + 262f605 commit 9151a3d
Show file tree
Hide file tree
Showing 9 changed files with 200 additions and 5 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# An Isomorphic Javascript SDK for Bitcoin, C-lightning and Opentimestamp Vis-à-vis CypherNode.
# An Isomorphic Javascript SDK for Bitcoin, C-lightning, Wasabi and Opentimestamp Vis-à-vis CypherNode.

# Why ?

Expand Down Expand Up @@ -80,7 +80,8 @@ Contains the individual clients that can be instaniated to access each of Cypher

- btcClient.js : All things bitcoin
- lncClient.js : All things lighting
- otsClient.js : All this opentimestamp
- otsClient.js : All things opentimestamp
- wasabi.js : All things Wasabi

Test files for each client are included that showcase the usage of functionality

Expand Down
14 changes: 12 additions & 2 deletions cli.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
const { client: lnclient } = require("./src/clients/lncClient");
const { client: btclient } = require("./src/clients/btcClient");
const { client: wasabiClient } = require("./src/clients/wasabiClient");
const repl = require("repl");

const ln = lnclient();
const btc = btclient();

const wasabi = wasabiClient();
const { log, error } = console;

module.exports = {ln,btc}
const replEvalPromise = (cmd, ctx, filename, cb) => {
let result = eval(cmd);
if (result instanceof Promise) {
return result.then(response => cb(null, response));
}
return cb(null, result);
};
repl.start({ prompt: "cyphernode-cli > ", eval: replEvalPromise });
2 changes: 2 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ var lncClient_1 = require("./src/clients/lncClient");
exports.lnClient = lncClient_1.client;
var otsClient_1 = require("./src/clients/otsClient");
exports.otsClient = otsClient_1.client;
var wasabiClient_1 = require("./src/clients/wasabiClient");
exports.wasabiClient = wasabiClient_1.client;
var cypherNodeHttpTransport_1 = require("./src/transport/cypherNodeHttpTransport");
exports.cypherNodeHttpTransport = cypherNodeHttpTransport_1.default;
var cryptoUtil_1 = require("./src/lib/cryptoUtil");
Expand Down
1 change: 1 addition & 0 deletions index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export { client as btcClient } from "./src/clients/btcClient";
export { client as lnClient } from "./src/clients/lncClient";
export { client as otsClient } from "./src/clients/otsClient";
export { client as wasabiClient } from "./src/clients/wasabiClient";
export {
default as cypherNodeHttpTransport
} from "./src/transport/cypherNodeHttpTransport";
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
"test:client:btc": "NODE_TLS_REJECT_UNAUTHORIZED=0 node -r dotenv/config ./node_modules/ava/cli.js ./src/clients/btcClient.spec.js",
"test:client:lnc": "NODE_TLS_REJECT_UNAUTHORIZED=0 node -r dotenv/config ./node_modules/ava/cli.js ./src/clients/lncClient.spec.js",
"test:client:ots": "NODE_TLS_REJECT_UNAUTHORIZED=0 node -r dotenv/config ./node_modules/ava/cli.js ./src/clients/otsClient.spec.js",
"test": "NODE_TLS_REJECT_UNAUTHORIZED=0 node -r dotenv/config ./node_modules/ava/cli.js ./src/lib/*.spec*.js ./src/clients/*.spec.js"
"test": "NODE_TLS_REJECT_UNAUTHORIZED=0 node -r dotenv/config ./node_modules/ava/cli.js ./src/lib/*.spec*.js ./src/clients/*.spec.js",
"cli": "CYPHERNODE_GATEKEEPER_CERT_CA=$(cat test.pem) node -r dotenv/config cli.js"
},
"optionalDependencies": {
"superagent": "^5.2.2"
Expand Down
2 changes: 2 additions & 0 deletions src/clients/btcClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,8 @@ exports.client = function (_a) {
throw "Label is required to for a pub32 watch";
if (/[^0-9a-zA-Z_i ]/.test(options.label))
throw "Labels must be alpha numeric or _";
if (!options.nstart || isNaN(options.nstart))
throw "nstart must be provided and must be a number";
return [4 /*yield*/, post("watchxpub", __assign({ pub32: xpub }, options))];
case 1:
result = _a.sent();
Expand Down
68 changes: 68 additions & 0 deletions src/clients/wasabiClient.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var cypherNodeHttpTransport_1 = __importDefault(require("../transport/cypherNodeHttpTransport"));
exports.client = function (_a) {
var _b = (_a === void 0 ? {} : _a).transport, transport = _b === void 0 ? cypherNodeHttpTransport_1.default() : _b;
var get = transport.get, post = transport.post;
var api = {
getNewAddress: function (label) {
return post("wasabi_getnewaddress", { label: label });
},
getBalances: function (anonset) {
return get("wasabi_getbalances", anonset);
},
getUnspentCoins: function (instanceId) {
return get("wasabi_getunspentcoins", instanceId);
},
getTxns: function (instanceId) {
return get("wasabi_gettransactions", instanceId);
},
spend: function (param) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2 /*return*/, post("wasabi_spend", param)];
});
});
}
};
return api;
};
43 changes: 43 additions & 0 deletions src/clients/wasabiClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import cypherNodeHTTPTransport from "../transport/cypherNodeHttpTransport";
import { ClientConfig } from "../lib/types/clients";
import {
WasabiClient,
Address,
WasabiGetBalancesPayload,
WasabiGetTxnsPayload,
WasabiNewAddressPayload,
WasabiSpendPayload,
WasabiGetUnspentCoinsPayload
} from "../lib/types/wasabi.d";

export const client = ({
transport = cypherNodeHTTPTransport()
}: ClientConfig = {}): WasabiClient => {
const { get, post } = transport;
const api = {
getNewAddress(label: string): Promise<WasabiNewAddressPayload> {
return post("wasabi_getnewaddress", { label });
},
getBalances(anonset?: number): Promise<WasabiGetBalancesPayload> {
return get("wasabi_getbalances", anonset);
},
getUnspentCoins(
instanceId?: number
): Promise<WasabiGetUnspentCoinsPayload> {
return get("wasabi_getunspentcoins", instanceId);
},
getTxns(instanceId?: number): Promise<WasabiGetTxnsPayload> {
return get("wasabi_gettransactions", instanceId);
},
async spend(param: {
address: Address;
amount: number;
instanceId?: number;
private?: boolean;
minanonset?: number;
}): Promise<WasabiSpendPayload> {
return post("wasabi_spend", param);
}
};
return api;
};
67 changes: 67 additions & 0 deletions src/lib/types/wasabi.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
export type Hash = string; // '0000000000000000001c6a6ae90f3f90f9a02098f5f447dc3ee09649097fa2cf'
export type BlockHash = Hash;
export type BlockHeight = number;
export type MerkleRoot = Hash;
export type TxnHash = Hash;
export type TimeStamp = number;
export type TxnHex = string;
export type TxnId = string;
export type Address = string;
export type AddressType = "bech32" | "legacy" | "p2sh-segwit" | "expub";
export interface WasabiNewAddressPayload {
address: Address;
keyPath: string; //"84'/0'/0'/0/23";
label: string; //'["unknown"]';
}
export interface WasabiGetBalancesPayload {
[instanceId: string]: { private: number; total: number };
}
export interface WasabiTxn {
datetime: string; // "2020-04-23T18:10:36+00:00";
height: number; //1721643;
amount: number; // 340000;
label: string; // "mytest";
tx: string; // "220850ec4d8a8daf6ebe9e74f4ab29ffca3392ff03a081c4915a83cb56b9e0e5";
}
export interface WasabiGetTxnsPayload {
instanceId: number | null;
transactions: [WasabiTxn];
}
export interface WasabiUnspentCoint {
txid: string; //"d914f27248354d5f1886ebf393f2a2ba9fd56a0c67e864cf5e549cdade8b351f";
index: number; // 0;
amount: number; //15815;
anonymitySet: number; // 9;
confirmed: boolean; // true;
label: string; // "";
keyPath: string; // "84'/0'/0'/1/1892";
address: string; // "tb1qlvxadhum3k5nthv8g9nkhze43sk9v727jnhkxj";
}
export interface WasabiGetUnspentCoinsPayload {
instanceId: number | null;
transactions: [WasabiUnspentCoint];
}
export interface WasabiSpendPayload {
message: string;
result:
| {
txid: string;
tx: string;
}
| "error";
event: string;
}

export interface WasabiClient {
getNewAddress(label: string): Promise<WasabiNewAddressPayload>;
getBalances(anonset?: number): Promise<WasabiGetBalancesPayload>;
getTxns(instanceId: number): Promise<WasabiGetTxnsPayload>;
getUnspentCoins(instanceId?: number): Promise<WasabiGetUnspentCoinsPayload>;
spend(param: {
address: Address;
amount: number;
instanceId?: number;
private?: boolean;
minanonset?: number;
}): Promise<WasabiSpendPayload>;
}

0 comments on commit 9151a3d

Please sign in to comment.