Skip to content

Commit 305bf0f

Browse files
committed
Initial commit'
1 parent 584081f commit 305bf0f

File tree

6 files changed

+4736
-0
lines changed

6 files changed

+4736
-0
lines changed

example.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
var KeyboxJS=require('./index');
2+
let keybox=new KeyboxJS();
3+
4+
5+
console.log(keybox.connect());
6+
keybox.sendMessage('EccGetPublicKeyRequest',{ Hdpath: "bip32/m/48'/1'/1'/1'/2" }).then(res=> {
7+
8+
console.log(res.getPubkey_asU8());
9+
10+
});
11+

index.js

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
var usb = require('usb');
2+
var messages = require('./lib/messages_pb');
3+
const MessageTypes =require('./lib/messagetypes');
4+
5+
class KeyboxJS {
6+
7+
constructor() {
8+
this.vid = 46763;
9+
this.pid = 47851;
10+
this.connected = false;
11+
}
12+
connect() {
13+
this.device = usb.findByIds(this.vid, this.pid);
14+
if (this.device == null) {
15+
return false;
16+
} else {
17+
this.device.open();
18+
this.iface = this.device.interface(0);
19+
this.iface.claim();
20+
this.tx = this.iface.endpoint(2);
21+
this.rx = this.iface.endpoint(129);
22+
this.connected = true;
23+
return true;
24+
}
25+
}
26+
reset() {
27+
let buffer = Buffer.alloc(1024);
28+
buffer.writeUInt8(0x5, 0);
29+
return new Promise((resolve, reject) => {
30+
this.tx.transfer(buffer, function (data) {
31+
this.rx.transfer(1024, function (error, data) {
32+
if (error) {
33+
throw error;
34+
}
35+
if (data.readUInt8(0) == 0x4) {
36+
resolve();
37+
} else {
38+
reject();
39+
}
40+
});
41+
});
42+
});
43+
}
44+
async sendMessage(messageType,props) {
45+
let self=this;
46+
let requestType=this.messageFromName(messageType);
47+
48+
let msg =new messages[requestType.name]();
49+
for(let prop in props) {
50+
msg['set'+prop](props[prop]);
51+
}
52+
let bytes = msg.serializeBinary();
53+
let buffer = Buffer.alloc(1024);
54+
if (bytes.length <= 1015) {
55+
let msglength=bytes.length;
56+
buffer.writeUInt8(0x1, 0);
57+
buffer.writeUInt32BE(requestType.id, 1);
58+
buffer.writeUInt32BE(msglength, 5);
59+
Buffer.from(bytes).copy(buffer,9);
60+
await this._sendSingleMessage(buffer);
61+
}else{
62+
throw new Error('Long messages (>1015) not implemented yet');
63+
}
64+
try {
65+
let data= await this._receive(1024);
66+
let response;
67+
if (data.readUInt8(0) == 1) {
68+
response=this._receiveSingleMessage(data);
69+
}else{
70+
if (data.readUInt8(0) == 2) {
71+
response=this._receiveMultiMessage(data);
72+
}else{
73+
this.reset();
74+
throw new Error('Unexpected response');
75+
}
76+
}
77+
return response;
78+
}catch(e) {
79+
this.reset();
80+
throw new Error(e);
81+
}
82+
}
83+
_sendSingleMessage(buffer) {
84+
return this._send(buffer);
85+
}
86+
_receiveSingleMessage(data) {
87+
let msgType=this.messageFromType(data.readUInt32BE(1));
88+
89+
let msgLength=data.readUInt32BE(5);
90+
91+
let message=data.slice(9,msgLength+9);
92+
93+
94+
let msgObject=messages[msgType.name].deserializeBinary(message);
95+
return(msgObject);
96+
}
97+
_sendMultiMessage() {
98+
99+
}
100+
_send(bytes) {
101+
return new Promise((resolve,reject) => {
102+
this.tx.transfer(bytes,resolve)
103+
});
104+
}
105+
_receive(size) {
106+
return new Promise((resolve,reject) => {
107+
this.rx.transfer(size,function(error,data) {
108+
if (error) {
109+
reject(error);
110+
}else{
111+
resolve(data);
112+
}
113+
});
114+
});
115+
}
116+
async _receiveMultiMessage(data) {
117+
let msgType=this.messageFromType(data.readUInt32BE(1));
118+
let msgLength=data.readUInt32BE(5);
119+
let message=data.slice(9);
120+
let count=0;
121+
while(message.length<msgLength) {
122+
await this._sendAck(1015+count*1019);
123+
let _part=await this._receive(1024);
124+
let _msgpart;
125+
if (_part.readUInt8(0)==0x3) {
126+
if ((message.length+1019)>msgLength) {
127+
_msgpart=_part.slice(5);
128+
}else{
129+
_msgpart=_part.slice(5,5+(msgLength-(1015+count*1019)));
130+
}
131+
}else{
132+
throw new Error('Unexpected rx code');
133+
}
134+
message=Buffer.concat([message,_msgpart]);
135+
count++;
136+
}
137+
let msgObject=messages[msgType.name].deserializeBinary(message).toObject()
138+
return message;
139+
140+
}
141+
_sendAck(offset) {
142+
return new Promise((resolve,reject)=> {
143+
let buffer = Buffer.alloc(1024);
144+
buffer.writeUInt8(0x4, 0);
145+
buffer.writeUInt32BE(offset, 1);
146+
this.tx.transfer(buffer, resolve);
147+
});
148+
}
149+
messageFromType(msgtype) {
150+
for(let type in MessageTypes) {
151+
if (MessageTypes[type].id==msgtype) {
152+
return MessageTypes[type];
153+
}
154+
}
155+
}
156+
messageFromName(msgtype) {
157+
for(let type in MessageTypes) {
158+
if (MessageTypes[type].name==msgtype) {
159+
return MessageTypes[type];
160+
}
161+
}
162+
}
163+
}
164+
module.exports=KeyboxJS;

0 commit comments

Comments
 (0)