Skip to content

Commit 007384f

Browse files
committed
improving backwards compatibility support
1 parent 824116c commit 007384f

File tree

5 files changed

+83
-18
lines changed

5 files changed

+83
-18
lines changed

src/common.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export const APP_KEY = "CSM";
44

55
export const INS = {
66
GET_VERSION: 0x00,
7+
INS_PUBLIC_KEY_SECP256K1: 0x01, // Obsolete
78
SIGN_SECP256K1: 0x02,
89
GET_ADDR_SECP256K1: 0x04,
910
};

src/helperV1.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,28 @@ export async function signSendChunkv1(app, chunkIdx, chunkNum, chunk) {
4444
};
4545
}, processErrorResponse);
4646
}
47+
48+
function compressPublicKey(publicKey) {
49+
if (publicKey.length !== 65) {
50+
throw new Error("decompressed public key length should be 65 bytes");
51+
}
52+
const y = publicKey.slice(33, 65);
53+
// eslint-disable-next-line no-bitwise
54+
const z = Buffer.from([2 + (y[y.length - 1] & 1)]);
55+
return Buffer.concat([z, publicKey.slice(1, 33)]);
56+
}
57+
58+
export async function publicKeyv1(app, data) {
59+
return app.transport.send(CLA, INS.INS_PUBLIC_KEY_SECP256K1, 0, 0, data, [0x9000]).then(response => {
60+
const errorCodeData = response.slice(-2);
61+
const returnCode = errorCodeData[0] * 256 + errorCodeData[1];
62+
const pk = Buffer.from(response.slice(0, 65));
63+
64+
return {
65+
pk,
66+
compressed_pk: compressPublicKey(pk),
67+
return_code: returnCode,
68+
error_message: errorCodeToString(returnCode),
69+
};
70+
}, processErrorResponse);
71+
}

src/helperV2.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { signSendChunkv1 } from "./helperV1";
2-
import { PAYLOAD_TYPE } from "./common";
2+
import { CLA, errorCodeToString, INS, PAYLOAD_TYPE, processErrorResponse } from "./common";
33

44
export function serializePathv2(path) {
55
if (!path || path.length !== 5) {
@@ -27,3 +27,18 @@ export async function signSendChunkv2(app, chunkIdx, chunkNum, chunk) {
2727

2828
return signSendChunkv1(app, payloadType, 0, chunk);
2929
}
30+
31+
export async function publicKeyv2(app, data) {
32+
return this.transport.send(CLA, INS.GET_ADDR_SECP256K1, 0, 0, data, [0x9000]).then(response => {
33+
const errorCodeData = response.slice(-2);
34+
const returnCode = errorCodeData[0] * 256 + errorCodeData[1];
35+
const compressedPk = Buffer.from(response.slice(0, 33));
36+
37+
return {
38+
pk: "OBSOLETE PROPERTY",
39+
compressed_pk: compressedPk,
40+
return_code: returnCode,
41+
error_message: errorCodeToString(returnCode),
42+
};
43+
}, processErrorResponse);
44+
}

src/index.js

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
import crypto from "crypto";
1919
import Ripemd160 from "ripemd160";
2020
import bech32 from "bech32";
21-
import { serializePathv1, signSendChunkv1 } from "./helperV1";
22-
import { serializePathv2, signSendChunkv2 } from "./helperV2";
21+
import { publicKeyv1, serializePathv1, signSendChunkv1 } from "./helperV1";
22+
import { publicKeyv2, serializePathv2, signSendChunkv2 } from "./helperV2";
2323
import { APP_KEY, CHUNK_SIZE, CLA, INS, errorCodeToString, getVersion, processErrorResponse } from "./common";
2424

2525
export default class CosmosApp {
@@ -194,19 +194,20 @@ export default class CosmosApp {
194194

195195
async publicKey(path) {
196196
const serializedPath = await this.serializePath(path);
197-
const data = Buffer.concat([CosmosApp.serializeHRP("cosmos"), serializedPath]);
198-
return this.transport.send(CLA, INS.GET_ADDR_SECP256K1, 0, 0, data, [0x9000]).then(response => {
199-
const errorCodeData = response.slice(-2);
200-
const returnCode = errorCodeData[0] * 256 + errorCodeData[1];
201-
const compressedPk = Buffer.from(response.slice(0, 33));
202197

203-
return {
204-
pk: "OBSOLETE PROPERTY",
205-
compressed_pk: compressedPk,
206-
return_code: returnCode,
207-
error_message: errorCodeToString(returnCode),
208-
};
209-
}, processErrorResponse);
198+
switch (this.versionResponse.major) {
199+
case 1:
200+
return publicKeyv1(this, serializedPath);
201+
case 2: {
202+
const data = Buffer.concat([CosmosApp.serializeHRP("cosmos"), serializedPath]);
203+
return publicKeyv2(this, data);
204+
}
205+
default:
206+
return {
207+
return_code: 0x6400,
208+
error_message: "App Version is not supported",
209+
};
210+
}
210211
}
211212

212213
async getAddressAndPubKey(path, hrp) {

tests/basic.ispec.js

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,19 @@ test("sign_big_tx", async () => {
218218
expect(responsePk.return_code).toEqual(0x9000);
219219
expect(responsePk.error_message).toEqual("No errors");
220220
expect(responseSign.return_code).toEqual(0x6a80);
221-
expect(responseSign.error_message).toEqual("NOMEM: JSON string contains too many tokens");
221+
222+
switch (app.versionResponse.major) {
223+
case 1:
224+
expect(responseSign.error_message).toEqual(
225+
"Bad key handle : NOMEM: JSON string contains too many tokens",
226+
);
227+
break;
228+
case 2:
229+
expect(responseSign.error_message).toEqual("NOMEM: JSON string contains too many tokens");
230+
break;
231+
default:
232+
expect.fail("Version not supported");
233+
}
222234
});
223235

224236
test("sign_invalid", async () => {
@@ -234,6 +246,17 @@ test("sign_invalid", async () => {
234246
const responseSign = await app.sign(path, invalidMessage);
235247

236248
console.log(responseSign);
237-
expect(responseSign.return_code).toEqual(0x6984);
238-
expect(responseSign.error_message).toEqual("Data is invalid : JSON Missing account number");
249+
250+
switch (app.versionResponse.major) {
251+
case 1:
252+
expect(responseSign.return_code).toEqual(0x6a80);
253+
expect(responseSign.error_message).toEqual("Bad key handle : JSON Missing account_number");
254+
break;
255+
case 2:
256+
expect(responseSign.return_code).toEqual(0x6984);
257+
expect(responseSign.error_message).toEqual("Data is invalid : JSON Missing account number");
258+
break;
259+
default:
260+
expect.fail("Version not supported");
261+
}
239262
});

0 commit comments

Comments
 (0)