Skip to content

Commit 57d84ec

Browse files
Joonmo YangJoonmo Yang
authored andcommitted
Implement routes with db backend
1 parent 5d34206 commit 57d84ec

File tree

4 files changed

+267
-59
lines changed

4 files changed

+267
-59
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
},
1515
"dependencies": {
1616
"@types/config": "^0.0.34",
17-
"codechain-keystore": "~0.4.0",
17+
"codechain-keystore": "^0.6.1",
18+
"codechain-primitives": "^1.0.1",
1819
"config": "^3.1.0",
1920
"debug": "~2.6.9",
2021
"express": "~4.16.0",

src/models/key.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { SecretStorage } from "codechain-keystore";
12
import { Model, snakeCaseMappers } from "objection";
23

34
export default class KeyModel extends Model {
@@ -18,4 +19,21 @@ export default class KeyModel extends Model {
1819
public readonly ciphertext!: string;
1920

2021
public readonly meta!: any;
22+
23+
public toJSON(): SecretStorage {
24+
return {
25+
crypto: {
26+
ciphertext: this.ciphertext,
27+
cipherparams: this.cipherparams,
28+
cipher: this.cipher,
29+
kdf: this.kdf,
30+
kdfparams: this.kdfparams,
31+
mac: this.mac
32+
},
33+
id: this.address,
34+
version: this.version,
35+
address: this.address,
36+
meta: this.meta
37+
};
38+
}
2139
}

src/routes/api.ts

Lines changed: 148 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,194 @@
1+
import * as storage from "codechain-keystore/lib/logic/storage";
2+
import { KeyType as KeyTypeId } from "codechain-keystore/lib/model/keytypes";
3+
import {
4+
generatePrivateKey,
5+
getAccountIdFromPublic,
6+
getPublicFromPrivate,
7+
signEcdsa
8+
} from "codechain-primitives";
19
import * as express from "express";
210
import { Context } from "../context";
11+
import KeyModel from "../models/key";
312

413
type KeyType = "asset" | "platform";
514

15+
function findKey(
16+
type: KeyType,
17+
address: string
18+
): Promise<KeyModel | undefined> {
19+
return KeyModel.query().findById([type, address]) as any;
20+
}
21+
622
export function createRouter(context: Context) {
723
const router = express.Router();
824

925
router.get("/keys", async (req, res) => {
1026
const keyType: KeyType = req.body.keyType;
11-
const keys = await context.cckey[keyType].getKeys();
12-
1327
res.json({
1428
success: true,
15-
result: keys
29+
result: await KeyModel.query().where({ type: keyType })
1630
});
1731
});
1832

1933
router.get("/keys/:key/publicKey", async (req, res) => {
2034
const { key } = req.params;
2135
const keyType: KeyType = req.body.keyType;
22-
const publicKey = await context.cckey[keyType].getPublicKey({ key });
23-
24-
res.json({
25-
success: true,
26-
result: publicKey
27-
});
28-
});
2936

30-
router.get("/keys/:key/rawKey", async (req, res) => {
31-
try {
32-
const { key } = req.params;
33-
const { passphrase } = req.body;
34-
const keyType: KeyType = req.body.keyType;
35-
const rawKey = await context.cckey[keyType].exportRawKey({
36-
key,
37-
passphrase
37+
const row = await findKey(keyType, key);
38+
if (row == null) {
39+
res.json({
40+
success: false,
41+
error: "Not found"
3842
});
39-
43+
} else {
44+
const priv = await storage.decode(row.toJSON(), "");
45+
const pub = getPublicFromPrivate(priv);
4046
res.json({
4147
success: true,
42-
result: rawKey
48+
result: pub
4349
});
44-
} catch (e) {
50+
}
51+
});
52+
53+
router.get("/keys/:key/rawKey", async (req, res) => {
54+
const { key } = req.params;
55+
const { passphrase } = req.body;
56+
const keyType: KeyType = req.body.keyType;
57+
58+
const row = await findKey(keyType, key);
59+
if (row == null) {
4560
res.json({
4661
success: false,
47-
error: e
62+
error: "Not found"
4863
});
64+
} else {
65+
try {
66+
const priv = await storage.decode(row.toJSON(), passphrase);
67+
res.json({
68+
success: true,
69+
result: priv
70+
});
71+
} catch (e) {
72+
res.json({
73+
success: false,
74+
error: "Invalid passphrase"
75+
});
76+
}
4977
}
5078
});
5179

5280
router.post("/keys", async (req, res) => {
5381
const { passphrase } = req.body;
5482
const keyType: KeyType = req.body.keyType;
55-
const key = await context.cckey[keyType].createKey({
56-
passphrase
57-
});
58-
res.json({
59-
success: true,
60-
result: key
61-
});
83+
84+
while (true) {
85+
const priv = generatePrivateKey();
86+
const pub = getPublicFromPrivate(priv);
87+
const address = getAccountIdFromPublic(pub);
88+
89+
// Check duplication
90+
if ((await findKey(keyType, address)) != null) {
91+
continue;
92+
}
93+
94+
let typeId: KeyTypeId | undefined;
95+
switch (keyType) {
96+
case "asset": {
97+
typeId = KeyTypeId.Asset;
98+
break;
99+
}
100+
case "platform": {
101+
typeId = KeyTypeId.Platform;
102+
break;
103+
}
104+
}
105+
106+
const secret = await storage.encode(
107+
priv,
108+
typeId!,
109+
passphrase,
110+
JSON.stringify({})
111+
);
112+
await KeyModel.query().insert({
113+
type: keyType,
114+
address: secret.address,
115+
version: secret.version,
116+
117+
kdf: secret.crypto.kdf,
118+
kdfparams: secret.crypto.kdfparams,
119+
mac: secret.crypto.mac,
120+
121+
cipher: secret.crypto.cipher,
122+
cipherparams: secret.crypto.cipherparams,
123+
ciphertext: secret.crypto.ciphertext,
124+
125+
meta: secret.meta
126+
});
127+
128+
res.json({
129+
success: true,
130+
result: secret.address
131+
});
132+
return;
133+
}
62134
});
63135

64136
router.delete("/keys/:key", async (req, res) => {
65137
const { key } = req.params;
66138
const keyType: KeyType = req.body.keyType;
67-
const result = await context.cckey[keyType].deleteKey({
68-
key
69-
});
70-
res.json({
71-
success: true,
72-
result
73-
});
74-
});
75139

76-
router.post("/keys/:key/sign", async (req, res) => {
77-
try {
78-
const { key } = req.params;
79-
const { message, passphrase = "" } = req.body;
80-
const keyType: KeyType = req.body.keyType;
81-
const result = await context.cckey[keyType].sign({
82-
key,
83-
passphrase,
84-
message
85-
});
140+
const row = await findKey(keyType, key);
141+
142+
if (row == null) {
86143
res.json({
87-
success: true,
88-
result
144+
success: false,
145+
error: "Not found"
89146
});
90-
} catch (e) {
147+
} else {
148+
try {
149+
// Check if the passphrase is correct
150+
await storage.decode(row.toJSON(), "");
151+
await KeyModel.query()
152+
.del()
153+
.findById([keyType, key]);
154+
res.json({
155+
success: true,
156+
result: true
157+
});
158+
} catch (e) {
159+
res.json({
160+
success: true,
161+
result: false
162+
});
163+
}
164+
}
165+
});
166+
167+
router.post("/keys/:key/sign", async (req, res) => {
168+
const { key } = req.params;
169+
const { message, passphrase = "" } = req.body;
170+
const keyType: KeyType = req.body.keyType;
171+
172+
const row = await findKey(keyType, key);
173+
174+
if (row == null) {
91175
res.json({
92176
success: false,
93-
error: e
177+
error: "Not found"
94178
});
179+
} else {
180+
try {
181+
const priv = await storage.decode(row.toJSON(), passphrase);
182+
res.json({
183+
success: true,
184+
result: signEcdsa(message, priv)
185+
});
186+
} catch (e) {
187+
res.json({
188+
success: false,
189+
error: e
190+
});
191+
}
95192
}
96193
});
97194

0 commit comments

Comments
 (0)