mirror of https://github.com/vacp2p/waku-ts.git
basic tests
This commit is contained in:
parent
0e32a1f136
commit
28ad834b94
|
@ -60,7 +60,9 @@
|
|||
"trailingComma": "es5"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.19.2",
|
||||
"basic-provider": "^1.1.0",
|
||||
"eccrypto-js": "^5.2.0"
|
||||
"eccrypto-js": "^5.2.0",
|
||||
"localStorage": "^1.0.4"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,11 @@ class Waku implements IWakuClient {
|
|||
this.signer = new WakuSigner(this.store);
|
||||
}
|
||||
|
||||
public async init(): Promise<any> {
|
||||
await this.signer.init();
|
||||
return this.provider.init();
|
||||
}
|
||||
|
||||
public async request(payload: JsonRpcRequest): Promise<any> {
|
||||
if (isSignerMethod(payload.method)) {
|
||||
return this.signer.request(payload);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import axios from "axios";
|
||||
import { EventEmitter } from "events";
|
||||
import { IRpcConnection } from "basic-provider";
|
||||
|
||||
|
@ -7,10 +8,7 @@ export class HttpConnection extends EventEmitter implements IRpcConnection {
|
|||
|
||||
constructor(url: string) {
|
||||
super();
|
||||
if (url) {
|
||||
this.url = url;
|
||||
this.connected = true;
|
||||
}
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public async send(payload: any): Promise<any> {
|
||||
|
@ -20,22 +18,26 @@ export class HttpConnection extends EventEmitter implements IRpcConnection {
|
|||
if (!this.connected) {
|
||||
throw new Error("HttpConnection is closed");
|
||||
}
|
||||
const response = await fetch(this.url, {
|
||||
method: "post",
|
||||
const { data } = await axios.post(this.url, payload, {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
const result = await response.json();
|
||||
return result;
|
||||
if (data.error) {
|
||||
throw new Error(data.error.message);
|
||||
}
|
||||
return data.result;
|
||||
}
|
||||
|
||||
public async open(): Promise<void> {
|
||||
this.connected = true;
|
||||
this.emit("connect");
|
||||
return;
|
||||
}
|
||||
|
||||
public async close(): Promise<void> {
|
||||
this.connected = false;
|
||||
this.emit("close");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ export class WakuProvider extends BasicProvider implements IWakuProvider {
|
|||
if (!this.connected) {
|
||||
await this.open();
|
||||
}
|
||||
const result = await this.send(RPC_METHODS.NETWORK.waku_info);
|
||||
const result = await this.send(RPC_METHODS.NETWORK.waku_info, []);
|
||||
this.emit("enable");
|
||||
return result;
|
||||
} catch (err) {
|
||||
|
@ -22,6 +22,10 @@ export class WakuProvider extends BasicProvider implements IWakuProvider {
|
|||
}
|
||||
}
|
||||
|
||||
public async init(): Promise<any> {
|
||||
return this.enable();
|
||||
}
|
||||
|
||||
public async request(payload: JsonRpcRequest): Promise<any> {
|
||||
return this.send(payload.method, payload.params);
|
||||
}
|
||||
|
|
|
@ -22,21 +22,26 @@ import { isKeyPair, isSymKey } from "../helpers/validators";
|
|||
export class WakuSigner implements IWakuSigner {
|
||||
private keyMap: KeyMap = {};
|
||||
|
||||
constructor(private store: IWakuStore) {
|
||||
this.loadKeys();
|
||||
}
|
||||
constructor(private store: IWakuStore) {}
|
||||
|
||||
// -- public ----------------------------------------------- //
|
||||
|
||||
public async init(): Promise<any> {
|
||||
return await this.loadKeys();
|
||||
}
|
||||
|
||||
public async request(payload: JsonRpcRequest): Promise<any> {
|
||||
const method = payload.method.replace(WAKU_PREFIX + "_", "");
|
||||
return this[method](...payload.params);
|
||||
}
|
||||
|
||||
public async newKeyPair(): Promise<string> {
|
||||
await this.loadKeys();
|
||||
const key = this.genKeyPair();
|
||||
await this.addKey(key);
|
||||
return key.id;
|
||||
}
|
||||
|
||||
public async addPrivateKey(prvKey: string): Promise<string> {
|
||||
await this.loadKeys();
|
||||
let key = this.getMatchingKey("prvKey", prvKey);
|
||||
if (!key) {
|
||||
key = this.genKeyPair(prvKey);
|
||||
|
@ -46,19 +51,16 @@ export class WakuSigner implements IWakuSigner {
|
|||
}
|
||||
|
||||
public async deleteKeyPair(id: string): Promise<boolean> {
|
||||
await this.loadKeys();
|
||||
await this.removeKey(id);
|
||||
return true;
|
||||
}
|
||||
|
||||
public async hasKeyPair(id: string): Promise<boolean> {
|
||||
await this.loadKeys();
|
||||
let key = this.getMatchingKey("id", id);
|
||||
return isKeyPair(key);
|
||||
}
|
||||
|
||||
public async getPublicKey(id: string): Promise<string> {
|
||||
await this.loadKeys();
|
||||
let key = this.getMatchingKey("id", id);
|
||||
if (!key) {
|
||||
throw new Error(`No matching pubKey for id: ${id}`);
|
||||
|
@ -67,7 +69,6 @@ export class WakuSigner implements IWakuSigner {
|
|||
}
|
||||
|
||||
public async getPrivateKey(id: string): Promise<string> {
|
||||
await this.loadKeys();
|
||||
let key = this.getMatchingKey("id", id);
|
||||
if (!key) {
|
||||
throw new Error(`No matching privKey for id: ${id}`);
|
||||
|
@ -76,14 +77,12 @@ export class WakuSigner implements IWakuSigner {
|
|||
}
|
||||
|
||||
public async newSymKey(): Promise<string> {
|
||||
await this.loadKeys();
|
||||
const key = this.genSymKey();
|
||||
await this.addKey(key);
|
||||
return key.id;
|
||||
}
|
||||
|
||||
public async addSymKey(symKey: string): Promise<string> {
|
||||
await this.loadKeys();
|
||||
let key = this.getMatchingKey("symKey", symKey);
|
||||
if (!key) {
|
||||
key = {
|
||||
|
@ -96,7 +95,6 @@ export class WakuSigner implements IWakuSigner {
|
|||
}
|
||||
|
||||
public async generateSymKeyFromPassword(): Promise<string> {
|
||||
await this.loadKeys();
|
||||
// TODO: needs to accept optional "password" argument
|
||||
const key = this.genSymKey();
|
||||
await this.addKey(key);
|
||||
|
@ -104,13 +102,11 @@ export class WakuSigner implements IWakuSigner {
|
|||
}
|
||||
|
||||
public async hasSymKey(id: string): Promise<boolean> {
|
||||
await this.loadKeys();
|
||||
let key = this.getMatchingKey("id", id);
|
||||
return isSymKey(key);
|
||||
}
|
||||
|
||||
public async getSymKey(id: string): Promise<string> {
|
||||
await this.loadKeys();
|
||||
let key = this.getMatchingKey("id", id);
|
||||
if (!key) {
|
||||
throw new Error(`No matching symKey for id: ${id}`);
|
||||
|
@ -119,16 +115,10 @@ export class WakuSigner implements IWakuSigner {
|
|||
}
|
||||
|
||||
public async deleteSymKey(id: string): Promise<boolean> {
|
||||
await this.loadKeys();
|
||||
await this.removeKey(id);
|
||||
return true;
|
||||
}
|
||||
|
||||
public async request(payload: JsonRpcRequest): Promise<any> {
|
||||
const method = payload.method.replace(WAKU_PREFIX + "_", "");
|
||||
return this[method](...payload.params);
|
||||
}
|
||||
|
||||
// -- private ----------------------------------------------- //
|
||||
|
||||
private getMatchingKey(param: string, value: string): Key | undefined {
|
||||
|
@ -160,21 +150,21 @@ export class WakuSigner implements IWakuSigner {
|
|||
};
|
||||
}
|
||||
|
||||
private async loadKeys() {
|
||||
this.keyMap = await this.store.get(STORE_KEYS_ID);
|
||||
private async loadKeys(): Promise<void> {
|
||||
this.keyMap = (await this.store.get(STORE_KEYS_ID)) || {};
|
||||
}
|
||||
|
||||
private async addKey(key: Key) {
|
||||
private async addKey(key: Key): Promise<void> {
|
||||
this.keyMap[key.id] = key;
|
||||
await this.persistKeys();
|
||||
}
|
||||
|
||||
private async removeKey(id: string) {
|
||||
private async removeKey(id: string): Promise<void> {
|
||||
delete this.keyMap[id];
|
||||
await this.persistKeys();
|
||||
}
|
||||
|
||||
private async persistKeys() {
|
||||
private async persistKeys(): Promise<void> {
|
||||
await this.store.set(STORE_KEYS_ID, this.keyMap);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,28 +1,24 @@
|
|||
import storage from "localStorage";
|
||||
|
||||
import { safeJsonParse, safeJsonStringify } from "./json";
|
||||
import { getOrUndefined } from "./misc";
|
||||
|
||||
export function getLocalStorage(): Storage {
|
||||
return getOrUndefined<Storage>("localStorage", window) || storage;
|
||||
}
|
||||
|
||||
export function setLocal(key: string, data: any): void {
|
||||
const raw = safeJsonStringify(data);
|
||||
const local = getOrUndefined<Storage>("localStorage", window);
|
||||
if (local) {
|
||||
local.setItem(key, raw);
|
||||
}
|
||||
const local = getLocalStorage();
|
||||
local.setItem(key, safeJsonStringify(data));
|
||||
}
|
||||
|
||||
export function getLocal(key: string): any {
|
||||
let data: any = null;
|
||||
let raw: string | null = null;
|
||||
const local = getOrUndefined<Storage>("localStorage", window);
|
||||
if (local) {
|
||||
raw = local.getItem(key);
|
||||
}
|
||||
data = safeJsonParse(raw);
|
||||
const local = getLocalStorage();
|
||||
const data = safeJsonParse(local.getItem(key));
|
||||
return data;
|
||||
}
|
||||
|
||||
export function removeLocal(key: string): void {
|
||||
const local = getOrUndefined<Storage>("localStorage", window);
|
||||
if (local) {
|
||||
local.removeItem(key);
|
||||
}
|
||||
const local = getLocalStorage();
|
||||
local.removeItem(key);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
import BasicProvider from "basic-provider";
|
||||
|
||||
import { JsonRpcRequest } from "./rpc";
|
||||
|
||||
export interface IWakuController {
|
||||
init(): Promise<any>;
|
||||
request(payload: JsonRpcRequest): Promise<any>;
|
||||
}
|
||||
export interface IWakuProvider extends BasicProvider, IWakuController {
|
||||
isWakuProvider: boolean;
|
||||
enable(): Promise<any>;
|
||||
}
|
||||
|
||||
export interface IWakuSigner extends IWakuController {
|
||||
newKeyPair(): Promise<string>;
|
||||
addPrivateKey(prvKey: string): Promise<string>;
|
||||
deleteKeyPair(id: string): Promise<boolean>;
|
||||
hasKeyPair(id: string): Promise<boolean>;
|
||||
getPublicKey(id: string): Promise<string>;
|
||||
getPrivateKey(id: string): Promise<string>;
|
||||
newSymKey(): Promise<string>;
|
||||
addSymKey(symKey: string): Promise<string>;
|
||||
generateSymKeyFromPassword(): Promise<string>;
|
||||
hasSymKey(id: string): Promise<boolean>;
|
||||
getSymKey(id: string): Promise<string>;
|
||||
deleteSymKey(id: string): Promise<boolean>;
|
||||
}
|
||||
|
||||
export interface IWakuStore {
|
||||
set(key: string, data: any): Promise<void>;
|
||||
get(key: string): Promise<any>;
|
||||
remove(key: string): Promise<void>;
|
||||
}
|
||||
|
||||
export interface IWakuClient extends IWakuController {
|
||||
provider: IWakuProvider;
|
||||
store: IWakuStore;
|
||||
signer: IWakuSigner;
|
||||
}
|
|
@ -1,64 +1,3 @@
|
|||
import BasicProvider from "basic-provider";
|
||||
|
||||
// -- interfaces ----------------------------------------------- //
|
||||
|
||||
export interface IWakuController {
|
||||
request(payload: JsonRpcRequest): Promise<any>;
|
||||
}
|
||||
export interface IWakuProvider extends BasicProvider, IWakuController {
|
||||
isWakuProvider: boolean;
|
||||
enable(): Promise<any>;
|
||||
}
|
||||
|
||||
export interface IWakuSigner extends IWakuController {
|
||||
newKeyPair(): Promise<string>;
|
||||
addPrivateKey(prvKey: string): Promise<string>;
|
||||
deleteKeyPair(id: string): Promise<boolean>;
|
||||
hasKeyPair(id: string): Promise<boolean>;
|
||||
getPublicKey(id: string): Promise<string>;
|
||||
getPrivateKey(id: string): Promise<string>;
|
||||
newSymKey(): Promise<string>;
|
||||
addSymKey(symKey: string): Promise<string>;
|
||||
generateSymKeyFromPassword(): Promise<string>;
|
||||
hasSymKey(id: string): Promise<boolean>;
|
||||
getSymKey(id: string): Promise<string>;
|
||||
deleteSymKey(id: string): Promise<boolean>;
|
||||
}
|
||||
|
||||
export interface IWakuStore {
|
||||
set(key: string, data: any): Promise<void>;
|
||||
get(key: string): Promise<any>;
|
||||
remove(key: string): Promise<void>;
|
||||
}
|
||||
|
||||
export interface IWakuClient extends IWakuController {
|
||||
provider: IWakuProvider;
|
||||
store: IWakuStore;
|
||||
signer: IWakuSigner;
|
||||
}
|
||||
|
||||
// -- types ----------------------------------------------- //
|
||||
|
||||
export type SymKey = {
|
||||
id: string;
|
||||
symKey: string;
|
||||
};
|
||||
|
||||
export type KeyPair = {
|
||||
id: string;
|
||||
pubKey: string;
|
||||
prvKey: string;
|
||||
};
|
||||
|
||||
export type Key = SymKey | KeyPair;
|
||||
|
||||
export type KeyMap = {
|
||||
[id: string]: Key;
|
||||
};
|
||||
|
||||
export type JsonRpcRequest = {
|
||||
id: number;
|
||||
jsonrpc: "2.0";
|
||||
method: string;
|
||||
params: any;
|
||||
};
|
||||
export * from "./controllers";
|
||||
export * from "./keys";
|
||||
export * from "./rpc";
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
export type SymKey = {
|
||||
id: string;
|
||||
symKey: string;
|
||||
};
|
||||
|
||||
export type KeyPair = {
|
||||
id: string;
|
||||
pubKey: string;
|
||||
prvKey: string;
|
||||
};
|
||||
|
||||
export type Key = SymKey | KeyPair;
|
||||
|
||||
export type KeyMap = {
|
||||
[id: string]: Key;
|
||||
};
|
|
@ -0,0 +1,12 @@
|
|||
export interface IWakuInfoResponse {
|
||||
messages: number;
|
||||
minPow: number;
|
||||
maxMessageSize: number;
|
||||
}
|
||||
|
||||
export type JsonRpcRequest = {
|
||||
id: number;
|
||||
jsonrpc: "2.0";
|
||||
method: string;
|
||||
params: any;
|
||||
};
|
|
@ -1,8 +1,60 @@
|
|||
import Waku from "../src";
|
||||
import Waku, { IWakuInfoResponse } from "../src";
|
||||
|
||||
describe("Waku", () => {
|
||||
it("needs tests", async () => {
|
||||
const waku = new Waku("http://localhost:8545");
|
||||
let waku: Waku;
|
||||
let info: IWakuInfoResponse;
|
||||
let keyPairId: string;
|
||||
|
||||
beforeEach(async () => {
|
||||
waku = new Waku("https://waku.walletconnect.org");
|
||||
info = await waku.init();
|
||||
});
|
||||
|
||||
it("should instantiate", async () => {
|
||||
expect(waku).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should init controllers", async () => {
|
||||
expect(info).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should create new key pair", async () => {
|
||||
keyPairId = await waku.request({
|
||||
id: 1,
|
||||
jsonrpc: "2.0",
|
||||
method: "waku_newKeyPair",
|
||||
params: [],
|
||||
});
|
||||
expect(keyPairId).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should check key pair", async () => {
|
||||
const check = await waku.request({
|
||||
id: 1,
|
||||
jsonrpc: "2.0",
|
||||
method: "waku_hasKeyPair",
|
||||
params: [keyPairId],
|
||||
});
|
||||
expect(check).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should get public key", async () => {
|
||||
const pubKey = await waku.request({
|
||||
id: 1,
|
||||
jsonrpc: "2.0",
|
||||
method: "waku_getPublicKey",
|
||||
params: [keyPairId],
|
||||
});
|
||||
expect(pubKey).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should get private key", async () => {
|
||||
const prvKey = await waku.request({
|
||||
id: 1,
|
||||
jsonrpc: "2.0",
|
||||
method: "waku_getPrivateKey",
|
||||
params: [keyPairId],
|
||||
});
|
||||
expect(prvKey).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
26
yarn.lock
26
yarn.lock
|
@ -1638,6 +1638,13 @@ aws4@^1.8.0:
|
|||
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e"
|
||||
integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==
|
||||
|
||||
axios@^0.19.2:
|
||||
version "0.19.2"
|
||||
resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27"
|
||||
integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==
|
||||
dependencies:
|
||||
follow-redirects "1.5.10"
|
||||
|
||||
axobject-query@^2.0.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.1.2.tgz#2bdffc0371e643e5f03ba99065d5179b9ca79799"
|
||||
|
@ -2523,6 +2530,13 @@ data-urls@^1.0.0:
|
|||
whatwg-mimetype "^2.2.0"
|
||||
whatwg-url "^7.0.0"
|
||||
|
||||
debug@=3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
|
||||
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9:
|
||||
version "2.6.9"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
||||
|
@ -3351,6 +3365,13 @@ flush-write-stream@^1.0.0:
|
|||
inherits "^2.0.3"
|
||||
readable-stream "^2.3.6"
|
||||
|
||||
follow-redirects@1.5.10:
|
||||
version "1.5.10"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a"
|
||||
integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==
|
||||
dependencies:
|
||||
debug "=3.1.0"
|
||||
|
||||
for-in@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
|
||||
|
@ -4750,6 +4771,11 @@ loader-utils@^1.2.3:
|
|||
emojis-list "^3.0.0"
|
||||
json5 "^1.0.1"
|
||||
|
||||
localStorage@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/localStorage/-/localStorage-1.0.4.tgz#57dfa28084385f81431accb8ae24b196398223f7"
|
||||
integrity sha512-r35zrihcDiX+dqWlJSeIwS9nrF95OQTgqMFm3FB2D/+XgdmZtcutZOb7t0xXkhOEM8a9kpuu7cc28g1g36I5DQ==
|
||||
|
||||
locate-path@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e"
|
||||
|
|
Loading…
Reference in New Issue