@ledgerhq/hw-app-exchange 0.7.0 → 0.8.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +6 -0
- package/lib/Exchange.d.ts +1 -0
- package/lib/Exchange.d.ts.map +1 -1
- package/lib/Exchange.integ.test.js +175 -196
- package/lib/Exchange.integ.test.js.map +1 -1
- package/lib/Exchange.js +132 -162
- package/lib/Exchange.js.map +1 -1
- package/lib/Exchange.test.js +49 -58
- package/lib/Exchange.test.js.map +1 -1
- package/lib/ReturnCode.js +2 -2
- package/lib/ReturnCode.js.map +1 -1
- package/lib/SellUtils.js +14 -24
- package/lib/SellUtils.js.map +1 -1
- package/lib/SellUtils.test.js +6 -15
- package/lib/SellUtils.test.js.map +1 -1
- package/lib/SwapUtils.js +18 -30
- package/lib/SwapUtils.js.map +1 -1
- package/lib/SwapUtils.test.js +6 -15
- package/lib/SwapUtils.test.js.map +1 -1
- package/lib-es/Exchange.d.ts +1 -0
- package/lib-es/Exchange.d.ts.map +1 -1
- package/lib-es/Exchange.integ.test.js +175 -196
- package/lib-es/Exchange.integ.test.js.map +1 -1
- package/lib-es/Exchange.js +132 -162
- package/lib-es/Exchange.js.map +1 -1
- package/lib-es/Exchange.test.js +49 -58
- package/lib-es/Exchange.test.js.map +1 -1
- package/lib-es/ReturnCode.js +2 -2
- package/lib-es/ReturnCode.js.map +1 -1
- package/lib-es/SellUtils.js +14 -24
- package/lib-es/SellUtils.js.map +1 -1
- package/lib-es/SellUtils.test.js +6 -15
- package/lib-es/SellUtils.test.js.map +1 -1
- package/lib-es/SwapUtils.js +18 -30
- package/lib-es/SwapUtils.js.map +1 -1
- package/lib-es/SwapUtils.test.js +6 -15
- package/lib-es/SwapUtils.test.js.map +1 -1
- package/package.json +4 -4
- package/src/ReturnCode.ts +2 -2
package/.turbo/turbo-build.log
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @ledgerhq/hw-app-exchange
|
|
2
2
|
|
|
3
|
+
## 0.8.0-next.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#9223](https://github.com/LedgerHQ/ledger-live/pull/9223) [`42948ff`](https://github.com/LedgerHQ/ledger-live/commit/42948fffa9b435ea2f5f2c7bc9ef66071eadce4b) Thanks [@CremaFR](https://github.com/CremaFR)! - update error message for clarity
|
|
8
|
+
|
|
3
9
|
## 0.7.0
|
|
4
10
|
|
|
5
11
|
### Minor Changes
|
package/lib/Exchange.d.ts
CHANGED
package/lib/Exchange.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Exchange.d.ts","sourceRoot":"","sources":["../src/Exchange.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Exchange.d.ts","sourceRoot":"","sources":["../src/Exchange.ts"],"names":[],"mappings":";;AAAA,OAAO,SAAS,MAAM,wBAAwB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAMzC,0BAAkB,SAAS;IACzB,KAAK,IAAO;IACZ,QAAQ,IAAO;CAChB;AAED,0BAAkB,aAAa;IAC7B,IAAI,IAAO;IACX,IAAI,IAAO;IACX,IAAI,IAAO;IACX,MAAM,IAAO;IACb,MAAM,IAAO;IACb,MAAM,IAAO;CACd;AAGD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAE7D;AA+BD,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,uBAAuB,CAAC,EAAE,8BAA8B,CAAC;CAC1D,CAAC;AAKF,MAAM,MAAM,8BAA8B,GAAG,KAAK,GAAG,KAAK,CAAC;AA+B3D,wBAAgB,cAAc,CAC5B,SAAS,EAAE,SAAS,EACpB,eAAe,EAAE,aAAa,EAC9B,eAAe,CAAC,EAAE,SAAS,EAC3B,OAAO,CAAC,EAAE,MAAM,GACf,QAAQ,CAEV;AAED,MAAM,CAAC,OAAO,OAAO,QAAQ;IAC3B,SAAS,EAAE,SAAS,CAAC;IACrB,eAAe,EAAE,aAAa,CAAC;IAC/B,eAAe,EAAE,SAAS,CAAC;IAC3B,eAAe,EAAE,KAAK,CAAC,MAAM,CAAC,CAA6C;gBAE/D,SAAS,EAAE,SAAS,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,CAAC,EAAE,SAAS;IAMvF,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC;IAwBtC,aAAa,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAalD,YAAY,CAAC,sBAAsB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAY3D,kBAAkB,CACtB,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,SAAS,EACd,UAAU,CAAC,EAAE,8BAA8B,GAC1C,OAAO,CAAC,IAAI,CAAC;IAgDhB;;;OAGG;YACW,uBAAuB;IAwB/B,yBAAyB,CAAC,oBAAoB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBtE,qBAAqB,CACzB,oBAAoB,EAAE,MAAM,EAC5B,uBAAuB,EAAE,MAAM,EAC/B,iBAAiB,EAAE,MAAM,GACxB,OAAO,CAAC,IAAI,CAAC;IA2BV,kBAAkB,CACtB,oBAAoB,EAAE,MAAM,EAC5B,uBAAuB,EAAE,MAAM,EAC/B,iBAAiB,EAAE,MAAM,GACxB,OAAO,CAAC,IAAI,CAAC;IAyBV,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAYpC,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAa/B,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBxE,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAY1D,OAAO,CAAC,iBAAiB;IAazB,OAAO,CAAC,gBAAgB;CAGzB"}
|
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
@@ -21,27 +12,27 @@ const protobufjs_1 = __importDefault(require("protobufjs"));
|
|
|
21
12
|
const bignumber_js_1 = __importDefault(require("bignumber.js"));
|
|
22
13
|
describe("Check Exchange until payload signature", () => {
|
|
23
14
|
let transport;
|
|
24
|
-
beforeAll(() =>
|
|
25
|
-
transport =
|
|
26
|
-
})
|
|
27
|
-
afterAll(() =>
|
|
15
|
+
beforeAll(async () => {
|
|
16
|
+
transport = await hw_transport_node_speculos_http_1.default.open({});
|
|
17
|
+
});
|
|
18
|
+
afterAll(async () => {
|
|
28
19
|
transport.close();
|
|
29
|
-
})
|
|
20
|
+
});
|
|
30
21
|
describe("Check SWAP", () => {
|
|
31
|
-
it("Legacy SWAP", () =>
|
|
22
|
+
it("Legacy SWAP", async () => {
|
|
32
23
|
// Given
|
|
33
24
|
const exchange = new Exchange_1.default(transport, 0 /* ExchangeTypes.Swap */);
|
|
34
25
|
// When
|
|
35
|
-
const transactionId =
|
|
26
|
+
const transactionId = await exchange.startNewTransaction();
|
|
36
27
|
// Then
|
|
37
28
|
expect(transactionId).toEqual(expect.any(String));
|
|
38
29
|
expect(transactionId).toHaveLength(10);
|
|
39
|
-
const { partnerInfo, partnerSigned, partnerPrivKey } =
|
|
40
|
-
|
|
41
|
-
|
|
30
|
+
const { partnerInfo, partnerSigned, partnerPrivKey } = await appExchangeDatasetTest(legacySignFormat);
|
|
31
|
+
await exchange.setPartnerKey(partnerInfo);
|
|
32
|
+
await exchange.checkPartner(partnerSigned);
|
|
42
33
|
const amount = new bignumber_js_1.default(100000);
|
|
43
34
|
const amountToWallet = new bignumber_js_1.default(1000);
|
|
44
|
-
const encodedPayload =
|
|
35
|
+
const encodedPayload = await generateSwapPayloadProtobuf({
|
|
45
36
|
payinAddress: "0xd692Cb1346262F584D17B4B470954501f6715a82",
|
|
46
37
|
refundAddress: "0xDad77910DbDFdE764fC21FCD4E74D71bBACA6D8D",
|
|
47
38
|
payoutAddress: "bc1qer57ma0fzhqys2cmydhuj9cprf9eg0nw922a8j",
|
|
@@ -52,24 +43,24 @@ describe("Check Exchange until payload signature", () => {
|
|
|
52
43
|
deviceTransactionId: transactionId,
|
|
53
44
|
});
|
|
54
45
|
const estimatedFees = new bignumber_js_1.default(0);
|
|
55
|
-
|
|
56
|
-
const payloadSignature =
|
|
57
|
-
|
|
58
|
-
})
|
|
59
|
-
it("NG SWAP", () =>
|
|
46
|
+
await exchange.processTransaction(encodedPayload, estimatedFees);
|
|
47
|
+
const payloadSignature = await signMessage(encodedPayload, partnerPrivKey, "der");
|
|
48
|
+
await exchange.checkTransactionSignature(payloadSignature);
|
|
49
|
+
});
|
|
50
|
+
it("NG SWAP", async () => {
|
|
60
51
|
// Given
|
|
61
52
|
const exchange = new Exchange_1.default(transport, 3 /* ExchangeTypes.SwapNg */);
|
|
62
53
|
// When
|
|
63
|
-
const transactionId =
|
|
54
|
+
const transactionId = await exchange.startNewTransaction();
|
|
64
55
|
// Then
|
|
65
56
|
expect(transactionId).toEqual(expect.any(String));
|
|
66
57
|
expect(transactionId).toHaveLength(64);
|
|
67
|
-
const { partnerInfo, partnerSigned, partnerPrivKey } =
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const amount = new bignumber_js_1.default(
|
|
71
|
-
const amountToWallet = new bignumber_js_1.default(
|
|
72
|
-
let encodedPayload =
|
|
58
|
+
const { partnerInfo, partnerSigned, partnerPrivKey } = await appExchangeDatasetTest(ngSignFormat);
|
|
59
|
+
await exchange.setPartnerKey(partnerInfo);
|
|
60
|
+
await exchange.checkPartner(partnerSigned);
|
|
61
|
+
const amount = new bignumber_js_1.default(100_000);
|
|
62
|
+
const amountToWallet = new bignumber_js_1.default(100_000_000_000);
|
|
63
|
+
let encodedPayload = await generateSwapPayloadProtobuf({
|
|
73
64
|
payinAddress: "0xd692Cb1346262F584D17B4B470954501f6715a82",
|
|
74
65
|
refundAddress: "0xDad77910DbDFdE764fC21FCD4E74D71bBACA6D8D",
|
|
75
66
|
payoutAddress: "bc1qer57ma0fzhqys2cmydhuj9cprf9eg0nw922a8j",
|
|
@@ -81,25 +72,25 @@ describe("Check Exchange until payload signature", () => {
|
|
|
81
72
|
});
|
|
82
73
|
encodedPayload = convertToJWSPayload(encodedPayload);
|
|
83
74
|
const estimatedFees = new bignumber_js_1.default(0);
|
|
84
|
-
|
|
85
|
-
const payloadSignature =
|
|
86
|
-
|
|
87
|
-
})
|
|
88
|
-
it("NG SWAP with more than 255 bytes in process transaction", () =>
|
|
75
|
+
await exchange.processTransaction(encodedPayload, estimatedFees, "jws");
|
|
76
|
+
const payloadSignature = await signMessage(encodedPayload, partnerPrivKey, "rs");
|
|
77
|
+
await exchange.checkTransactionSignature(payloadSignature);
|
|
78
|
+
});
|
|
79
|
+
it("NG SWAP with more than 255 bytes in process transaction", async () => {
|
|
89
80
|
// Given
|
|
90
81
|
const exchange = new Exchange_1.default(transport, 3 /* ExchangeTypes.SwapNg */);
|
|
91
82
|
// When
|
|
92
|
-
const transactionId =
|
|
83
|
+
const transactionId = await exchange.startNewTransaction();
|
|
93
84
|
// Then
|
|
94
85
|
expect(transactionId).toEqual(expect.any(String));
|
|
95
86
|
expect(transactionId).toHaveLength(64);
|
|
96
|
-
const { partnerInfo, partnerSigned, partnerPrivKey } =
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
const amount = new bignumber_js_1.default(
|
|
100
|
-
const amountToWallet = new bignumber_js_1.default(
|
|
87
|
+
const { partnerInfo, partnerSigned, partnerPrivKey } = await appExchangeDatasetTest(ngSignFormat);
|
|
88
|
+
await exchange.setPartnerKey(partnerInfo);
|
|
89
|
+
await exchange.checkPartner(partnerSigned);
|
|
90
|
+
const amount = new bignumber_js_1.default(100_000);
|
|
91
|
+
const amountToWallet = new bignumber_js_1.default(100_000_000_000);
|
|
101
92
|
// Extra properties have a limited size of 20 (i.e. app-exchange/src/proto/protocol.options)
|
|
102
|
-
let encodedPayload =
|
|
93
|
+
let encodedPayload = await generateSwapPayloadProtobuf({
|
|
103
94
|
payinAddress: "0xd692Cb1346262F584D17B4B470954501f6715a82",
|
|
104
95
|
payinExtraId: '{ extraInfo: "Go" }',
|
|
105
96
|
refundAddress: "0xDad77910DbDFdE764fC21FCD4E74D71bBACA6D8D",
|
|
@@ -114,51 +105,51 @@ describe("Check Exchange until payload signature", () => {
|
|
|
114
105
|
});
|
|
115
106
|
encodedPayload = convertToJWSPayload(encodedPayload);
|
|
116
107
|
const estimatedFees = new bignumber_js_1.default(0);
|
|
117
|
-
|
|
108
|
+
await exchange.processTransaction(encodedPayload, estimatedFees, "jws");
|
|
118
109
|
console.log("DEBUG - SWAP partner encoded payload:", encodedPayload.toString("hex"));
|
|
119
|
-
const payloadSignature =
|
|
110
|
+
const payloadSignature = await signMessage(encodedPayload, partnerPrivKey, "rs");
|
|
120
111
|
console.log("DEBUG - SWAP partner payload signature:", Buffer.from(payloadSignature).toString("hex"));
|
|
121
|
-
|
|
122
|
-
})
|
|
123
|
-
it("NG SWAP with prepared data", () =>
|
|
112
|
+
await exchange.checkTransactionSignature(payloadSignature);
|
|
113
|
+
});
|
|
114
|
+
it("NG SWAP with prepared data", async () => {
|
|
124
115
|
// Given
|
|
125
116
|
const exchange = new Exchange_1.default(transport, 3 /* ExchangeTypes.SwapNg */);
|
|
126
117
|
// When
|
|
127
|
-
const transactionId =
|
|
118
|
+
const transactionId = await exchange.startNewTransaction();
|
|
128
119
|
// Then
|
|
129
120
|
expect(transactionId).toEqual(expect.any(String));
|
|
130
121
|
expect(transactionId).toHaveLength(64);
|
|
131
|
-
const { partnerInfo, partnerSigned, apdu } =
|
|
132
|
-
|
|
122
|
+
const { partnerInfo, partnerSigned, apdu } = await appExchangeDataset(ngSignFormat);
|
|
123
|
+
await exchange.setPartnerKey(partnerInfo);
|
|
133
124
|
console.log("DEBUG - Swap partner APDU:", apdu.toString("hex"));
|
|
134
125
|
console.log("DEBUG - Swap partner signed:", Buffer.from(partnerSigned).toString("hex"));
|
|
135
|
-
|
|
126
|
+
await exchange.checkPartner(partnerSigned);
|
|
136
127
|
const encodedPayload = Buffer.from(".CipiYzFxYXIwc3Jycjd4Zmt2eTVsNjQzbHlkbnc5cmU1OWd0enp3ZjVtZHEaKmJjMXFhcjBzcnJyN3hma3Z5NWw2NDNseWRudzlyZTU5Z3R6endmNHRlcSoqMHhiNzk0ZjVlYTBiYTM5NDk0Y2U4Mzk2MTNmZmZiYTc0Mjc5NTc5MjY4OgNCVENCA0JBVEoCBH5SBgV0-95gAGIgNQrqDJf3R_HQ92CBRhSkdSOAGxrrfQvLuqKk9Gv4GEs=");
|
|
137
128
|
const estimatedFees = new bignumber_js_1.default(0);
|
|
138
|
-
|
|
129
|
+
await exchange.processTransaction(encodedPayload, estimatedFees, "jws");
|
|
139
130
|
console.log("DEBUG - SWAP partner encoded payload:", encodedPayload.toString("hex"));
|
|
140
131
|
// const payloadSignature = await signMessage(encodedPayload, partnerPrivKey, "rs");
|
|
141
132
|
const payloadSignature = Buffer.from("zGcNUYKM8sLxvT7zPU1C8vrMmanVlUroELnAeil4weo1LCk0zUBRse5-3Acv7I7II90xVTIxm26BnxRbZvVmTQ==", "base64url");
|
|
142
133
|
console.log("DEBUG - SWAP partner payload signature:", Buffer.from(payloadSignature).toString("hex"));
|
|
143
|
-
|
|
144
|
-
})
|
|
145
|
-
it("NG SWAP with TON", () =>
|
|
134
|
+
await exchange.checkTransactionSignature(payloadSignature);
|
|
135
|
+
});
|
|
136
|
+
it("NG SWAP with TON", async () => {
|
|
146
137
|
// Given
|
|
147
138
|
const exchange = new Exchange_1.default(transport, 3 /* ExchangeTypes.SwapNg */);
|
|
148
139
|
// When
|
|
149
|
-
const transactionId =
|
|
140
|
+
const transactionId = await exchange.startNewTransaction();
|
|
150
141
|
// Then
|
|
151
142
|
expect(transactionId).toEqual(expect.any(String));
|
|
152
143
|
expect(transactionId).toHaveLength(64);
|
|
153
|
-
const { partnerInfo, partnerSigned, apdu, partnerPrivKey } =
|
|
154
|
-
|
|
144
|
+
const { partnerInfo, partnerSigned, apdu, partnerPrivKey } = await appExchangeDatasetTest(ngSignFormat);
|
|
145
|
+
await exchange.setPartnerKey(partnerInfo);
|
|
155
146
|
console.log("DEBUG - Swap partner APDU:", apdu.toString("hex"));
|
|
156
147
|
console.log("DEBUG - Swap partner signed:", Buffer.from(partnerSigned).toString("hex"));
|
|
157
|
-
|
|
148
|
+
await exchange.checkPartner(partnerSigned);
|
|
158
149
|
const amount = new bignumber_js_1.default(100);
|
|
159
|
-
const amountToWallet = new bignumber_js_1.default(
|
|
150
|
+
const amountToWallet = new bignumber_js_1.default(1_000);
|
|
160
151
|
// Extra properties have a limited size of 20 (i.e. app-exchange/src/proto/protocol.options)
|
|
161
|
-
let encodedPayload =
|
|
152
|
+
let encodedPayload = await generateSwapPayloadProtobuf({
|
|
162
153
|
payinAddress: "UQAbvs2tCnsTWxCZX7JW-dqlk0vM8x_m8aJqF4wwRWGtTEZD",
|
|
163
154
|
refundAddress: "UQAbvs2tCnsTWxCZX7JW-dqlk0vM8x_m8aJqF4wwRWGtTEZD",
|
|
164
155
|
payoutAddress: "0x66c4371aE8FFeD2ec1c2EBbbcCfb7E494181E1E3",
|
|
@@ -173,48 +164,48 @@ describe("Check Exchange until payload signature", () => {
|
|
|
173
164
|
});
|
|
174
165
|
encodedPayload = convertToJWSPayload(encodedPayload);
|
|
175
166
|
const estimatedFees = new bignumber_js_1.default(0);
|
|
176
|
-
|
|
167
|
+
await exchange.processTransaction(encodedPayload, estimatedFees, "jws");
|
|
177
168
|
console.log("DEBUG - SWAP partner encoded payload:", encodedPayload.toString("hex"));
|
|
178
|
-
const payloadSignature =
|
|
169
|
+
const payloadSignature = await signMessage(encodedPayload, partnerPrivKey, "rs");
|
|
179
170
|
console.log("DEBUG - SWAP partner payload signature:", Buffer.from(payloadSignature).toString("hex"));
|
|
180
|
-
|
|
171
|
+
await exchange.checkTransactionSignature(payloadSignature);
|
|
181
172
|
const configEth = {
|
|
182
173
|
config: Buffer.from("0345544808457468657265756d050345544812", "hex"),
|
|
183
174
|
signature: Buffer.from("3044022065d7931ab3144362d57e3fdcc5de921fb65024737d917f0ab1f8b173d1ed3c2e022027493568d112dc53c7177f8e5fc915d91a903780a067badf109085a73d360323", "hex"),
|
|
184
175
|
};
|
|
185
176
|
let addressParameters = bip32asBuffer("44'/60'/0'/0/0");
|
|
186
|
-
|
|
177
|
+
await exchange.validatePayoutOrAsset(configEth.config, configEth.signature, addressParameters);
|
|
187
178
|
const delay = (milliseconds) => {
|
|
188
179
|
return new Promise(resolve => {
|
|
189
180
|
setTimeout(resolve, milliseconds);
|
|
190
181
|
});
|
|
191
182
|
};
|
|
192
|
-
|
|
183
|
+
await delay(500);
|
|
193
184
|
const configTon = {
|
|
194
185
|
config: Buffer.from("03544f4e03544f4e00", "hex"),
|
|
195
186
|
signature: Buffer.from("3045022100b35be5d1ad0d71572b5f3d72b40766521d5492fad6ed54289a64488bec3344a902205b522b7b8c7c800826bcd0bda092e84db5d1c23f6061c8b57c8efb3641d243a7", "hex"),
|
|
196
187
|
};
|
|
197
188
|
addressParameters = bip32asBuffer("44'/607'/0'/0'/0'/0'");
|
|
198
|
-
|
|
199
|
-
})
|
|
189
|
+
await exchange.checkRefundAddress(configTon.config, configTon.signature, addressParameters);
|
|
190
|
+
});
|
|
200
191
|
});
|
|
201
192
|
describe("Check SELL", () => {
|
|
202
|
-
it("NG Sell", () =>
|
|
193
|
+
it("NG Sell", async () => {
|
|
203
194
|
// Given
|
|
204
195
|
const exchange = new Exchange_1.default(transport, 4 /* ExchangeTypes.SellNg */);
|
|
205
196
|
// When
|
|
206
|
-
const transactionId =
|
|
197
|
+
const transactionId = await exchange.startNewTransaction();
|
|
207
198
|
// Then
|
|
208
199
|
expect(transactionId).toEqual(expect.any(String));
|
|
209
200
|
expect(transactionId).toHaveLength(64);
|
|
210
|
-
const { partnerInfo, partnerSigned, partnerPrivKey, apdu } =
|
|
211
|
-
|
|
201
|
+
const { partnerInfo, partnerSigned, partnerPrivKey, apdu } = await appExchangeSellDataset(ngSignFormat);
|
|
202
|
+
await exchange.setPartnerKey(partnerInfo);
|
|
212
203
|
console.log("DEBUG - Sell partner pubkey:", partnerInfo.publicKey.toString("hex"));
|
|
213
204
|
console.log("DEBUG - Sell partner APDU:", apdu.toString("hex"));
|
|
214
205
|
console.log("DEBUG - Sell partner signed:", Buffer.from(partnerSigned).toString("hex"));
|
|
215
|
-
|
|
216
|
-
const amount = new bignumber_js_1.default(
|
|
217
|
-
let encodedPayload =
|
|
206
|
+
await exchange.checkPartner(partnerSigned);
|
|
207
|
+
const amount = new bignumber_js_1.default(100_000);
|
|
208
|
+
let encodedPayload = await generateSellPayloadProtobuf({
|
|
218
209
|
traderEmail: "test@ledger.fr",
|
|
219
210
|
inCurrency: "ETH",
|
|
220
211
|
inAmount: Buffer.from(amount.toString(16), "hex"),
|
|
@@ -228,40 +219,40 @@ describe("Check Exchange until payload signature", () => {
|
|
|
228
219
|
});
|
|
229
220
|
encodedPayload = convertToJWSPayload(encodedPayload);
|
|
230
221
|
const estimatedFees = new bignumber_js_1.default(0);
|
|
231
|
-
|
|
222
|
+
await exchange.processTransaction(encodedPayload, estimatedFees, "jws");
|
|
232
223
|
console.log("DEBUG - SELL partner encoded payload:", encodedPayload.toString("hex"));
|
|
233
|
-
const payloadSignature =
|
|
224
|
+
const payloadSignature = await signMessage(encodedPayload, partnerPrivKey, "rs");
|
|
234
225
|
console.log("DEBUG - SELL partner payload signature:", Buffer.from(payloadSignature).toString("hex"));
|
|
235
|
-
|
|
236
|
-
})
|
|
226
|
+
await exchange.checkTransactionSignature(payloadSignature);
|
|
227
|
+
});
|
|
237
228
|
});
|
|
238
229
|
});
|
|
239
230
|
describe("Test internal sign and verification functionality", () => {
|
|
240
231
|
describe("With Ledger keys", () => {
|
|
241
232
|
const privKey = Buffer.from("b1ed47ef58f782e2bc4d5abe70ef66d9009c2957967017054470e0f3e10f5833", "hex");
|
|
242
233
|
const pubKey = Buffer.from("0420da62003c0ce097e33644a10fe4c30454069a4454f0fa9d4e84f45091429b5220af9e35c0b2d9289380137307de4dd1d418428cf21a93b33561bb09d88fe579", "hex");
|
|
243
|
-
test("simple signature", () =>
|
|
234
|
+
test("simple signature", async () => {
|
|
244
235
|
// Given
|
|
245
236
|
const msg = "Something important to cipher";
|
|
246
237
|
// When
|
|
247
|
-
const sig =
|
|
238
|
+
const sig = await signMessage(Buffer.from(msg), privKey, "rs");
|
|
248
239
|
console.log("DEBUG - Test internal: message signature", Buffer.from(sig).toString("hex"));
|
|
249
240
|
// Then
|
|
250
|
-
const hashBuffer =
|
|
241
|
+
const hashBuffer = await crypto_1.subtle.digest("SHA-256", Buffer.from(msg));
|
|
251
242
|
const hash = new Uint8Array(hashBuffer);
|
|
252
243
|
expect(secp256k1_1.default.ecdsaVerify(sig, hash, pubKey)).toBeTruthy();
|
|
253
|
-
})
|
|
254
|
-
test("APDU signature generated by this test suite", () =>
|
|
244
|
+
});
|
|
245
|
+
test("APDU signature generated by this test suite", async () => {
|
|
255
246
|
// Given
|
|
256
247
|
const msg = "0953454c4c5f54455354000478d5facdae2305f48795d3ce7d9244f5060d2f800901da5746d1f4177ae8d7bbe63f3870efc0d36af8f91962811e1d8d9df91ce3b3ea2cd9f550c7d465f8b7b3";
|
|
257
248
|
// When
|
|
258
249
|
const sig = Buffer.from("30440220471b035b40dafa095d615998c82202b2bd00fb45670b828f1dda3b68e5b24cc3022022a1c64d02b8c14e1e4cc2d05b00234642c11db3d4461ff5366f5af337cf0ced", "hex");
|
|
259
250
|
// Then
|
|
260
|
-
const hashBuffer =
|
|
251
|
+
const hashBuffer = await crypto_1.subtle.digest("SHA-256", Buffer.from(msg, "hex"));
|
|
261
252
|
const hash = new Uint8Array(hashBuffer);
|
|
262
253
|
expect(secp256k1_1.default.ecdsaVerify(convertSignatureFromDER(sig), hash, pubKey)).toBeTruthy();
|
|
263
|
-
})
|
|
264
|
-
test("APDU signature generated by external tool", () =>
|
|
254
|
+
});
|
|
255
|
+
test("APDU signature generated by external tool", async () => {
|
|
265
256
|
// Given
|
|
266
257
|
// {"name":"TEST_PROVIDER","payloadSignatureComputedFormat":"jws","publicKey":{"curve":"secp256r1","data":"047c13debdb9e1afac5a82bbe78da6dca98a2e59af8a9a3f827acb8ed325c79a6c5749eff65d4e3470bd2995def771f45426c58eada7227d536feeffb58fa71c24"},"service":{"appVersion":2,"name":"swap"},"signature":"3045022072e6773318af531e478c40f53815d2fa0a1c06c49519bb693ff234662fb6558802210083ab26162da41d3c429dd10051f565440576193031eb0590a9ea200af987f062"}
|
|
267
258
|
const msg = "0d544553545f50524f564944455201047c13debdb9e1afac5a82bbe78da6dca98a2e59af8a9a3f827acb8ed325c79a6c5749eff65d4e3470bd2995def771f45426c58eada7227d536feeffb58fa71c24";
|
|
@@ -278,14 +269,14 @@ describe("Test internal sign and verification functionality", () => {
|
|
|
278
269
|
// "3045022068e5971fdad78583e7bb28adac09212108966fd2ed4f8ad206499bca59f0ad12022100aed715d306f772524b805dd4f91afc79b4bda1a14f91d90ea78739e05461d6c7",
|
|
279
270
|
// "hex",
|
|
280
271
|
// );
|
|
281
|
-
const sig =
|
|
272
|
+
const sig = await signMessage(Buffer.from(msg, "hex"), LEDGER_FAKE_PRIVATE_KEY, "der");
|
|
282
273
|
console.log("DEBUG - Test internal: message signature", Buffer.from(sig).toString("hex"));
|
|
283
274
|
// Then
|
|
284
|
-
const hashBuffer =
|
|
275
|
+
const hashBuffer = await crypto_1.subtle.digest("SHA-256", Buffer.from(msg, "hex"));
|
|
285
276
|
const hash = new Uint8Array(hashBuffer);
|
|
286
277
|
expect(secp256k1_1.default.ecdsaVerify(convertSignatureFromDER(sig), hash, pubKey)).toBeTruthy();
|
|
287
|
-
})
|
|
288
|
-
test("APDU signature already validated", () =>
|
|
278
|
+
});
|
|
279
|
+
test("APDU signature already validated", async () => {
|
|
289
280
|
// Given
|
|
290
281
|
const msg = legacySignFormat({
|
|
291
282
|
name: "Coinify",
|
|
@@ -299,36 +290,36 @@ describe("Test internal sign and verification functionality", () => {
|
|
|
299
290
|
// const sig = await signMessage(Buffer.from(msg, "hex"), LEDGER_FAKE_PRIVATE_KEY, "der");
|
|
300
291
|
console.log("DEBUG - Test internal: message signature", Buffer.from(sig).toString("hex"));
|
|
301
292
|
// Then
|
|
302
|
-
const hashBuffer =
|
|
293
|
+
const hashBuffer = await crypto_1.subtle.digest("SHA-256", msg);
|
|
303
294
|
const hash = new Uint8Array(hashBuffer);
|
|
304
295
|
expect(secp256k1_1.default.ecdsaVerify(convertSignatureFromDER(sig), hash, pubKey)).toBeTruthy();
|
|
305
|
-
})
|
|
296
|
+
});
|
|
306
297
|
});
|
|
307
298
|
describe("With SELL keys", () => {
|
|
308
299
|
const privKey = Buffer.from("308f6a5369aea611d89abf937d0ffaf0b43b457d42cbf0cf754786b3088f17ae", "hex");
|
|
309
300
|
const pubKey = Buffer.from("0478d5facdae2305f48795d3ce7d9244f5060d2f800901da5746d1f4177ae8d7bbe63f3870efc0d36af8f91962811e1d8d9df91ce3b3ea2cd9f550c7d465f8b7b3", "hex");
|
|
310
|
-
test("SELL private and public K1 key pair", () =>
|
|
301
|
+
test("SELL private and public K1 key pair", async () => {
|
|
311
302
|
// Given
|
|
312
303
|
const msg = "Something important to cipher";
|
|
313
304
|
// When
|
|
314
|
-
const sig =
|
|
305
|
+
const sig = await signMessage(Buffer.from(msg), privKey, "rs");
|
|
315
306
|
console.log("DEBUG - Test internal: message signature", Buffer.from(sig).toString("hex"));
|
|
316
307
|
// Then
|
|
317
|
-
const hashBuffer =
|
|
308
|
+
const hashBuffer = await crypto_1.subtle.digest("SHA-256", Buffer.from(msg));
|
|
318
309
|
const hash = new Uint8Array(hashBuffer);
|
|
319
310
|
expect(secp256k1_1.default.ecdsaVerify(sig, hash, pubKey)).toBeTruthy();
|
|
320
|
-
})
|
|
321
|
-
test("SELL verify payload signature", () =>
|
|
311
|
+
});
|
|
312
|
+
test("SELL verify payload signature", async () => {
|
|
322
313
|
// Given
|
|
323
314
|
const msg = "2e436735305a584e305147786c5a47646c6369356d636849445256524947674959616949714d48686b4e6a6b79513249784d7a51324d6a5979526a55344e4551784e304930516a51334d446b314e4455774d5759324e7a4531595467794b674e465656497942416f41454145364944554b366779583930667830506467675559557048556a674273613633304c79377169705052722d42684c";
|
|
324
315
|
// When
|
|
325
316
|
const sig = Buffer.from("348e938ce75c06da9a27652c2af6146b4581f948c600b4f7093743e8af256d172324131dcc852f068d0bd20afd0c8444bc635e9520d3a29cab7ff7c27dc8b782", "hex");
|
|
326
317
|
console.log("DEBUG - Test internal: message signature", Buffer.from(sig).toString("hex"));
|
|
327
318
|
// Then
|
|
328
|
-
const hashBuffer =
|
|
319
|
+
const hashBuffer = await crypto_1.subtle.digest("SHA-256", Buffer.from(msg, "hex"));
|
|
329
320
|
const hash = new Uint8Array(hashBuffer);
|
|
330
321
|
expect(secp256k1_1.default.ecdsaVerify(sig, hash, pubKey)).toBeTruthy();
|
|
331
|
-
})
|
|
322
|
+
});
|
|
332
323
|
});
|
|
333
324
|
});
|
|
334
325
|
// Those information comes from dataset test of app-exchange (i.e. check signing_authority.py file).
|
|
@@ -353,106 +344,94 @@ const ngSignFormat = (info) => {
|
|
|
353
344
|
info.publicKey,
|
|
354
345
|
]);
|
|
355
346
|
};
|
|
356
|
-
function appExchangeDatasetTest(signFormat) {
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
};
|
|
379
|
-
});
|
|
347
|
+
async function appExchangeDatasetTest(signFormat) {
|
|
348
|
+
// Generate random provider key
|
|
349
|
+
let privKey;
|
|
350
|
+
do {
|
|
351
|
+
privKey = (0, crypto_1.randomBytes)(32);
|
|
352
|
+
} while (!secp256k1_1.default.privateKeyVerify(privKey));
|
|
353
|
+
// The expected public should not be compressed and be a full 64 length (with R and S)
|
|
354
|
+
const isCompressed = false;
|
|
355
|
+
const pubKey = secp256k1_1.default.publicKeyCreate(privKey, isCompressed);
|
|
356
|
+
const partnerInfo = {
|
|
357
|
+
name: "SWAP_TEST",
|
|
358
|
+
curve: "secp256k1",
|
|
359
|
+
publicKey: pubKey,
|
|
360
|
+
};
|
|
361
|
+
const msg = signFormat(partnerInfo);
|
|
362
|
+
const sig = await signMessage(msg, LEDGER_FAKE_PRIVATE_KEY, "der");
|
|
363
|
+
return {
|
|
364
|
+
partnerInfo,
|
|
365
|
+
apdu: msg,
|
|
366
|
+
partnerSigned: sig,
|
|
367
|
+
partnerPrivKey: privKey,
|
|
368
|
+
};
|
|
380
369
|
}
|
|
381
|
-
function appExchangeDataset(signFormat) {
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
};
|
|
397
|
-
});
|
|
370
|
+
async function appExchangeDataset(signFormat) {
|
|
371
|
+
const pubKey = Buffer.from("0478d5facdae2305f48795d3ce7d9244f5060d2f800901da5746d1f4177ae8d7bbe63f3870efc0d36af8f91962811e1d8d9df91ce3b3ea2cd9f550c7d465f8b7b3", "hex");
|
|
372
|
+
secp256k1_1.default.publicKeyVerify(pubKey);
|
|
373
|
+
const partnerInfo = {
|
|
374
|
+
name: "SWAP_TEST",
|
|
375
|
+
curve: "secp256k1",
|
|
376
|
+
publicKey: pubKey,
|
|
377
|
+
};
|
|
378
|
+
const msg = signFormat(partnerInfo);
|
|
379
|
+
const sig = await signMessage(msg, LEDGER_FAKE_PRIVATE_KEY, "der");
|
|
380
|
+
return {
|
|
381
|
+
partnerInfo,
|
|
382
|
+
apdu: msg,
|
|
383
|
+
partnerSigned: sig,
|
|
384
|
+
};
|
|
398
385
|
}
|
|
399
|
-
function appExchangeSellDataset(signFormat) {
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
};
|
|
417
|
-
});
|
|
386
|
+
async function appExchangeSellDataset(signFormat) {
|
|
387
|
+
const privKey = Buffer.from("308f6a5369aea611d89abf937d0ffaf0b43b457d42cbf0cf754786b3088f17ae", "hex");
|
|
388
|
+
const pubKey = Buffer.from("0478d5facdae2305f48795d3ce7d9244f5060d2f800901da5746d1f4177ae8d7bbe63f3870efc0d36af8f91962811e1d8d9df91ce3b3ea2cd9f550c7d465f8b7b3", "hex");
|
|
389
|
+
secp256k1_1.default.publicKeyVerify(pubKey);
|
|
390
|
+
const partnerInfo = {
|
|
391
|
+
name: "SELL_TEST",
|
|
392
|
+
curve: "secp256k1",
|
|
393
|
+
publicKey: pubKey,
|
|
394
|
+
};
|
|
395
|
+
const msg = signFormat(partnerInfo);
|
|
396
|
+
const sig = await signMessage(msg, LEDGER_FAKE_PRIVATE_KEY, "der");
|
|
397
|
+
return {
|
|
398
|
+
partnerInfo,
|
|
399
|
+
apdu: msg,
|
|
400
|
+
partnerSigned: sig,
|
|
401
|
+
partnerPrivKey: privKey,
|
|
402
|
+
};
|
|
418
403
|
}
|
|
419
|
-
function generateSwapPayloadProtobuf(payload) {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
return Buffer.from(messageEncoded);
|
|
430
|
-
});
|
|
404
|
+
async function generateSwapPayloadProtobuf(payload) {
|
|
405
|
+
const root = await protobufjs_1.default.load("protocol.proto");
|
|
406
|
+
const TransactionResponse = root.lookupType("ledger_swap.NewTransactionResponse");
|
|
407
|
+
const err = TransactionResponse.verify(payload);
|
|
408
|
+
if (err) {
|
|
409
|
+
throw Error(err);
|
|
410
|
+
}
|
|
411
|
+
const message = TransactionResponse.create(payload);
|
|
412
|
+
const messageEncoded = TransactionResponse.encode(message).finish();
|
|
413
|
+
return Buffer.from(messageEncoded);
|
|
431
414
|
}
|
|
432
|
-
function generateSellPayloadProtobuf(payload) {
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
return Buffer.from(messageEncoded);
|
|
443
|
-
});
|
|
415
|
+
async function generateSellPayloadProtobuf(payload) {
|
|
416
|
+
const root = await protobufjs_1.default.load("protocol.proto");
|
|
417
|
+
const SellResponse = root.lookupType("ledger_swap.NewSellResponse");
|
|
418
|
+
const err = SellResponse.verify(payload);
|
|
419
|
+
if (err) {
|
|
420
|
+
throw Error(err);
|
|
421
|
+
}
|
|
422
|
+
const message = SellResponse.create(payload);
|
|
423
|
+
const messageEncoded = SellResponse.encode(message).finish();
|
|
424
|
+
return Buffer.from(messageEncoded);
|
|
444
425
|
}
|
|
445
426
|
// Sign message in ECDSA-SHA256 with secp256k1 curve and returnsa DER format signature
|
|
446
|
-
function signMessage(message, privKey, sigFormat) {
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
return sig;
|
|
455
|
-
});
|
|
427
|
+
async function signMessage(message, privKey, sigFormat) {
|
|
428
|
+
const hashBuffer = await crypto_1.subtle.digest("SHA-256", message);
|
|
429
|
+
const hash = new Uint8Array(hashBuffer);
|
|
430
|
+
const sig = secp256k1_1.default.ecdsaSign(hash, privKey).signature;
|
|
431
|
+
if (sigFormat === "der") {
|
|
432
|
+
return convertSignatureToDER(sig);
|
|
433
|
+
}
|
|
434
|
+
return sig;
|
|
456
435
|
}
|
|
457
436
|
function convertSignatureToDER(sig) {
|
|
458
437
|
return secp256k1_1.default.signatureExport(sig);
|