@cityofzion/bs-ethereum 1.3.0 → 1.4.1
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/dist/LedgerServiceEthereum.d.ts +10 -8
- package/dist/LedgerServiceEthereum.js +114 -61
- package/package.json +2 -2
|
@@ -1,16 +1,10 @@
|
|
|
1
|
-
import { Account, LedgerService } from '@cityofzion/blockchain-service';
|
|
1
|
+
import { Account, LedgerService, LedgerServiceEmitter } from '@cityofzion/blockchain-service';
|
|
2
2
|
import Transport from '@ledgerhq/hw-transport';
|
|
3
3
|
import { ethers, Signer } from 'ethers';
|
|
4
4
|
import { TypedDataSigner } from '@ethersproject/abstract-signer';
|
|
5
|
-
export declare class LedgerServiceEthereum implements LedgerService {
|
|
6
|
-
getLedgerTransport?: ((account: Account) => Promise<Transport>) | undefined;
|
|
7
|
-
constructor(getLedgerTransport?: ((account: Account) => Promise<Transport>) | undefined);
|
|
8
|
-
getAddress(transport: Transport): Promise<string>;
|
|
9
|
-
getPublicKey(transport: Transport): Promise<string>;
|
|
10
|
-
}
|
|
11
5
|
export declare class LedgerSigner extends Signer implements TypedDataSigner {
|
|
12
6
|
#private;
|
|
13
|
-
constructor(transport: Transport, provider?: ethers.providers.Provider);
|
|
7
|
+
constructor(transport: Transport, provider?: ethers.providers.Provider, emitter?: LedgerServiceEmitter);
|
|
14
8
|
connect(provider: ethers.providers.Provider): LedgerSigner;
|
|
15
9
|
getAddress(): Promise<string>;
|
|
16
10
|
getPublicKey(): Promise<string>;
|
|
@@ -18,3 +12,11 @@ export declare class LedgerSigner extends Signer implements TypedDataSigner {
|
|
|
18
12
|
signTransaction(transaction: ethers.utils.Deferrable<ethers.providers.TransactionRequest>): Promise<string>;
|
|
19
13
|
_signTypedData(domain: ethers.TypedDataDomain, types: Record<string, ethers.TypedDataField[]>, value: Record<string, any>): Promise<string>;
|
|
20
14
|
}
|
|
15
|
+
export declare class LedgerServiceEthereum implements LedgerService {
|
|
16
|
+
getLedgerTransport?: ((account: Account) => Promise<Transport>) | undefined;
|
|
17
|
+
emitter: LedgerServiceEmitter;
|
|
18
|
+
constructor(getLedgerTransport?: ((account: Account) => Promise<Transport>) | undefined);
|
|
19
|
+
getAddress(transport: Transport): Promise<string>;
|
|
20
|
+
getPublicKey(transport: Transport): Promise<string>;
|
|
21
|
+
getSigner(transport: Transport): LedgerSigner;
|
|
22
|
+
}
|
|
@@ -42,44 +42,27 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
42
42
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
43
43
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
44
44
|
};
|
|
45
|
-
var
|
|
45
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
46
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
47
|
+
};
|
|
48
|
+
var _LedgerSigner_instances, _LedgerSigner_transport, _LedgerSigner_emitter, _LedgerSigner_path, _LedgerSigner_retry;
|
|
46
49
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
47
|
-
exports.
|
|
50
|
+
exports.LedgerServiceEthereum = exports.LedgerSigner = void 0;
|
|
48
51
|
const hw_app_eth_1 = __importStar(require("@ledgerhq/hw-app-eth"));
|
|
49
52
|
const ethers_1 = require("ethers");
|
|
50
53
|
const properties_1 = require("@ethersproject/properties");
|
|
51
54
|
const constants_1 = require("./constants");
|
|
52
|
-
|
|
53
|
-
constructor(getLedgerTransport) {
|
|
54
|
-
this.getLedgerTransport = getLedgerTransport;
|
|
55
|
-
}
|
|
56
|
-
getAddress(transport) {
|
|
57
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
58
|
-
const signer = new LedgerSigner(transport);
|
|
59
|
-
return yield signer.getAddress();
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
getPublicKey(transport) {
|
|
63
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
64
|
-
const signer = new LedgerSigner(transport);
|
|
65
|
-
return yield signer.getPublicKey();
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
exports.LedgerServiceEthereum = LedgerServiceEthereum;
|
|
70
|
-
function wait(duration) {
|
|
71
|
-
return new Promise(resolve => {
|
|
72
|
-
setTimeout(resolve, duration);
|
|
73
|
-
});
|
|
74
|
-
}
|
|
55
|
+
const events_1 = __importDefault(require("events"));
|
|
75
56
|
class LedgerSigner extends ethers_1.Signer {
|
|
76
|
-
constructor(transport, provider) {
|
|
57
|
+
constructor(transport, provider, emitter) {
|
|
77
58
|
super();
|
|
78
59
|
_LedgerSigner_instances.add(this);
|
|
79
60
|
_LedgerSigner_transport.set(this, void 0);
|
|
61
|
+
_LedgerSigner_emitter.set(this, void 0);
|
|
80
62
|
_LedgerSigner_path.set(this, void 0);
|
|
81
63
|
__classPrivateFieldSet(this, _LedgerSigner_path, constants_1.DEFAULT_PATH, "f");
|
|
82
64
|
__classPrivateFieldSet(this, _LedgerSigner_transport, transport, "f");
|
|
65
|
+
__classPrivateFieldSet(this, _LedgerSigner_emitter, emitter, "f");
|
|
83
66
|
(0, properties_1.defineReadOnly)(this, 'provider', provider);
|
|
84
67
|
}
|
|
85
68
|
connect(provider) {
|
|
@@ -100,55 +83,98 @@ class LedgerSigner extends ethers_1.Signer {
|
|
|
100
83
|
});
|
|
101
84
|
}
|
|
102
85
|
signMessage(message) {
|
|
86
|
+
var _a, _b, _c;
|
|
103
87
|
return __awaiter(this, void 0, void 0, function* () {
|
|
104
|
-
|
|
105
|
-
message
|
|
88
|
+
try {
|
|
89
|
+
if (typeof message === 'string') {
|
|
90
|
+
message = ethers_1.ethers.utils.toUtf8Bytes(message);
|
|
91
|
+
}
|
|
92
|
+
const ledgerApp = new hw_app_eth_1.default(__classPrivateFieldGet(this, _LedgerSigner_transport, "f"));
|
|
93
|
+
(_a = __classPrivateFieldGet(this, _LedgerSigner_emitter, "f")) === null || _a === void 0 ? void 0 : _a.emit('getSignatureStart');
|
|
94
|
+
const obj = yield __classPrivateFieldGet(this, _LedgerSigner_instances, "m", _LedgerSigner_retry).call(this, () => ledgerApp.signPersonalMessage(__classPrivateFieldGet(this, _LedgerSigner_path, "f"), ethers_1.ethers.utils.hexlify(message).substring(2)));
|
|
95
|
+
(_b = __classPrivateFieldGet(this, _LedgerSigner_emitter, "f")) === null || _b === void 0 ? void 0 : _b.emit('getSignatureEnd');
|
|
96
|
+
// Normalize the signature for Ethers
|
|
97
|
+
obj.r = '0x' + obj.r;
|
|
98
|
+
obj.s = '0x' + obj.s;
|
|
99
|
+
return ethers_1.ethers.utils.joinSignature(obj);
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
(_c = __classPrivateFieldGet(this, _LedgerSigner_emitter, "f")) === null || _c === void 0 ? void 0 : _c.emit('getSignatureEnd');
|
|
103
|
+
throw error;
|
|
106
104
|
}
|
|
107
|
-
const ledgerApp = new hw_app_eth_1.default(__classPrivateFieldGet(this, _LedgerSigner_transport, "f"));
|
|
108
|
-
const obj = yield __classPrivateFieldGet(this, _LedgerSigner_instances, "m", _LedgerSigner_retry).call(this, () => ledgerApp.signPersonalMessage(__classPrivateFieldGet(this, _LedgerSigner_path, "f"), ethers_1.ethers.utils.hexlify(message).substring(2)));
|
|
109
|
-
// Normalize the signature for Ethers
|
|
110
|
-
obj.r = '0x' + obj.r;
|
|
111
|
-
obj.s = '0x' + obj.s;
|
|
112
|
-
return ethers_1.ethers.utils.joinSignature(obj);
|
|
113
105
|
});
|
|
114
106
|
}
|
|
115
107
|
signTransaction(transaction) {
|
|
108
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
116
109
|
return __awaiter(this, void 0, void 0, function* () {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
110
|
+
try {
|
|
111
|
+
const ledgerApp = new hw_app_eth_1.default(__classPrivateFieldGet(this, _LedgerSigner_transport, "f"));
|
|
112
|
+
const tx = yield ethers_1.ethers.utils.resolveProperties(transaction);
|
|
113
|
+
const unsignedTransaction = {
|
|
114
|
+
chainId: (_a = tx.chainId) !== null && _a !== void 0 ? _a : undefined,
|
|
115
|
+
data: (_b = tx.data) !== null && _b !== void 0 ? _b : undefined,
|
|
116
|
+
gasLimit: (_c = tx.gasLimit) !== null && _c !== void 0 ? _c : undefined,
|
|
117
|
+
gasPrice: (_d = tx.gasPrice) !== null && _d !== void 0 ? _d : undefined,
|
|
118
|
+
nonce: tx.nonce ? ethers_1.ethers.BigNumber.from(tx.nonce).toNumber() : undefined,
|
|
119
|
+
to: (_e = tx.to) !== null && _e !== void 0 ? _e : undefined,
|
|
120
|
+
value: (_f = tx.value) !== null && _f !== void 0 ? _f : undefined,
|
|
121
|
+
};
|
|
122
|
+
const serializedUnsignedTransaction = ethers_1.ethers.utils.serializeTransaction(unsignedTransaction).substring(2);
|
|
123
|
+
const resolution = yield hw_app_eth_1.ledgerService.resolveTransaction(serializedUnsignedTransaction, {}, {});
|
|
124
|
+
(_g = __classPrivateFieldGet(this, _LedgerSigner_emitter, "f")) === null || _g === void 0 ? void 0 : _g.emit('getSignatureStart');
|
|
125
|
+
const signature = yield __classPrivateFieldGet(this, _LedgerSigner_instances, "m", _LedgerSigner_retry).call(this, () => ledgerApp.signTransaction(__classPrivateFieldGet(this, _LedgerSigner_path, "f"), serializedUnsignedTransaction, resolution));
|
|
126
|
+
(_h = __classPrivateFieldGet(this, _LedgerSigner_emitter, "f")) === null || _h === void 0 ? void 0 : _h.emit('getSignatureEnd');
|
|
127
|
+
return ethers_1.ethers.utils.serializeTransaction(unsignedTransaction, {
|
|
128
|
+
v: ethers_1.ethers.BigNumber.from('0x' + signature.v).toNumber(),
|
|
129
|
+
r: '0x' + signature.r,
|
|
130
|
+
s: '0x' + signature.s,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
(_j = __classPrivateFieldGet(this, _LedgerSigner_emitter, "f")) === null || _j === void 0 ? void 0 : _j.emit('getSignatureEnd');
|
|
135
|
+
throw error;
|
|
136
|
+
}
|
|
128
137
|
});
|
|
129
138
|
}
|
|
130
139
|
_signTypedData(domain, types, value) {
|
|
140
|
+
var _a, _b, _c;
|
|
131
141
|
return __awaiter(this, void 0, void 0, function* () {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
142
|
+
try {
|
|
143
|
+
const populated = yield ethers_1.ethers.utils._TypedDataEncoder.resolveNames(domain, types, value, (name) => __awaiter(this, void 0, void 0, function* () {
|
|
144
|
+
if (!this.provider)
|
|
145
|
+
throw new Error('Cannot resolve ENS names without a provider');
|
|
146
|
+
const resolved = yield this.provider.resolveName(name);
|
|
147
|
+
if (!resolved)
|
|
148
|
+
throw new Error('No address found for domain name');
|
|
149
|
+
return resolved;
|
|
150
|
+
}));
|
|
151
|
+
const payload = ethers_1.ethers.utils._TypedDataEncoder.getPayload(populated.domain, types, populated.value);
|
|
152
|
+
const ledgerApp = new hw_app_eth_1.default(__classPrivateFieldGet(this, _LedgerSigner_transport, "f"));
|
|
153
|
+
(_a = __classPrivateFieldGet(this, _LedgerSigner_emitter, "f")) === null || _a === void 0 ? void 0 : _a.emit('getSignatureStart');
|
|
154
|
+
let obj;
|
|
155
|
+
try {
|
|
156
|
+
obj = yield __classPrivateFieldGet(this, _LedgerSigner_instances, "m", _LedgerSigner_retry).call(this, () => ledgerApp.signEIP712Message(__classPrivateFieldGet(this, _LedgerSigner_path, "f"), payload));
|
|
157
|
+
}
|
|
158
|
+
catch (_d) {
|
|
159
|
+
const domainSeparatorHex = ethers_1.ethers.utils._TypedDataEncoder.hashDomain(payload.domain);
|
|
160
|
+
const hashStructMessageHex = ethers_1.ethers.utils._TypedDataEncoder.hashStruct(payload.primaryType, types, payload.message);
|
|
161
|
+
obj = yield __classPrivateFieldGet(this, _LedgerSigner_instances, "m", _LedgerSigner_retry).call(this, () => ledgerApp.signEIP712HashedMessage(__classPrivateFieldGet(this, _LedgerSigner_path, "f"), domainSeparatorHex, hashStructMessageHex));
|
|
162
|
+
}
|
|
163
|
+
(_b = __classPrivateFieldGet(this, _LedgerSigner_emitter, "f")) === null || _b === void 0 ? void 0 : _b.emit('getSignatureEnd');
|
|
164
|
+
// Normalize the signature for Ethers
|
|
165
|
+
obj.r = '0x' + obj.r;
|
|
166
|
+
obj.s = '0x' + obj.s;
|
|
167
|
+
return ethers_1.ethers.utils.joinSignature(obj);
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
(_c = __classPrivateFieldGet(this, _LedgerSigner_emitter, "f")) === null || _c === void 0 ? void 0 : _c.emit('getSignatureEnd');
|
|
171
|
+
throw error;
|
|
172
|
+
}
|
|
147
173
|
});
|
|
148
174
|
}
|
|
149
175
|
}
|
|
150
176
|
exports.LedgerSigner = LedgerSigner;
|
|
151
|
-
_LedgerSigner_transport = new WeakMap(), _LedgerSigner_path = new WeakMap(), _LedgerSigner_instances = new WeakSet(), _LedgerSigner_retry = function _LedgerSigner_retry(callback) {
|
|
177
|
+
_LedgerSigner_transport = new WeakMap(), _LedgerSigner_emitter = new WeakMap(), _LedgerSigner_path = new WeakMap(), _LedgerSigner_instances = new WeakSet(), _LedgerSigner_retry = function _LedgerSigner_retry(callback) {
|
|
152
178
|
// eslint-disable-next-line no-async-promise-executor
|
|
153
179
|
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
|
154
180
|
// Wait up to 5 seconds
|
|
@@ -167,3 +193,30 @@ _LedgerSigner_transport = new WeakMap(), _LedgerSigner_path = new WeakMap(), _Le
|
|
|
167
193
|
return reject(new Error('timeout'));
|
|
168
194
|
}));
|
|
169
195
|
};
|
|
196
|
+
class LedgerServiceEthereum {
|
|
197
|
+
constructor(getLedgerTransport) {
|
|
198
|
+
this.getLedgerTransport = getLedgerTransport;
|
|
199
|
+
this.emitter = new events_1.default();
|
|
200
|
+
}
|
|
201
|
+
getAddress(transport) {
|
|
202
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
203
|
+
const signer = new LedgerSigner(transport);
|
|
204
|
+
return yield signer.getAddress();
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
getPublicKey(transport) {
|
|
208
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
209
|
+
const signer = new LedgerSigner(transport);
|
|
210
|
+
return yield signer.getPublicKey();
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
getSigner(transport) {
|
|
214
|
+
return new LedgerSigner(transport, undefined, this.emitter);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
exports.LedgerServiceEthereum = LedgerServiceEthereum;
|
|
218
|
+
function wait(duration) {
|
|
219
|
+
return new Promise(resolve => {
|
|
220
|
+
setTimeout(resolve, duration);
|
|
221
|
+
});
|
|
222
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cityofzion/bs-ethereum",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"repository": "https://github.com/CityOfZion/blockchain-services",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"@ledgerhq/hw-app-eth": "~6.35.7",
|
|
24
24
|
"@ethersproject/abstract-signer": "~5.7.0",
|
|
25
25
|
"@ethersproject/properties": "~5.7.0",
|
|
26
|
-
"@cityofzion/blockchain-service": "0.
|
|
26
|
+
"@cityofzion/blockchain-service": "0.12.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/jest": "29.5.3",
|