@ledgerhq/hw-app-vet 0.1.0-nightly.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 +4 -0
- package/CHANGELOG.md +12 -0
- package/LICENSE.txt +21 -0
- package/README.md +83 -0
- package/jest.config.ts +6 -0
- package/lib/Vet.d.ts +38 -0
- package/lib/Vet.d.ts.map +1 -0
- package/lib/Vet.js +105 -0
- package/lib/Vet.js.map +1 -0
- package/lib/constants.d.ts +33 -0
- package/lib/constants.d.ts.map +1 -0
- package/lib/constants.js +37 -0
- package/lib/constants.js.map +1 -0
- package/lib/errors.d.ts +4 -0
- package/lib/errors.d.ts.map +1 -0
- package/lib/errors.js +6 -0
- package/lib/errors.js.map +1 -0
- package/lib/model.d.ts +6 -0
- package/lib/model.d.ts.map +1 -0
- package/lib/model.js +3 -0
- package/lib/model.js.map +1 -0
- package/lib/utils.d.ts +4 -0
- package/lib/utils.d.ts.map +1 -0
- package/lib/utils.js +50 -0
- package/lib/utils.js.map +1 -0
- package/lib-es/Vet.d.ts +38 -0
- package/lib-es/Vet.d.ts.map +1 -0
- package/lib-es/Vet.js +102 -0
- package/lib-es/Vet.js.map +1 -0
- package/lib-es/constants.d.ts +33 -0
- package/lib-es/constants.d.ts.map +1 -0
- package/lib-es/constants.js +34 -0
- package/lib-es/constants.js.map +1 -0
- package/lib-es/errors.d.ts +4 -0
- package/lib-es/errors.d.ts.map +1 -0
- package/lib-es/errors.js +3 -0
- package/lib-es/errors.js.map +1 -0
- package/lib-es/model.d.ts +6 -0
- package/lib-es/model.d.ts.map +1 -0
- package/lib-es/model.js +2 -0
- package/lib-es/model.js.map +1 -0
- package/lib-es/utils.d.ts +4 -0
- package/lib-es/utils.d.ts.map +1 -0
- package/lib-es/utils.js +45 -0
- package/lib-es/utils.js.map +1 -0
- package/package.json +58 -0
- package/src/Vet.ts +131 -0
- package/src/constants.ts +32 -0
- package/src/errors.ts +5 -0
- package/src/model.ts +5 -0
- package/src/utils.ts +46 -0
- package/tests/Vechain.test.ts +62 -0
- package/tsconfig.json +8 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# @ledgerhq/hw-app-vet
|
|
2
|
+
|
|
3
|
+
## 0.1.0-nightly.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#4947](https://github.com/LedgerHQ/ledger-live/pull/4947) [`2edfa533bc`](https://github.com/LedgerHQ/ledger-live/commit/2edfa533bccafbfd8a61aea0f5422c0db79825ea) Thanks [@hedi-edelbloute](https://github.com/hedi-edelbloute)! - vechain integration
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [[`2edfa533bc`](https://github.com/LedgerHQ/ledger-live/commit/2edfa533bccafbfd8a61aea0f5422c0db79825ea)]:
|
|
12
|
+
- @ledgerhq/cryptoassets@11.2.0-nightly.2
|
package/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2017-present Ledger https://www.ledger.com/
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
<img src="https://user-images.githubusercontent.com/4631227/191834116-59cf590e-25cc-4956-ae5c-812ea464f324.png" height="100" />
|
|
2
|
+
|
|
3
|
+
[GitHub](https://github.com/LedgerHQ/ledger-live/),
|
|
4
|
+
[Ledger Devs Discord](https://developers.ledger.com/discord-pro),
|
|
5
|
+
[Developer Portal](https://developers.ledger.com/)
|
|
6
|
+
|
|
7
|
+
## @ledgerhq/hw-app-vet
|
|
8
|
+
|
|
9
|
+
Ledger Hardware Wallet ETH JavaScript bindings.
|
|
10
|
+
|
|
11
|
+
***
|
|
12
|
+
|
|
13
|
+
## Are you adding Ledger support to your software wallet?
|
|
14
|
+
|
|
15
|
+
You may be using this package to communicate with the VeChain Nano App.
|
|
16
|
+
|
|
17
|
+
For a smooth and quick integration:
|
|
18
|
+
|
|
19
|
+
* See the developers’ documentation on the [Developer Portal](https://developers.ledger.com/docs/transport/overview/) and
|
|
20
|
+
* Go on [Discord](https://developers.ledger.com/discord-pro/) to chat with developer support and the developer community.
|
|
21
|
+
|
|
22
|
+
***
|
|
23
|
+
|
|
24
|
+
## API
|
|
25
|
+
|
|
26
|
+
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
|
|
27
|
+
|
|
28
|
+
#### Table of Contents
|
|
29
|
+
|
|
30
|
+
* [Vet](#vet)
|
|
31
|
+
* [Parameters](#parameters)
|
|
32
|
+
* [Examples](#examples)
|
|
33
|
+
* [getAddress](#getaddress)
|
|
34
|
+
* [Parameters](#parameters-1)
|
|
35
|
+
* [Examples](#examples-1)
|
|
36
|
+
* [signTransaction](#signtransaction)
|
|
37
|
+
* [Parameters](#parameters-2)
|
|
38
|
+
|
|
39
|
+
### Vet
|
|
40
|
+
|
|
41
|
+
VeChain API
|
|
42
|
+
|
|
43
|
+
#### Parameters
|
|
44
|
+
|
|
45
|
+
* `transport` **Transport** 
|
|
46
|
+
* `scrambleKey` (optional, default `"V3T"`)
|
|
47
|
+
|
|
48
|
+
#### Examples
|
|
49
|
+
|
|
50
|
+
```javascript
|
|
51
|
+
import Vet from "@ledgerhq/hw-app-vet";
|
|
52
|
+
const vet = new Vet(transport)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
#### getAddress
|
|
56
|
+
|
|
57
|
+
get VeChain address for a given BIP 32 path.
|
|
58
|
+
|
|
59
|
+
##### Parameters
|
|
60
|
+
|
|
61
|
+
* `path` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** a path in BIP 32 format
|
|
62
|
+
* `display` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** 
|
|
63
|
+
* `chainCode` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** 
|
|
64
|
+
* `statusCodes` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\<StatusCodes>** (optional, default `[StatusCodes.OK]`)
|
|
65
|
+
|
|
66
|
+
##### Examples
|
|
67
|
+
|
|
68
|
+
```javascript
|
|
69
|
+
vet.getAddress("m/44'/818'/0'/0").then(o => o.address)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<{publicKey: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), address: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), chainCode: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?}>** an object with a publicKey and address
|
|
73
|
+
|
|
74
|
+
#### signTransaction
|
|
75
|
+
|
|
76
|
+
You can sign a transaction and retrieve v, r, s given the raw transaction and the BIP 32 path of the account to sign.
|
|
77
|
+
|
|
78
|
+
##### Parameters
|
|
79
|
+
|
|
80
|
+
* `path` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** : the BIP32 path to sign the transaction on
|
|
81
|
+
* `rawTxHex` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** : the raw vechain transaction in hexadecimal to sign
|
|
82
|
+
|
|
83
|
+
Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[Buffer](https://nodejs.org/api/buffer.html)>** 
|
package/jest.config.ts
ADDED
package/lib/Vet.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import type Transport from "@ledgerhq/hw-transport";
|
|
3
|
+
import { StatusCodes } from "./constants";
|
|
4
|
+
import { Buffer } from "buffer";
|
|
5
|
+
/**
|
|
6
|
+
* VeChain API
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* import Vet from "@ledgerhq/hw-app-vet";
|
|
10
|
+
* const vet = new Vet(transport)
|
|
11
|
+
*/
|
|
12
|
+
export default class Vet {
|
|
13
|
+
transport: Transport;
|
|
14
|
+
constructor(transport: Transport, scrambleKey?: string);
|
|
15
|
+
getAppConfiguration(): Promise<any>;
|
|
16
|
+
/**
|
|
17
|
+
* get VeChain address for a given BIP 32 path.
|
|
18
|
+
* @param path a path in BIP 32 format
|
|
19
|
+
* @option display
|
|
20
|
+
* @option chainCode
|
|
21
|
+
* @return an object with a publicKey and address
|
|
22
|
+
* @example
|
|
23
|
+
* vet.getAddress("m/44'/818'/0'/0").then(o => o.address)
|
|
24
|
+
*/
|
|
25
|
+
getAddress(path: string, display?: boolean, chainCode?: boolean, statusCodes?: StatusCodes[]): Promise<{
|
|
26
|
+
publicKey: string;
|
|
27
|
+
address: string;
|
|
28
|
+
chainCode?: string;
|
|
29
|
+
}>;
|
|
30
|
+
/**
|
|
31
|
+
* You can sign a transaction and retrieve v, r, s given the raw transaction and the BIP 32 path of the account to sign.
|
|
32
|
+
*
|
|
33
|
+
* @param path: the BIP32 path to sign the transaction on
|
|
34
|
+
* @param rawTxHex: the raw vechain transaction in hexadecimal to sign
|
|
35
|
+
*/
|
|
36
|
+
signTransaction(path: string, rawTxHex: string): Promise<Buffer>;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=Vet.d.ts.map
|
package/lib/Vet.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Vet.d.ts","sourceRoot":"","sources":["../src/Vet.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,SAAS,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1C,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAchC;;;;;;GAMG;AAEH,MAAM,CAAC,OAAO,OAAO,GAAG;IACtB,SAAS,EAAE,SAAS,CAAC;gBAET,SAAS,EAAE,SAAS,EAAE,WAAW,SAAQ;IAS/C,mBAAmB,IAAI,OAAO,CAAC,GAAG,CAAC;IAQzC;;;;;;;;OAQG;IACG,UAAU,CACd,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,OAAO,EACjB,SAAS,CAAC,EAAE,OAAO,EACnB,WAAW,GAAE,WAAW,EAAqB,GAC5C,OAAO,CAAC;QACT,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IAsCF;;;;;OAKG;IACG,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAsBvE"}
|
package/lib/Vet.js
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const constants_1 = require("./constants");
|
|
13
|
+
const utils_1 = require("./utils");
|
|
14
|
+
const buffer_1 = require("buffer");
|
|
15
|
+
const errors_1 = require("./errors");
|
|
16
|
+
const remapTransactionRelatedErrors = e => {
|
|
17
|
+
if (e && e.statusCode === 0x6a80) {
|
|
18
|
+
return new errors_1.VechainAppPleaseEnableContractDataAndMultiClause("Please enable contract data in Vechain app settings");
|
|
19
|
+
}
|
|
20
|
+
return e;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* VeChain API
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* import Vet from "@ledgerhq/hw-app-vet";
|
|
27
|
+
* const vet = new Vet(transport)
|
|
28
|
+
*/
|
|
29
|
+
class Vet {
|
|
30
|
+
constructor(transport, scrambleKey = "V3T") {
|
|
31
|
+
this.transport = transport;
|
|
32
|
+
transport.decorateAppAPIMethods(this, ["getAppConfiguration", "getAddress", "signTransaction"], scrambleKey);
|
|
33
|
+
}
|
|
34
|
+
getAppConfiguration() {
|
|
35
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
36
|
+
const response = yield this.transport.send(0xe0, 0x06, 0x00, 0x00, buffer_1.Buffer.alloc(0), [
|
|
37
|
+
constants_1.StatusCodes.OK,
|
|
38
|
+
]);
|
|
39
|
+
return response.slice(0, 4);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* get VeChain address for a given BIP 32 path.
|
|
44
|
+
* @param path a path in BIP 32 format
|
|
45
|
+
* @option display
|
|
46
|
+
* @option chainCode
|
|
47
|
+
* @return an object with a publicKey and address
|
|
48
|
+
* @example
|
|
49
|
+
* vet.getAddress("m/44'/818'/0'/0").then(o => o.address)
|
|
50
|
+
*/
|
|
51
|
+
getAddress(path, display, chainCode, statusCodes = [constants_1.StatusCodes.OK]) {
|
|
52
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
53
|
+
const paths = (0, utils_1.splitPath)(path);
|
|
54
|
+
const buffer = buffer_1.Buffer.alloc(1 + paths.length * 4);
|
|
55
|
+
buffer[0] = paths.length;
|
|
56
|
+
paths.forEach((element, index) => {
|
|
57
|
+
buffer.writeUInt32BE(element, 1 + 4 * index);
|
|
58
|
+
});
|
|
59
|
+
const response = yield this.transport.send(0xe0, 0x02, display ? 0x01 : 0x00, chainCode ? 0x01 : 0x00, buffer, statusCodes);
|
|
60
|
+
const publicKeyLength = response[0];
|
|
61
|
+
const addressLength = response[1 + publicKeyLength];
|
|
62
|
+
const acc = {
|
|
63
|
+
publicKey: response.slice(1, 1 + publicKeyLength).toString("hex"),
|
|
64
|
+
address: "0x" +
|
|
65
|
+
response
|
|
66
|
+
.slice(1 + publicKeyLength + 1, 1 + publicKeyLength + 1 + addressLength)
|
|
67
|
+
.toString("ascii")
|
|
68
|
+
.toLowerCase(),
|
|
69
|
+
};
|
|
70
|
+
if (chainCode) {
|
|
71
|
+
acc.chainCode = response
|
|
72
|
+
.slice(1 + publicKeyLength + 1 + addressLength, 1 + publicKeyLength + 1 + addressLength + 32)
|
|
73
|
+
.toString("hex");
|
|
74
|
+
}
|
|
75
|
+
return acc;
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* You can sign a transaction and retrieve v, r, s given the raw transaction and the BIP 32 path of the account to sign.
|
|
80
|
+
*
|
|
81
|
+
* @param path: the BIP32 path to sign the transaction on
|
|
82
|
+
* @param rawTxHex: the raw vechain transaction in hexadecimal to sign
|
|
83
|
+
*/
|
|
84
|
+
signTransaction(path, rawTxHex) {
|
|
85
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
86
|
+
const buffers = (0, utils_1.splitRaw)(path, rawTxHex, true);
|
|
87
|
+
const responses = [];
|
|
88
|
+
for (let i = 0; i < buffers.length; i++) {
|
|
89
|
+
const data = buffers[i];
|
|
90
|
+
responses.push(yield this.transport
|
|
91
|
+
.send(0xe0, 0x04, i === 0 ? 0x00 : 0x80, 0x00, data, [constants_1.StatusCodes.OK])
|
|
92
|
+
.catch(e => {
|
|
93
|
+
throw remapTransactionRelatedErrors(e);
|
|
94
|
+
}));
|
|
95
|
+
}
|
|
96
|
+
const lastResponse = responses[responses.length - 1];
|
|
97
|
+
if (lastResponse.length < 65) {
|
|
98
|
+
throw new Error("invalid signature");
|
|
99
|
+
}
|
|
100
|
+
return lastResponse.slice(0, 65);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
exports.default = Vet;
|
|
105
|
+
//# sourceMappingURL=Vet.js.map
|
package/lib/Vet.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Vet.js","sourceRoot":"","sources":["../src/Vet.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export declare enum StatusCodes {
|
|
2
|
+
PIN_REMAINING_ATTEMPTS = 25536,
|
|
3
|
+
INCORRECT_LENGTH = 26368,
|
|
4
|
+
COMMAND_INCOMPATIBLE_FILE_STRUCTURE = 27009,
|
|
5
|
+
SECURITY_STATUS_NOT_SATISFIED = 27010,
|
|
6
|
+
CONDITIONS_OF_USE_NOT_SATISFIED = 27013,
|
|
7
|
+
INCORRECT_DATA = 27264,
|
|
8
|
+
NOT_ENOUGH_MEMORY_SPACE = 27268,
|
|
9
|
+
REFERENCED_DATA_NOT_FOUND = 27272,
|
|
10
|
+
FILE_ALREADY_EXISTS = 27273,
|
|
11
|
+
INCORRECT_P1_P2 = 27392,
|
|
12
|
+
INS_NOT_SUPPORTED = 27904,
|
|
13
|
+
CLA_NOT_SUPPORTED = 28160,
|
|
14
|
+
TECHNICAL_PROBLEM = 28416,
|
|
15
|
+
OK = 36864,
|
|
16
|
+
MEMORY_PROBLEM = 37440,
|
|
17
|
+
NO_EF_SELECTED = 37888,
|
|
18
|
+
INVALID_OFFSET = 37890,
|
|
19
|
+
FILE_NOT_FOUND = 37892,
|
|
20
|
+
INCONSISTENT_FILE = 37896,
|
|
21
|
+
ALGORITHM_NOT_SUPPORTED = 38020,
|
|
22
|
+
INVALID_KCV = 38021,
|
|
23
|
+
CODE_NOT_INITIALIZED = 38914,
|
|
24
|
+
ACCESS_CONDITION_NOT_FULFILLED = 38916,
|
|
25
|
+
CONTRADICTION_SECRET_CODE_STATUS = 38920,
|
|
26
|
+
CONTRADICTION_INVALIDATION = 38928,
|
|
27
|
+
CODE_BLOCKED = 38976,
|
|
28
|
+
MAX_VALUE_REACHED = 38992,
|
|
29
|
+
GP_AUTH_FAILED = 25344,
|
|
30
|
+
LICENSING = 28482,
|
|
31
|
+
HALTED = 28586
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,oBAAY,WAAW;IACrB,sBAAsB,QAAS;IAC/B,gBAAgB,QAAS;IACzB,mCAAmC,QAAS;IAC5C,6BAA6B,QAAS;IACtC,+BAA+B,QAAS;IACxC,cAAc,QAAS;IACvB,uBAAuB,QAAS;IAChC,yBAAyB,QAAS;IAClC,mBAAmB,QAAS;IAC5B,eAAe,QAAS;IACxB,iBAAiB,QAAS;IAC1B,iBAAiB,QAAS;IAC1B,iBAAiB,QAAS;IAC1B,EAAE,QAAS;IACX,cAAc,QAAS;IACvB,cAAc,QAAS;IACvB,cAAc,QAAS;IACvB,cAAc,QAAS;IACvB,iBAAiB,QAAS;IAC1B,uBAAuB,QAAS;IAChC,WAAW,QAAS;IACpB,oBAAoB,QAAS;IAC7B,8BAA8B,QAAS;IACvC,gCAAgC,QAAS;IACzC,0BAA0B,QAAS;IACnC,YAAY,QAAS;IACrB,iBAAiB,QAAS;IAC1B,cAAc,QAAS;IACvB,SAAS,QAAS;IAClB,MAAM,QAAS;CAChB"}
|
package/lib/constants.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StatusCodes = void 0;
|
|
4
|
+
var StatusCodes;
|
|
5
|
+
(function (StatusCodes) {
|
|
6
|
+
StatusCodes[StatusCodes["PIN_REMAINING_ATTEMPTS"] = 25536] = "PIN_REMAINING_ATTEMPTS";
|
|
7
|
+
StatusCodes[StatusCodes["INCORRECT_LENGTH"] = 26368] = "INCORRECT_LENGTH";
|
|
8
|
+
StatusCodes[StatusCodes["COMMAND_INCOMPATIBLE_FILE_STRUCTURE"] = 27009] = "COMMAND_INCOMPATIBLE_FILE_STRUCTURE";
|
|
9
|
+
StatusCodes[StatusCodes["SECURITY_STATUS_NOT_SATISFIED"] = 27010] = "SECURITY_STATUS_NOT_SATISFIED";
|
|
10
|
+
StatusCodes[StatusCodes["CONDITIONS_OF_USE_NOT_SATISFIED"] = 27013] = "CONDITIONS_OF_USE_NOT_SATISFIED";
|
|
11
|
+
StatusCodes[StatusCodes["INCORRECT_DATA"] = 27264] = "INCORRECT_DATA";
|
|
12
|
+
StatusCodes[StatusCodes["NOT_ENOUGH_MEMORY_SPACE"] = 27268] = "NOT_ENOUGH_MEMORY_SPACE";
|
|
13
|
+
StatusCodes[StatusCodes["REFERENCED_DATA_NOT_FOUND"] = 27272] = "REFERENCED_DATA_NOT_FOUND";
|
|
14
|
+
StatusCodes[StatusCodes["FILE_ALREADY_EXISTS"] = 27273] = "FILE_ALREADY_EXISTS";
|
|
15
|
+
StatusCodes[StatusCodes["INCORRECT_P1_P2"] = 27392] = "INCORRECT_P1_P2";
|
|
16
|
+
StatusCodes[StatusCodes["INS_NOT_SUPPORTED"] = 27904] = "INS_NOT_SUPPORTED";
|
|
17
|
+
StatusCodes[StatusCodes["CLA_NOT_SUPPORTED"] = 28160] = "CLA_NOT_SUPPORTED";
|
|
18
|
+
StatusCodes[StatusCodes["TECHNICAL_PROBLEM"] = 28416] = "TECHNICAL_PROBLEM";
|
|
19
|
+
StatusCodes[StatusCodes["OK"] = 36864] = "OK";
|
|
20
|
+
StatusCodes[StatusCodes["MEMORY_PROBLEM"] = 37440] = "MEMORY_PROBLEM";
|
|
21
|
+
StatusCodes[StatusCodes["NO_EF_SELECTED"] = 37888] = "NO_EF_SELECTED";
|
|
22
|
+
StatusCodes[StatusCodes["INVALID_OFFSET"] = 37890] = "INVALID_OFFSET";
|
|
23
|
+
StatusCodes[StatusCodes["FILE_NOT_FOUND"] = 37892] = "FILE_NOT_FOUND";
|
|
24
|
+
StatusCodes[StatusCodes["INCONSISTENT_FILE"] = 37896] = "INCONSISTENT_FILE";
|
|
25
|
+
StatusCodes[StatusCodes["ALGORITHM_NOT_SUPPORTED"] = 38020] = "ALGORITHM_NOT_SUPPORTED";
|
|
26
|
+
StatusCodes[StatusCodes["INVALID_KCV"] = 38021] = "INVALID_KCV";
|
|
27
|
+
StatusCodes[StatusCodes["CODE_NOT_INITIALIZED"] = 38914] = "CODE_NOT_INITIALIZED";
|
|
28
|
+
StatusCodes[StatusCodes["ACCESS_CONDITION_NOT_FULFILLED"] = 38916] = "ACCESS_CONDITION_NOT_FULFILLED";
|
|
29
|
+
StatusCodes[StatusCodes["CONTRADICTION_SECRET_CODE_STATUS"] = 38920] = "CONTRADICTION_SECRET_CODE_STATUS";
|
|
30
|
+
StatusCodes[StatusCodes["CONTRADICTION_INVALIDATION"] = 38928] = "CONTRADICTION_INVALIDATION";
|
|
31
|
+
StatusCodes[StatusCodes["CODE_BLOCKED"] = 38976] = "CODE_BLOCKED";
|
|
32
|
+
StatusCodes[StatusCodes["MAX_VALUE_REACHED"] = 38992] = "MAX_VALUE_REACHED";
|
|
33
|
+
StatusCodes[StatusCodes["GP_AUTH_FAILED"] = 25344] = "GP_AUTH_FAILED";
|
|
34
|
+
StatusCodes[StatusCodes["LICENSING"] = 28482] = "LICENSING";
|
|
35
|
+
StatusCodes[StatusCodes["HALTED"] = 28586] = "HALTED";
|
|
36
|
+
})(StatusCodes = exports.StatusCodes || (exports.StatusCodes = {}));
|
|
37
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAAA,IAAY,WA+BX;AA/BD,WAAY,WAAW;IACrB,qFAA+B,CAAA;IAC/B,yEAAyB,CAAA;IACzB,+GAA4C,CAAA;IAC5C,mGAAsC,CAAA;IACtC,uGAAwC,CAAA;IACxC,qEAAuB,CAAA;IACvB,uFAAgC,CAAA;IAChC,2FAAkC,CAAA;IAClC,+EAA4B,CAAA;IAC5B,uEAAwB,CAAA;IACxB,2EAA0B,CAAA;IAC1B,2EAA0B,CAAA;IAC1B,2EAA0B,CAAA;IAC1B,6CAAW,CAAA;IACX,qEAAuB,CAAA;IACvB,qEAAuB,CAAA;IACvB,qEAAuB,CAAA;IACvB,qEAAuB,CAAA;IACvB,2EAA0B,CAAA;IAC1B,uFAAgC,CAAA;IAChC,+DAAoB,CAAA;IACpB,iFAA6B,CAAA;IAC7B,qGAAuC,CAAA;IACvC,yGAAyC,CAAA;IACzC,6FAAmC,CAAA;IACnC,iEAAqB,CAAA;IACrB,2EAA0B,CAAA;IAC1B,qEAAuB,CAAA;IACvB,2DAAkB,CAAA;IAClB,qDAAe,CAAA;AACjB,CAAC,EA/BW,WAAW,GAAX,mBAAW,KAAX,mBAAW,QA+BtB"}
|
package/lib/errors.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,gDAAgD;;EAE5D,CAAC"}
|
package/lib/errors.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.VechainAppPleaseEnableContractDataAndMultiClause = void 0;
|
|
4
|
+
const errors_1 = require("@ledgerhq/errors");
|
|
5
|
+
exports.VechainAppPleaseEnableContractDataAndMultiClause = (0, errors_1.createCustomErrorClass)("VechainAppPleaseEnableContractDataAndMultiClause");
|
|
6
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";;;AAAA,6CAA0D;AAE7C,QAAA,gDAAgD,GAAG,IAAA,+BAAsB,EACpF,kDAAkD,CACnD,CAAC"}
|
package/lib/model.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
|
package/lib/model.js
ADDED
package/lib/model.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":""}
|
package/lib/utils.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,eAAO,MAAM,SAAS,SAAU,MAAM,KAAG,MAAM,EAW9C,CAAC;AAEF,eAAO,MAAM,QAAQ,SAAU,MAAM,UAAU,MAAM,iBAAiB,OAAO,KAAG,MAAM,EA8BrF,CAAC"}
|
package/lib/utils.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.splitRaw = exports.splitPath = void 0;
|
|
4
|
+
const buffer_1 = require("buffer");
|
|
5
|
+
const splitPath = (path) => {
|
|
6
|
+
return path
|
|
7
|
+
.split("/")
|
|
8
|
+
.map(elem => {
|
|
9
|
+
let num = parseInt(elem, 10);
|
|
10
|
+
if (elem.length > 1 && elem[elem.length - 1] === "'") {
|
|
11
|
+
num += 0x80000000;
|
|
12
|
+
}
|
|
13
|
+
return num;
|
|
14
|
+
})
|
|
15
|
+
.filter(num => !isNaN(num));
|
|
16
|
+
};
|
|
17
|
+
exports.splitPath = splitPath;
|
|
18
|
+
const splitRaw = (path, rawHex, isTransaction) => {
|
|
19
|
+
const contentByteLength = isTransaction ? 0 : 4;
|
|
20
|
+
const paths = (0, exports.splitPath)(path);
|
|
21
|
+
let offset = 0;
|
|
22
|
+
const raw = buffer_1.Buffer.from(rawHex, "hex");
|
|
23
|
+
const buffers = [];
|
|
24
|
+
while (offset !== raw.length) {
|
|
25
|
+
const maxChunkSize = offset === 0 ? 255 - 1 - paths.length * 4 - contentByteLength : 255;
|
|
26
|
+
const chunkSize = offset + maxChunkSize > raw.length ? raw.length - offset : maxChunkSize;
|
|
27
|
+
const buffer = buffer_1.Buffer.alloc(offset === 0 ? 1 + paths.length * 4 + contentByteLength + chunkSize : chunkSize);
|
|
28
|
+
if (offset === 0) {
|
|
29
|
+
buffer[0] = paths.length;
|
|
30
|
+
paths.forEach((element, index) => {
|
|
31
|
+
buffer.writeUInt32BE(element, 1 + 4 * index);
|
|
32
|
+
});
|
|
33
|
+
if (isTransaction) {
|
|
34
|
+
raw.copy(buffer, 1 + 4 * paths.length, offset, offset + chunkSize);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
buffer.writeUInt32BE(raw.length, 1 + 4 * paths.length);
|
|
38
|
+
raw.copy(buffer, 1 + 4 * paths.length + 4, offset, offset + chunkSize);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
raw.copy(buffer, 0, offset, offset + chunkSize);
|
|
43
|
+
}
|
|
44
|
+
buffers.push(buffer);
|
|
45
|
+
offset += chunkSize;
|
|
46
|
+
}
|
|
47
|
+
return buffers;
|
|
48
|
+
};
|
|
49
|
+
exports.splitRaw = splitRaw;
|
|
50
|
+
//# sourceMappingURL=utils.js.map
|
package/lib/utils.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
|
package/lib-es/Vet.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import type Transport from "@ledgerhq/hw-transport";
|
|
3
|
+
import { StatusCodes } from "./constants";
|
|
4
|
+
import { Buffer } from "buffer";
|
|
5
|
+
/**
|
|
6
|
+
* VeChain API
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* import Vet from "@ledgerhq/hw-app-vet";
|
|
10
|
+
* const vet = new Vet(transport)
|
|
11
|
+
*/
|
|
12
|
+
export default class Vet {
|
|
13
|
+
transport: Transport;
|
|
14
|
+
constructor(transport: Transport, scrambleKey?: string);
|
|
15
|
+
getAppConfiguration(): Promise<any>;
|
|
16
|
+
/**
|
|
17
|
+
* get VeChain address for a given BIP 32 path.
|
|
18
|
+
* @param path a path in BIP 32 format
|
|
19
|
+
* @option display
|
|
20
|
+
* @option chainCode
|
|
21
|
+
* @return an object with a publicKey and address
|
|
22
|
+
* @example
|
|
23
|
+
* vet.getAddress("m/44'/818'/0'/0").then(o => o.address)
|
|
24
|
+
*/
|
|
25
|
+
getAddress(path: string, display?: boolean, chainCode?: boolean, statusCodes?: StatusCodes[]): Promise<{
|
|
26
|
+
publicKey: string;
|
|
27
|
+
address: string;
|
|
28
|
+
chainCode?: string;
|
|
29
|
+
}>;
|
|
30
|
+
/**
|
|
31
|
+
* You can sign a transaction and retrieve v, r, s given the raw transaction and the BIP 32 path of the account to sign.
|
|
32
|
+
*
|
|
33
|
+
* @param path: the BIP32 path to sign the transaction on
|
|
34
|
+
* @param rawTxHex: the raw vechain transaction in hexadecimal to sign
|
|
35
|
+
*/
|
|
36
|
+
signTransaction(path: string, rawTxHex: string): Promise<Buffer>;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=Vet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Vet.d.ts","sourceRoot":"","sources":["../src/Vet.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,SAAS,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1C,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAchC;;;;;;GAMG;AAEH,MAAM,CAAC,OAAO,OAAO,GAAG;IACtB,SAAS,EAAE,SAAS,CAAC;gBAET,SAAS,EAAE,SAAS,EAAE,WAAW,SAAQ;IAS/C,mBAAmB,IAAI,OAAO,CAAC,GAAG,CAAC;IAQzC;;;;;;;;OAQG;IACG,UAAU,CACd,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,OAAO,EACjB,SAAS,CAAC,EAAE,OAAO,EACnB,WAAW,GAAE,WAAW,EAAqB,GAC5C,OAAO,CAAC;QACT,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IAsCF;;;;;OAKG;IACG,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAsBvE"}
|
package/lib-es/Vet.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { StatusCodes } from "./constants";
|
|
11
|
+
import { splitPath, splitRaw } from "./utils";
|
|
12
|
+
import { Buffer } from "buffer";
|
|
13
|
+
import { VechainAppPleaseEnableContractDataAndMultiClause } from "./errors";
|
|
14
|
+
const remapTransactionRelatedErrors = e => {
|
|
15
|
+
if (e && e.statusCode === 0x6a80) {
|
|
16
|
+
return new VechainAppPleaseEnableContractDataAndMultiClause("Please enable contract data in Vechain app settings");
|
|
17
|
+
}
|
|
18
|
+
return e;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* VeChain API
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* import Vet from "@ledgerhq/hw-app-vet";
|
|
25
|
+
* const vet = new Vet(transport)
|
|
26
|
+
*/
|
|
27
|
+
export default class Vet {
|
|
28
|
+
constructor(transport, scrambleKey = "V3T") {
|
|
29
|
+
this.transport = transport;
|
|
30
|
+
transport.decorateAppAPIMethods(this, ["getAppConfiguration", "getAddress", "signTransaction"], scrambleKey);
|
|
31
|
+
}
|
|
32
|
+
getAppConfiguration() {
|
|
33
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
34
|
+
const response = yield this.transport.send(0xe0, 0x06, 0x00, 0x00, Buffer.alloc(0), [
|
|
35
|
+
StatusCodes.OK,
|
|
36
|
+
]);
|
|
37
|
+
return response.slice(0, 4);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* get VeChain address for a given BIP 32 path.
|
|
42
|
+
* @param path a path in BIP 32 format
|
|
43
|
+
* @option display
|
|
44
|
+
* @option chainCode
|
|
45
|
+
* @return an object with a publicKey and address
|
|
46
|
+
* @example
|
|
47
|
+
* vet.getAddress("m/44'/818'/0'/0").then(o => o.address)
|
|
48
|
+
*/
|
|
49
|
+
getAddress(path, display, chainCode, statusCodes = [StatusCodes.OK]) {
|
|
50
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
51
|
+
const paths = splitPath(path);
|
|
52
|
+
const buffer = Buffer.alloc(1 + paths.length * 4);
|
|
53
|
+
buffer[0] = paths.length;
|
|
54
|
+
paths.forEach((element, index) => {
|
|
55
|
+
buffer.writeUInt32BE(element, 1 + 4 * index);
|
|
56
|
+
});
|
|
57
|
+
const response = yield this.transport.send(0xe0, 0x02, display ? 0x01 : 0x00, chainCode ? 0x01 : 0x00, buffer, statusCodes);
|
|
58
|
+
const publicKeyLength = response[0];
|
|
59
|
+
const addressLength = response[1 + publicKeyLength];
|
|
60
|
+
const acc = {
|
|
61
|
+
publicKey: response.slice(1, 1 + publicKeyLength).toString("hex"),
|
|
62
|
+
address: "0x" +
|
|
63
|
+
response
|
|
64
|
+
.slice(1 + publicKeyLength + 1, 1 + publicKeyLength + 1 + addressLength)
|
|
65
|
+
.toString("ascii")
|
|
66
|
+
.toLowerCase(),
|
|
67
|
+
};
|
|
68
|
+
if (chainCode) {
|
|
69
|
+
acc.chainCode = response
|
|
70
|
+
.slice(1 + publicKeyLength + 1 + addressLength, 1 + publicKeyLength + 1 + addressLength + 32)
|
|
71
|
+
.toString("hex");
|
|
72
|
+
}
|
|
73
|
+
return acc;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* You can sign a transaction and retrieve v, r, s given the raw transaction and the BIP 32 path of the account to sign.
|
|
78
|
+
*
|
|
79
|
+
* @param path: the BIP32 path to sign the transaction on
|
|
80
|
+
* @param rawTxHex: the raw vechain transaction in hexadecimal to sign
|
|
81
|
+
*/
|
|
82
|
+
signTransaction(path, rawTxHex) {
|
|
83
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
84
|
+
const buffers = splitRaw(path, rawTxHex, true);
|
|
85
|
+
const responses = [];
|
|
86
|
+
for (let i = 0; i < buffers.length; i++) {
|
|
87
|
+
const data = buffers[i];
|
|
88
|
+
responses.push(yield this.transport
|
|
89
|
+
.send(0xe0, 0x04, i === 0 ? 0x00 : 0x80, 0x00, data, [StatusCodes.OK])
|
|
90
|
+
.catch(e => {
|
|
91
|
+
throw remapTransactionRelatedErrors(e);
|
|
92
|
+
}));
|
|
93
|
+
}
|
|
94
|
+
const lastResponse = responses[responses.length - 1];
|
|
95
|
+
if (lastResponse.length < 65) {
|
|
96
|
+
throw new Error("invalid signature");
|
|
97
|
+
}
|
|
98
|
+
return lastResponse.slice(0, 65);
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=Vet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Vet.js","sourceRoot":"","sources":["../src/Vet.ts"],"names":[],"mappings":";;;;;;;;;AACA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,gDAAgD,EAAE,MAAM,UAAU,CAAC;AAE5E,MAAM,6BAA6B,GAAG,CAAC,CAAC,EAAE;IACxC,IAAI,CAAC,IAAI,CAAC,CAAC,UAAU,KAAK,MAAM,EAAE;QAChC,OAAO,IAAI,gDAAgD,CACzD,qDAAqD,CACtD,CAAC;KACH;IAED,OAAO,CAAC,CAAC;AACX,CAAC,CAAC;AAEF;;;;;;GAMG;AAEH,MAAM,CAAC,OAAO,OAAO,GAAG;IAGtB,YAAY,SAAoB,EAAE,WAAW,GAAG,KAAK;QACnD,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,SAAS,CAAC,qBAAqB,CAC7B,IAAI,EACJ,CAAC,qBAAqB,EAAE,YAAY,EAAE,iBAAiB,CAAC,EACxD,WAAW,CACZ,CAAC;IACJ,CAAC;IAEK,mBAAmB;;YACvB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;gBAClF,WAAW,CAAC,EAAE;aACf,CAAC,CAAC;YAEH,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9B,CAAC;KAAA;IAED;;;;;;;;OAQG;IACG,UAAU,CACd,IAAY,EACZ,OAAiB,EACjB,SAAmB,EACnB,cAA6B,CAAC,WAAW,CAAC,EAAE,CAAC;;YAM7C,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;YAC9B,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAClD,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC;YACzB,KAAK,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE;gBAC/B,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;YAC/C,CAAC,CAAC,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CACxC,IAAI,EACJ,IAAI,EACJ,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EACrB,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EACvB,MAAM,EACN,WAAW,CACZ,CAAC;YAEF,MAAM,eAAe,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YACpC,MAAM,aAAa,GAAG,QAAQ,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC;YACpD,MAAM,GAAG,GAAqB;gBAC5B,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,eAAe,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;gBACjE,OAAO,EACL,IAAI;oBACJ,QAAQ;yBACL,KAAK,CAAC,CAAC,GAAG,eAAe,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,GAAG,CAAC,GAAG,aAAa,CAAC;yBACvE,QAAQ,CAAC,OAAO,CAAC;yBACjB,WAAW,EAAE;aACnB,CAAC;YACF,IAAI,SAAS,EAAE;gBACb,GAAG,CAAC,SAAS,GAAG,QAAQ;qBACrB,KAAK,CACJ,CAAC,GAAG,eAAe,GAAG,CAAC,GAAG,aAAa,EACvC,CAAC,GAAG,eAAe,GAAG,CAAC,GAAG,aAAa,GAAG,EAAE,CAC7C;qBACA,QAAQ,CAAC,KAAK,CAAC,CAAC;aACpB;YACD,OAAO,GAAG,CAAC;QACb,CAAC;KAAA;IAED;;;;;OAKG;IACG,eAAe,CAAC,IAAY,EAAE,QAAgB;;YAClD,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;YAC/C,MAAM,SAAS,GAAG,EAAc,CAAC;YAEjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;gBACvC,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;gBACxB,SAAS,CAAC,IAAI,CACZ,MAAM,IAAI,CAAC,SAAS;qBACjB,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;qBACrE,KAAK,CAAC,CAAC,CAAC,EAAE;oBACT,MAAM,6BAA6B,CAAC,CAAC,CAAC,CAAC;gBACzC,CAAC,CAAC,CACL,CAAC;aACH;YAED,MAAM,YAAY,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACrD,IAAI,YAAY,CAAC,MAAM,GAAG,EAAE,EAAE;gBAC5B,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;aACtC;YAED,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACnC,CAAC;KAAA;CACF"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export declare enum StatusCodes {
|
|
2
|
+
PIN_REMAINING_ATTEMPTS = 25536,
|
|
3
|
+
INCORRECT_LENGTH = 26368,
|
|
4
|
+
COMMAND_INCOMPATIBLE_FILE_STRUCTURE = 27009,
|
|
5
|
+
SECURITY_STATUS_NOT_SATISFIED = 27010,
|
|
6
|
+
CONDITIONS_OF_USE_NOT_SATISFIED = 27013,
|
|
7
|
+
INCORRECT_DATA = 27264,
|
|
8
|
+
NOT_ENOUGH_MEMORY_SPACE = 27268,
|
|
9
|
+
REFERENCED_DATA_NOT_FOUND = 27272,
|
|
10
|
+
FILE_ALREADY_EXISTS = 27273,
|
|
11
|
+
INCORRECT_P1_P2 = 27392,
|
|
12
|
+
INS_NOT_SUPPORTED = 27904,
|
|
13
|
+
CLA_NOT_SUPPORTED = 28160,
|
|
14
|
+
TECHNICAL_PROBLEM = 28416,
|
|
15
|
+
OK = 36864,
|
|
16
|
+
MEMORY_PROBLEM = 37440,
|
|
17
|
+
NO_EF_SELECTED = 37888,
|
|
18
|
+
INVALID_OFFSET = 37890,
|
|
19
|
+
FILE_NOT_FOUND = 37892,
|
|
20
|
+
INCONSISTENT_FILE = 37896,
|
|
21
|
+
ALGORITHM_NOT_SUPPORTED = 38020,
|
|
22
|
+
INVALID_KCV = 38021,
|
|
23
|
+
CODE_NOT_INITIALIZED = 38914,
|
|
24
|
+
ACCESS_CONDITION_NOT_FULFILLED = 38916,
|
|
25
|
+
CONTRADICTION_SECRET_CODE_STATUS = 38920,
|
|
26
|
+
CONTRADICTION_INVALIDATION = 38928,
|
|
27
|
+
CODE_BLOCKED = 38976,
|
|
28
|
+
MAX_VALUE_REACHED = 38992,
|
|
29
|
+
GP_AUTH_FAILED = 25344,
|
|
30
|
+
LICENSING = 28482,
|
|
31
|
+
HALTED = 28586
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,oBAAY,WAAW;IACrB,sBAAsB,QAAS;IAC/B,gBAAgB,QAAS;IACzB,mCAAmC,QAAS;IAC5C,6BAA6B,QAAS;IACtC,+BAA+B,QAAS;IACxC,cAAc,QAAS;IACvB,uBAAuB,QAAS;IAChC,yBAAyB,QAAS;IAClC,mBAAmB,QAAS;IAC5B,eAAe,QAAS;IACxB,iBAAiB,QAAS;IAC1B,iBAAiB,QAAS;IAC1B,iBAAiB,QAAS;IAC1B,EAAE,QAAS;IACX,cAAc,QAAS;IACvB,cAAc,QAAS;IACvB,cAAc,QAAS;IACvB,cAAc,QAAS;IACvB,iBAAiB,QAAS;IAC1B,uBAAuB,QAAS;IAChC,WAAW,QAAS;IACpB,oBAAoB,QAAS;IAC7B,8BAA8B,QAAS;IACvC,gCAAgC,QAAS;IACzC,0BAA0B,QAAS;IACnC,YAAY,QAAS;IACrB,iBAAiB,QAAS;IAC1B,cAAc,QAAS;IACvB,SAAS,QAAS;IAClB,MAAM,QAAS;CAChB"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export var StatusCodes;
|
|
2
|
+
(function (StatusCodes) {
|
|
3
|
+
StatusCodes[StatusCodes["PIN_REMAINING_ATTEMPTS"] = 25536] = "PIN_REMAINING_ATTEMPTS";
|
|
4
|
+
StatusCodes[StatusCodes["INCORRECT_LENGTH"] = 26368] = "INCORRECT_LENGTH";
|
|
5
|
+
StatusCodes[StatusCodes["COMMAND_INCOMPATIBLE_FILE_STRUCTURE"] = 27009] = "COMMAND_INCOMPATIBLE_FILE_STRUCTURE";
|
|
6
|
+
StatusCodes[StatusCodes["SECURITY_STATUS_NOT_SATISFIED"] = 27010] = "SECURITY_STATUS_NOT_SATISFIED";
|
|
7
|
+
StatusCodes[StatusCodes["CONDITIONS_OF_USE_NOT_SATISFIED"] = 27013] = "CONDITIONS_OF_USE_NOT_SATISFIED";
|
|
8
|
+
StatusCodes[StatusCodes["INCORRECT_DATA"] = 27264] = "INCORRECT_DATA";
|
|
9
|
+
StatusCodes[StatusCodes["NOT_ENOUGH_MEMORY_SPACE"] = 27268] = "NOT_ENOUGH_MEMORY_SPACE";
|
|
10
|
+
StatusCodes[StatusCodes["REFERENCED_DATA_NOT_FOUND"] = 27272] = "REFERENCED_DATA_NOT_FOUND";
|
|
11
|
+
StatusCodes[StatusCodes["FILE_ALREADY_EXISTS"] = 27273] = "FILE_ALREADY_EXISTS";
|
|
12
|
+
StatusCodes[StatusCodes["INCORRECT_P1_P2"] = 27392] = "INCORRECT_P1_P2";
|
|
13
|
+
StatusCodes[StatusCodes["INS_NOT_SUPPORTED"] = 27904] = "INS_NOT_SUPPORTED";
|
|
14
|
+
StatusCodes[StatusCodes["CLA_NOT_SUPPORTED"] = 28160] = "CLA_NOT_SUPPORTED";
|
|
15
|
+
StatusCodes[StatusCodes["TECHNICAL_PROBLEM"] = 28416] = "TECHNICAL_PROBLEM";
|
|
16
|
+
StatusCodes[StatusCodes["OK"] = 36864] = "OK";
|
|
17
|
+
StatusCodes[StatusCodes["MEMORY_PROBLEM"] = 37440] = "MEMORY_PROBLEM";
|
|
18
|
+
StatusCodes[StatusCodes["NO_EF_SELECTED"] = 37888] = "NO_EF_SELECTED";
|
|
19
|
+
StatusCodes[StatusCodes["INVALID_OFFSET"] = 37890] = "INVALID_OFFSET";
|
|
20
|
+
StatusCodes[StatusCodes["FILE_NOT_FOUND"] = 37892] = "FILE_NOT_FOUND";
|
|
21
|
+
StatusCodes[StatusCodes["INCONSISTENT_FILE"] = 37896] = "INCONSISTENT_FILE";
|
|
22
|
+
StatusCodes[StatusCodes["ALGORITHM_NOT_SUPPORTED"] = 38020] = "ALGORITHM_NOT_SUPPORTED";
|
|
23
|
+
StatusCodes[StatusCodes["INVALID_KCV"] = 38021] = "INVALID_KCV";
|
|
24
|
+
StatusCodes[StatusCodes["CODE_NOT_INITIALIZED"] = 38914] = "CODE_NOT_INITIALIZED";
|
|
25
|
+
StatusCodes[StatusCodes["ACCESS_CONDITION_NOT_FULFILLED"] = 38916] = "ACCESS_CONDITION_NOT_FULFILLED";
|
|
26
|
+
StatusCodes[StatusCodes["CONTRADICTION_SECRET_CODE_STATUS"] = 38920] = "CONTRADICTION_SECRET_CODE_STATUS";
|
|
27
|
+
StatusCodes[StatusCodes["CONTRADICTION_INVALIDATION"] = 38928] = "CONTRADICTION_INVALIDATION";
|
|
28
|
+
StatusCodes[StatusCodes["CODE_BLOCKED"] = 38976] = "CODE_BLOCKED";
|
|
29
|
+
StatusCodes[StatusCodes["MAX_VALUE_REACHED"] = 38992] = "MAX_VALUE_REACHED";
|
|
30
|
+
StatusCodes[StatusCodes["GP_AUTH_FAILED"] = 25344] = "GP_AUTH_FAILED";
|
|
31
|
+
StatusCodes[StatusCodes["LICENSING"] = 28482] = "LICENSING";
|
|
32
|
+
StatusCodes[StatusCodes["HALTED"] = 28586] = "HALTED";
|
|
33
|
+
})(StatusCodes || (StatusCodes = {}));
|
|
34
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,WA+BX;AA/BD,WAAY,WAAW;IACrB,qFAA+B,CAAA;IAC/B,yEAAyB,CAAA;IACzB,+GAA4C,CAAA;IAC5C,mGAAsC,CAAA;IACtC,uGAAwC,CAAA;IACxC,qEAAuB,CAAA;IACvB,uFAAgC,CAAA;IAChC,2FAAkC,CAAA;IAClC,+EAA4B,CAAA;IAC5B,uEAAwB,CAAA;IACxB,2EAA0B,CAAA;IAC1B,2EAA0B,CAAA;IAC1B,2EAA0B,CAAA;IAC1B,6CAAW,CAAA;IACX,qEAAuB,CAAA;IACvB,qEAAuB,CAAA;IACvB,qEAAuB,CAAA;IACvB,qEAAuB,CAAA;IACvB,2EAA0B,CAAA;IAC1B,uFAAgC,CAAA;IAChC,+DAAoB,CAAA;IACpB,iFAA6B,CAAA;IAC7B,qGAAuC,CAAA;IACvC,yGAAyC,CAAA;IACzC,6FAAmC,CAAA;IACnC,iEAAqB,CAAA;IACrB,2EAA0B,CAAA;IAC1B,qEAAuB,CAAA;IACvB,2DAAkB,CAAA;IAClB,qDAAe,CAAA;AACjB,CAAC,EA/BW,WAAW,KAAX,WAAW,QA+BtB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,gDAAgD;;EAE5D,CAAC"}
|
package/lib-es/errors.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,MAAM,CAAC,MAAM,gDAAgD,GAAG,sBAAsB,CACpF,kDAAkD,CACnD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
|
package/lib-es/model.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,eAAO,MAAM,SAAS,SAAU,MAAM,KAAG,MAAM,EAW9C,CAAC;AAEF,eAAO,MAAM,QAAQ,SAAU,MAAM,UAAU,MAAM,iBAAiB,OAAO,KAAG,MAAM,EA8BrF,CAAC"}
|
package/lib-es/utils.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Buffer } from "buffer";
|
|
2
|
+
export const splitPath = (path) => {
|
|
3
|
+
return path
|
|
4
|
+
.split("/")
|
|
5
|
+
.map(elem => {
|
|
6
|
+
let num = parseInt(elem, 10);
|
|
7
|
+
if (elem.length > 1 && elem[elem.length - 1] === "'") {
|
|
8
|
+
num += 0x80000000;
|
|
9
|
+
}
|
|
10
|
+
return num;
|
|
11
|
+
})
|
|
12
|
+
.filter(num => !isNaN(num));
|
|
13
|
+
};
|
|
14
|
+
export const splitRaw = (path, rawHex, isTransaction) => {
|
|
15
|
+
const contentByteLength = isTransaction ? 0 : 4;
|
|
16
|
+
const paths = splitPath(path);
|
|
17
|
+
let offset = 0;
|
|
18
|
+
const raw = Buffer.from(rawHex, "hex");
|
|
19
|
+
const buffers = [];
|
|
20
|
+
while (offset !== raw.length) {
|
|
21
|
+
const maxChunkSize = offset === 0 ? 255 - 1 - paths.length * 4 - contentByteLength : 255;
|
|
22
|
+
const chunkSize = offset + maxChunkSize > raw.length ? raw.length - offset : maxChunkSize;
|
|
23
|
+
const buffer = Buffer.alloc(offset === 0 ? 1 + paths.length * 4 + contentByteLength + chunkSize : chunkSize);
|
|
24
|
+
if (offset === 0) {
|
|
25
|
+
buffer[0] = paths.length;
|
|
26
|
+
paths.forEach((element, index) => {
|
|
27
|
+
buffer.writeUInt32BE(element, 1 + 4 * index);
|
|
28
|
+
});
|
|
29
|
+
if (isTransaction) {
|
|
30
|
+
raw.copy(buffer, 1 + 4 * paths.length, offset, offset + chunkSize);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
buffer.writeUInt32BE(raw.length, 1 + 4 * paths.length);
|
|
34
|
+
raw.copy(buffer, 1 + 4 * paths.length + 4, offset, offset + chunkSize);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
raw.copy(buffer, 0, offset, offset + chunkSize);
|
|
39
|
+
}
|
|
40
|
+
buffers.push(buffer);
|
|
41
|
+
offset += chunkSize;
|
|
42
|
+
}
|
|
43
|
+
return buffers;
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ledgerhq/hw-app-vet",
|
|
3
|
+
"version": "0.1.0-nightly.0",
|
|
4
|
+
"description": "Ledger Hardware Wallet VeChain Application API",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"Ledger",
|
|
7
|
+
"LedgerWallet",
|
|
8
|
+
"VeChain",
|
|
9
|
+
"vet",
|
|
10
|
+
"vtho",
|
|
11
|
+
"VeThor",
|
|
12
|
+
"NanoS",
|
|
13
|
+
"Hardware Wallet"
|
|
14
|
+
],
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/LedgerHQ/ledger-live.git"
|
|
18
|
+
},
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/LedgerHQ/ledger-live/issues"
|
|
21
|
+
},
|
|
22
|
+
"homepage": "https://github.com/LedgerHQ/ledger-live/tree/develop/libs/ledgerjs/packages/hw-app-vet",
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"main": "lib/Vet.js",
|
|
27
|
+
"module": "lib-es/Vet.js",
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"thor-devkit": "^2.0.6",
|
|
30
|
+
"@ledgerhq/cryptoassets": "^11.2.0-nightly.2",
|
|
31
|
+
"@ledgerhq/errors": "^6.16.0-nightly.2",
|
|
32
|
+
"@ledgerhq/hw-transport": "^6.30.0-nightly.2",
|
|
33
|
+
"@ledgerhq/hw-transport-mocker": "^6.28.0-nightly.2",
|
|
34
|
+
"@ledgerhq/logs": "^6.12.0-nightly.0"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/jest": "^29.5.0",
|
|
38
|
+
"@types/node": "^18.15.3",
|
|
39
|
+
"documentation": "14.0.2",
|
|
40
|
+
"jest": "^28.1.1",
|
|
41
|
+
"source-map-support": "^0.5.21",
|
|
42
|
+
"ts-jest": "^28.0.5",
|
|
43
|
+
"ts-node": "^10.4.0",
|
|
44
|
+
"typescript": "^4",
|
|
45
|
+
"@ledgerhq/hw-transport-mocker": "^6.28.0-nightly.2"
|
|
46
|
+
},
|
|
47
|
+
"gitHead": "dd0dea64b58e5a9125c8a422dcffd29e5ef6abec",
|
|
48
|
+
"scripts": {
|
|
49
|
+
"clean": "rimraf lib lib-es",
|
|
50
|
+
"build": "tsc && tsc -m ES6 --outDir lib-es",
|
|
51
|
+
"prewatch": "pnpm build",
|
|
52
|
+
"watch": "tsc --watch",
|
|
53
|
+
"doc": "documentation readme src/** --section=API --pe ts --re ts --re d.ts",
|
|
54
|
+
"lint": "eslint ./src --no-error-on-unmatched-pattern --ext .ts,.tsx",
|
|
55
|
+
"lint:fix": "pnpm lint --fix",
|
|
56
|
+
"test": "jest"
|
|
57
|
+
}
|
|
58
|
+
}
|
package/src/Vet.ts
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import type Transport from "@ledgerhq/hw-transport";
|
|
2
|
+
import { StatusCodes } from "./constants";
|
|
3
|
+
import { VETLedgerAccount } from "./model";
|
|
4
|
+
import { splitPath, splitRaw } from "./utils";
|
|
5
|
+
import { Buffer } from "buffer";
|
|
6
|
+
|
|
7
|
+
import { VechainAppPleaseEnableContractDataAndMultiClause } from "./errors";
|
|
8
|
+
|
|
9
|
+
const remapTransactionRelatedErrors = e => {
|
|
10
|
+
if (e && e.statusCode === 0x6a80) {
|
|
11
|
+
return new VechainAppPleaseEnableContractDataAndMultiClause(
|
|
12
|
+
"Please enable contract data in Vechain app settings",
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return e;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* VeChain API
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* import Vet from "@ledgerhq/hw-app-vet";
|
|
24
|
+
* const vet = new Vet(transport)
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
export default class Vet {
|
|
28
|
+
transport: Transport;
|
|
29
|
+
|
|
30
|
+
constructor(transport: Transport, scrambleKey = "V3T") {
|
|
31
|
+
this.transport = transport;
|
|
32
|
+
transport.decorateAppAPIMethods(
|
|
33
|
+
this,
|
|
34
|
+
["getAppConfiguration", "getAddress", "signTransaction"],
|
|
35
|
+
scrambleKey,
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async getAppConfiguration(): Promise<any> {
|
|
40
|
+
const response = await this.transport.send(0xe0, 0x06, 0x00, 0x00, Buffer.alloc(0), [
|
|
41
|
+
StatusCodes.OK,
|
|
42
|
+
]);
|
|
43
|
+
|
|
44
|
+
return response.slice(0, 4);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* get VeChain address for a given BIP 32 path.
|
|
49
|
+
* @param path a path in BIP 32 format
|
|
50
|
+
* @option display
|
|
51
|
+
* @option chainCode
|
|
52
|
+
* @return an object with a publicKey and address
|
|
53
|
+
* @example
|
|
54
|
+
* vet.getAddress("m/44'/818'/0'/0").then(o => o.address)
|
|
55
|
+
*/
|
|
56
|
+
async getAddress(
|
|
57
|
+
path: string,
|
|
58
|
+
display?: boolean,
|
|
59
|
+
chainCode?: boolean,
|
|
60
|
+
statusCodes: StatusCodes[] = [StatusCodes.OK],
|
|
61
|
+
): Promise<{
|
|
62
|
+
publicKey: string;
|
|
63
|
+
address: string;
|
|
64
|
+
chainCode?: string;
|
|
65
|
+
}> {
|
|
66
|
+
const paths = splitPath(path);
|
|
67
|
+
const buffer = Buffer.alloc(1 + paths.length * 4);
|
|
68
|
+
buffer[0] = paths.length;
|
|
69
|
+
paths.forEach((element, index) => {
|
|
70
|
+
buffer.writeUInt32BE(element, 1 + 4 * index);
|
|
71
|
+
});
|
|
72
|
+
const response = await this.transport.send(
|
|
73
|
+
0xe0,
|
|
74
|
+
0x02,
|
|
75
|
+
display ? 0x01 : 0x00,
|
|
76
|
+
chainCode ? 0x01 : 0x00,
|
|
77
|
+
buffer,
|
|
78
|
+
statusCodes,
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
const publicKeyLength = response[0];
|
|
82
|
+
const addressLength = response[1 + publicKeyLength];
|
|
83
|
+
const acc: VETLedgerAccount = {
|
|
84
|
+
publicKey: response.slice(1, 1 + publicKeyLength).toString("hex"),
|
|
85
|
+
address:
|
|
86
|
+
"0x" +
|
|
87
|
+
response
|
|
88
|
+
.slice(1 + publicKeyLength + 1, 1 + publicKeyLength + 1 + addressLength)
|
|
89
|
+
.toString("ascii")
|
|
90
|
+
.toLowerCase(),
|
|
91
|
+
};
|
|
92
|
+
if (chainCode) {
|
|
93
|
+
acc.chainCode = response
|
|
94
|
+
.slice(
|
|
95
|
+
1 + publicKeyLength + 1 + addressLength,
|
|
96
|
+
1 + publicKeyLength + 1 + addressLength + 32,
|
|
97
|
+
)
|
|
98
|
+
.toString("hex");
|
|
99
|
+
}
|
|
100
|
+
return acc;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* You can sign a transaction and retrieve v, r, s given the raw transaction and the BIP 32 path of the account to sign.
|
|
105
|
+
*
|
|
106
|
+
* @param path: the BIP32 path to sign the transaction on
|
|
107
|
+
* @param rawTxHex: the raw vechain transaction in hexadecimal to sign
|
|
108
|
+
*/
|
|
109
|
+
async signTransaction(path: string, rawTxHex: string): Promise<Buffer> {
|
|
110
|
+
const buffers = splitRaw(path, rawTxHex, true);
|
|
111
|
+
const responses = [] as Buffer[];
|
|
112
|
+
|
|
113
|
+
for (let i = 0; i < buffers.length; i++) {
|
|
114
|
+
const data = buffers[i];
|
|
115
|
+
responses.push(
|
|
116
|
+
await this.transport
|
|
117
|
+
.send(0xe0, 0x04, i === 0 ? 0x00 : 0x80, 0x00, data, [StatusCodes.OK])
|
|
118
|
+
.catch(e => {
|
|
119
|
+
throw remapTransactionRelatedErrors(e);
|
|
120
|
+
}),
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const lastResponse = responses[responses.length - 1];
|
|
125
|
+
if (lastResponse.length < 65) {
|
|
126
|
+
throw new Error("invalid signature");
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return lastResponse.slice(0, 65);
|
|
130
|
+
}
|
|
131
|
+
}
|
package/src/constants.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export enum StatusCodes {
|
|
2
|
+
PIN_REMAINING_ATTEMPTS = 0x63c0,
|
|
3
|
+
INCORRECT_LENGTH = 0x6700,
|
|
4
|
+
COMMAND_INCOMPATIBLE_FILE_STRUCTURE = 0x6981,
|
|
5
|
+
SECURITY_STATUS_NOT_SATISFIED = 0x6982,
|
|
6
|
+
CONDITIONS_OF_USE_NOT_SATISFIED = 0x6985,
|
|
7
|
+
INCORRECT_DATA = 0x6a80,
|
|
8
|
+
NOT_ENOUGH_MEMORY_SPACE = 0x6a84,
|
|
9
|
+
REFERENCED_DATA_NOT_FOUND = 0x6a88,
|
|
10
|
+
FILE_ALREADY_EXISTS = 0x6a89,
|
|
11
|
+
INCORRECT_P1_P2 = 0x6b00,
|
|
12
|
+
INS_NOT_SUPPORTED = 0x6d00,
|
|
13
|
+
CLA_NOT_SUPPORTED = 0x6e00,
|
|
14
|
+
TECHNICAL_PROBLEM = 0x6f00,
|
|
15
|
+
OK = 0x9000,
|
|
16
|
+
MEMORY_PROBLEM = 0x9240,
|
|
17
|
+
NO_EF_SELECTED = 0x9400,
|
|
18
|
+
INVALID_OFFSET = 0x9402,
|
|
19
|
+
FILE_NOT_FOUND = 0x9404,
|
|
20
|
+
INCONSISTENT_FILE = 0x9408,
|
|
21
|
+
ALGORITHM_NOT_SUPPORTED = 0x9484,
|
|
22
|
+
INVALID_KCV = 0x9485,
|
|
23
|
+
CODE_NOT_INITIALIZED = 0x9802,
|
|
24
|
+
ACCESS_CONDITION_NOT_FULFILLED = 0x9804,
|
|
25
|
+
CONTRADICTION_SECRET_CODE_STATUS = 0x9808,
|
|
26
|
+
CONTRADICTION_INVALIDATION = 0x9810,
|
|
27
|
+
CODE_BLOCKED = 0x9840,
|
|
28
|
+
MAX_VALUE_REACHED = 0x9850,
|
|
29
|
+
GP_AUTH_FAILED = 0x6300,
|
|
30
|
+
LICENSING = 0x6f42,
|
|
31
|
+
HALTED = 0x6faa,
|
|
32
|
+
}
|
package/src/errors.ts
ADDED
package/src/model.ts
ADDED
package/src/utils.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Buffer } from "buffer";
|
|
2
|
+
|
|
3
|
+
export const splitPath = (path: string): number[] => {
|
|
4
|
+
return path
|
|
5
|
+
.split("/")
|
|
6
|
+
.map(elem => {
|
|
7
|
+
let num = parseInt(elem, 10);
|
|
8
|
+
if (elem.length > 1 && elem[elem.length - 1] === "'") {
|
|
9
|
+
num += 0x80000000;
|
|
10
|
+
}
|
|
11
|
+
return num;
|
|
12
|
+
})
|
|
13
|
+
.filter(num => !isNaN(num));
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const splitRaw = (path: string, rawHex: string, isTransaction: boolean): Buffer[] => {
|
|
17
|
+
const contentByteLength = isTransaction ? 0 : 4;
|
|
18
|
+
const paths = splitPath(path);
|
|
19
|
+
let offset = 0;
|
|
20
|
+
const raw = Buffer.from(rawHex, "hex");
|
|
21
|
+
const buffers: Buffer[] = [];
|
|
22
|
+
while (offset !== raw.length) {
|
|
23
|
+
const maxChunkSize = offset === 0 ? 255 - 1 - paths.length * 4 - contentByteLength : 255;
|
|
24
|
+
const chunkSize = offset + maxChunkSize > raw.length ? raw.length - offset : maxChunkSize;
|
|
25
|
+
const buffer = Buffer.alloc(
|
|
26
|
+
offset === 0 ? 1 + paths.length * 4 + contentByteLength + chunkSize : chunkSize,
|
|
27
|
+
);
|
|
28
|
+
if (offset === 0) {
|
|
29
|
+
buffer[0] = paths.length;
|
|
30
|
+
paths.forEach((element, index) => {
|
|
31
|
+
buffer.writeUInt32BE(element, 1 + 4 * index);
|
|
32
|
+
});
|
|
33
|
+
if (isTransaction) {
|
|
34
|
+
raw.copy(buffer, 1 + 4 * paths.length, offset, offset + chunkSize);
|
|
35
|
+
} else {
|
|
36
|
+
buffer.writeUInt32BE(raw.length, 1 + 4 * paths.length);
|
|
37
|
+
raw.copy(buffer, 1 + 4 * paths.length + 4, offset, offset + chunkSize);
|
|
38
|
+
}
|
|
39
|
+
} else {
|
|
40
|
+
raw.copy(buffer, 0, offset, offset + chunkSize);
|
|
41
|
+
}
|
|
42
|
+
buffers.push(buffer);
|
|
43
|
+
offset += chunkSize;
|
|
44
|
+
}
|
|
45
|
+
return buffers;
|
|
46
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { openTransportReplayer, RecordStore } from "@ledgerhq/hw-transport-mocker";
|
|
2
|
+
import Vet from "../src/Vet";
|
|
3
|
+
import { Transaction as ThorTransaction } from "thor-devkit";
|
|
4
|
+
|
|
5
|
+
test("getAppConfiguration", async () => {
|
|
6
|
+
const transport = await openTransportReplayer(
|
|
7
|
+
RecordStore.fromString(`
|
|
8
|
+
=> e006000000
|
|
9
|
+
<= 030100079000
|
|
10
|
+
`),
|
|
11
|
+
);
|
|
12
|
+
const vet = new Vet(transport);
|
|
13
|
+
const result = await vet.getAppConfiguration();
|
|
14
|
+
expect({ version: result[1] + "." + result[2] + "." + result[3] }).toEqual({
|
|
15
|
+
version: "1.0.7",
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test("Get address", async () => {
|
|
20
|
+
const transport = await openTransportReplayer(
|
|
21
|
+
RecordStore.fromString(`
|
|
22
|
+
=> e002000015058000002c80000332800000000000000000000000
|
|
23
|
+
<= 410482c44bc99cdf08d4360c97fbf62d387288ab75c576926943ad90059002720e93f58799391393c98ad41136aa4ac871b103d25cb9a88f1aadd7dbbe3c7794888928333234373631393364346133323438383332326666426239383335613763463263376532323032439000
|
|
24
|
+
`),
|
|
25
|
+
);
|
|
26
|
+
const vet = new Vet(transport);
|
|
27
|
+
const { address } = await vet.getAddress("44'/818'/0'/0/0");
|
|
28
|
+
expect(address).toEqual("0x32476193d4a32488322ffbb9835a7cf2c7e2202c");
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test("signMessage", async () => {
|
|
32
|
+
const transport = await openTransportReplayer(
|
|
33
|
+
RecordStore.fromString(`
|
|
34
|
+
=> e004000037058000002c80000332800000000000000000000000e1278012d8d7940000000000000000000000000000000000000000808080808080c0
|
|
35
|
+
<= dd0ad907f6cfdd068226999eee0d20789732905270a7c4ed385872599f40978e043a5d7a15e396e59e9c9e921be5f4e02e3b6284b8cf835443f4123ca20b5b35009000
|
|
36
|
+
`),
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
const unsigned = new ThorTransaction({
|
|
40
|
+
chainTag: 39,
|
|
41
|
+
blockRef: "0x0000000000000000",
|
|
42
|
+
expiration: 18,
|
|
43
|
+
clauses: [
|
|
44
|
+
{
|
|
45
|
+
to: "0x0000000000000000000000000000000000000000",
|
|
46
|
+
value: "0",
|
|
47
|
+
data: "0x",
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
gasPriceCoef: 0,
|
|
51
|
+
gas: "0",
|
|
52
|
+
dependsOn: null,
|
|
53
|
+
nonce: 0,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const vet = new Vet(transport);
|
|
57
|
+
const res = await vet.signTransaction("44'/818'/0'/0/0", unsigned.encode().toString("hex"));
|
|
58
|
+
|
|
59
|
+
expect(res.toString("hex")).toEqual(
|
|
60
|
+
"dd0ad907f6cfdd068226999eee0d20789732905270a7c4ed385872599f40978e043a5d7a15e396e59e9c9e921be5f4e02e3b6284b8cf835443f4123ca20b5b3500",
|
|
61
|
+
);
|
|
62
|
+
});
|