@reef-knot/ledger-connector 1.0.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/dist/_virtual/_tslib.js +26 -0
- package/dist/hid/connector.d.ts +23 -0
- package/dist/hid/connector.d.ts.map +1 -0
- package/dist/hid/connector.js +73 -0
- package/dist/hid/helpers.d.ts +12 -0
- package/dist/hid/helpers.d.ts.map +1 -0
- package/dist/hid/helpers.js +70 -0
- package/dist/hid/index.d.ts +2 -0
- package/dist/hid/index.d.ts.map +1 -0
- package/dist/hid/provider.d.ts +20 -0
- package/dist/hid/provider.d.ts.map +1 -0
- package/dist/hid/provider.js +96 -0
- package/dist/hid/signer.d.ts +29 -0
- package/dist/hid/signer.d.ts.map +1 -0
- package/dist/hid/signer.js +178 -0
- package/dist/hid/types.d.ts +10 -0
- package/dist/hid/types.d.ts.map +1 -0
- package/dist/iframe/connector.d.ts +24 -0
- package/dist/iframe/connector.d.ts.map +1 -0
- package/dist/iframe/connector.js +97 -0
- package/dist/iframe/helpers.d.ts +3 -0
- package/dist/iframe/helpers.d.ts.map +1 -0
- package/dist/iframe/helpers.js +24 -0
- package/dist/iframe/index.d.ts +3 -0
- package/dist/iframe/index.d.ts.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/package.json +53 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/******************************************************************************
|
|
2
|
+
Copyright (c) Microsoft Corporation.
|
|
3
|
+
|
|
4
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
5
|
+
purpose with or without fee is hereby granted.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
8
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
9
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
10
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
11
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
12
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
13
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
14
|
+
***************************************************************************** */
|
|
15
|
+
|
|
16
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
17
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
18
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
19
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
20
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
21
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
22
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { __awaiter };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { AbstractConnector } from '@web3-react/abstract-connector';
|
|
2
|
+
import type { ConnectorUpdate } from '@web3-react/types';
|
|
3
|
+
import type { LedgerHQProvider } from './provider';
|
|
4
|
+
type LedgerHQConnectorArguments = {
|
|
5
|
+
chainId: number;
|
|
6
|
+
url: string;
|
|
7
|
+
};
|
|
8
|
+
export declare class LedgerHQConnector extends AbstractConnector {
|
|
9
|
+
provider?: LedgerHQProvider;
|
|
10
|
+
url: string;
|
|
11
|
+
chainId: number;
|
|
12
|
+
constructor({ chainId, url }: LedgerHQConnectorArguments);
|
|
13
|
+
private handleDisconnect;
|
|
14
|
+
isSupported(): boolean;
|
|
15
|
+
getProviderInstance(): Promise<LedgerHQProvider>;
|
|
16
|
+
activate(): Promise<ConnectorUpdate>;
|
|
17
|
+
getProvider(): Promise<LedgerHQProvider | undefined>;
|
|
18
|
+
getChainId(): Promise<number>;
|
|
19
|
+
getAccount(): Promise<string>;
|
|
20
|
+
deactivate(): void;
|
|
21
|
+
}
|
|
22
|
+
export default LedgerHQConnector;
|
|
23
|
+
//# sourceMappingURL=connector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connector.d.ts","sourceRoot":"","sources":["../../src/hid/connector.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,KAAK,0BAA0B,GAAG;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,qBAAa,iBAAkB,SAAQ,iBAAiB;IAC/C,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAE5B,GAAG,EAAE,MAAM,CAAC;IAEZ,OAAO,EAAE,MAAM,CAAC;gBAEX,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,0BAA0B;IASxD,OAAO,CAAC,gBAAgB;IAKjB,WAAW,IAAI,OAAO;IAIhB,mBAAmB,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAMhD,QAAQ,IAAI,OAAO,CAAC,eAAe,CAAC;IAepC,WAAW,IAAI,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC;IAIpD,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAI7B,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAKnC,UAAU,IAAI,IAAI;CAI1B;AAED,eAAe,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { __awaiter } from '../_virtual/_tslib.js';
|
|
2
|
+
import invariant from 'tiny-invariant';
|
|
3
|
+
import { AbstractConnector } from '@web3-react/abstract-connector';
|
|
4
|
+
import { isHIDSupported, checkError } from './helpers.js';
|
|
5
|
+
|
|
6
|
+
class LedgerHQConnector extends AbstractConnector {
|
|
7
|
+
constructor({
|
|
8
|
+
chainId,
|
|
9
|
+
url
|
|
10
|
+
}) {
|
|
11
|
+
super({
|
|
12
|
+
supportedChainIds: [chainId]
|
|
13
|
+
});
|
|
14
|
+
this.chainId = chainId;
|
|
15
|
+
this.url = url;
|
|
16
|
+
this.handleDisconnect = this.handleDisconnect.bind(this);
|
|
17
|
+
}
|
|
18
|
+
handleDisconnect() {
|
|
19
|
+
this.emitDeactivate();
|
|
20
|
+
}
|
|
21
|
+
// eslint-disable-next-line class-methods-use-this
|
|
22
|
+
isSupported() {
|
|
23
|
+
return isHIDSupported();
|
|
24
|
+
}
|
|
25
|
+
getProviderInstance() {
|
|
26
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
27
|
+
// eslint-disable-next-line no-shadow
|
|
28
|
+
const {
|
|
29
|
+
LedgerHQProvider
|
|
30
|
+
} = yield import('./provider.js');
|
|
31
|
+
return new LedgerHQProvider(this.url, this.chainId);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
activate() {
|
|
35
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
36
|
+
try {
|
|
37
|
+
if (!this.provider) {
|
|
38
|
+
this.provider = yield this.getProviderInstance();
|
|
39
|
+
}
|
|
40
|
+
this.provider.on('disconnect', this.handleDisconnect);
|
|
41
|
+
const account = yield this.provider.enable();
|
|
42
|
+
return {
|
|
43
|
+
provider: this.provider,
|
|
44
|
+
account
|
|
45
|
+
};
|
|
46
|
+
} catch (error) {
|
|
47
|
+
return checkError(error);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
getProvider() {
|
|
52
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
53
|
+
return this.provider;
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
getChainId() {
|
|
57
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
58
|
+
return this.chainId;
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
getAccount() {
|
|
62
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
63
|
+
invariant(this.provider, 'Provider is not defined');
|
|
64
|
+
return this.provider.getAddress();
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
deactivate() {
|
|
68
|
+
invariant(this.provider, 'Provider is not defined');
|
|
69
|
+
this.provider.removeListener('disconnect', this.handleDisconnect);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export { LedgerHQConnector, LedgerHQConnector as default };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BigNumberish } from '@ethersproject/bignumber';
|
|
2
|
+
import { TransactionRequestExtended, UnsignedTransactionStrict } from './types';
|
|
3
|
+
export declare const isHIDSupported: () => boolean;
|
|
4
|
+
export declare const hasEIP1559: (tx: {
|
|
5
|
+
type?: number;
|
|
6
|
+
maxFeePerGas?: BigNumberish;
|
|
7
|
+
maxPriorityFeePerGas?: BigNumberish;
|
|
8
|
+
}) => boolean;
|
|
9
|
+
export declare const toNumber: (value: BigNumberish | undefined | null) => number | undefined;
|
|
10
|
+
export declare const convertToUnsigned: (tx: TransactionRequestExtended) => Promise<UnsignedTransactionStrict>;
|
|
11
|
+
export declare const checkError: (error: any) => never;
|
|
12
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/hid/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAEnE,OAAO,EAAE,0BAA0B,EAAE,yBAAyB,EAAE,MAAM,SAAS,CAAC;AAEhF,eAAO,MAAM,cAAc,eAM1B,CAAC;AAEF,eAAO,MAAM,UAAU,OAAQ;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,oBAAoB,CAAC,EAAE,YAAY,CAAC;CACrC,YAIA,CAAC;AAEF,eAAO,MAAM,QAAQ,UACZ,YAAY,GAAG,SAAS,GAAG,IAAI,KACrC,MAAM,GAAG,SAEX,CAAC;AAEF,eAAO,MAAM,iBAAiB,OACxB,0BAA0B,KAC7B,QAAQ,yBAAyB,CAgCnC,CAAC;AAEF,eAAO,MAAM,UAAU,UAAW,GAAG,KAAG,KAmBvC,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { __awaiter } from '../_virtual/_tslib.js';
|
|
2
|
+
import { BigNumber } from '@ethersproject/bignumber';
|
|
3
|
+
import { resolveProperties } from '@ethersproject/properties';
|
|
4
|
+
|
|
5
|
+
const isHIDSupported = () => {
|
|
6
|
+
try {
|
|
7
|
+
return 'hid' in window.navigator;
|
|
8
|
+
} catch (error) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
const hasEIP1559 = tx => {
|
|
13
|
+
return tx.type === 2 || tx.maxFeePerGas != null || tx.maxPriorityFeePerGas != null;
|
|
14
|
+
};
|
|
15
|
+
const toNumber = value => {
|
|
16
|
+
return value == null ? undefined : BigNumber.from(value).toNumber();
|
|
17
|
+
};
|
|
18
|
+
const convertToUnsigned = tx => __awaiter(void 0, void 0, void 0, function* () {
|
|
19
|
+
const resolvedTx = yield resolveProperties(tx);
|
|
20
|
+
const {
|
|
21
|
+
chainId,
|
|
22
|
+
data,
|
|
23
|
+
gasLimit,
|
|
24
|
+
gas,
|
|
25
|
+
gasPrice,
|
|
26
|
+
value,
|
|
27
|
+
to
|
|
28
|
+
} = resolvedTx;
|
|
29
|
+
const nonce = toNumber(resolvedTx.nonce);
|
|
30
|
+
const type = toNumber(resolvedTx.type);
|
|
31
|
+
// Allowed transaction keys for Legacy and EIP-155 Transactions
|
|
32
|
+
const baseTx = {
|
|
33
|
+
gasLimit: gasLimit || gas,
|
|
34
|
+
type: type !== null && type !== void 0 ? type : 2,
|
|
35
|
+
chainId,
|
|
36
|
+
gasPrice,
|
|
37
|
+
nonce,
|
|
38
|
+
value,
|
|
39
|
+
data,
|
|
40
|
+
to
|
|
41
|
+
};
|
|
42
|
+
// EIP-2930
|
|
43
|
+
if (tx.accessList != null) {
|
|
44
|
+
baseTx.accessList = tx.accessList;
|
|
45
|
+
}
|
|
46
|
+
// EIP-1559
|
|
47
|
+
if (hasEIP1559(tx)) {
|
|
48
|
+
baseTx.maxFeePerGas = tx.maxFeePerGas;
|
|
49
|
+
baseTx.maxPriorityFeePerGas = tx.maxPriorityFeePerGas;
|
|
50
|
+
baseTx.type = 2;
|
|
51
|
+
}
|
|
52
|
+
return baseTx;
|
|
53
|
+
});
|
|
54
|
+
const checkError = error => {
|
|
55
|
+
if (error.statusText === 'INS_NOT_SUPPORTED') {
|
|
56
|
+
// eslint-disable-next-line no-param-reassign
|
|
57
|
+
error.message = 'Device is not supported. Make sure the Ethereum app is open on the device.';
|
|
58
|
+
}
|
|
59
|
+
if (error.statusText === 'UNKNOWN_ERROR') {
|
|
60
|
+
// eslint-disable-next-line no-param-reassign
|
|
61
|
+
error.message = 'Unknown error. Make sure the device is connected and the Ethereum app is open on the device.';
|
|
62
|
+
}
|
|
63
|
+
if (error.statusText === 'CONDITIONS_OF_USE_NOT_SATISFIED') {
|
|
64
|
+
// eslint-disable-next-line no-param-reassign
|
|
65
|
+
error.message = 'User rejected the request';
|
|
66
|
+
}
|
|
67
|
+
throw error;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export { checkError, convertToUnsigned, hasEIP1559, isHIDSupported, toNumber };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hid/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/// <reference types="w3c-web-hid" />
|
|
2
|
+
import { JsonRpcBatchProvider, Network } from '@ethersproject/providers';
|
|
3
|
+
import type TransportHID from '@ledgerhq/hw-transport-webhid';
|
|
4
|
+
import { LedgerHQSigner } from './signer';
|
|
5
|
+
export declare class LedgerHQProvider extends JsonRpcBatchProvider {
|
|
6
|
+
signer?: LedgerHQSigner;
|
|
7
|
+
device?: HIDDevice;
|
|
8
|
+
transport?: typeof TransportHID;
|
|
9
|
+
getSigner(): LedgerHQSigner;
|
|
10
|
+
listAccounts(): Promise<Array<string>>;
|
|
11
|
+
detectNetwork(): Promise<Network>;
|
|
12
|
+
getTransport(): Promise<TransportHID>;
|
|
13
|
+
enable(): Promise<string>;
|
|
14
|
+
getAddress(): Promise<string>;
|
|
15
|
+
request({ method, params, }: {
|
|
16
|
+
method: string;
|
|
17
|
+
params: Array<unknown>;
|
|
18
|
+
}): Promise<unknown>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/hid/provider.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,KAAK,YAAY,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAK1C,qBAAa,gBAAiB,SAAQ,oBAAoB;IACjD,MAAM,CAAC,EAAE,cAAc,CAAC;IAExB,MAAM,CAAC,EAAE,SAAS,CAAC;IAEnB,SAAS,CAAC,EAAE,OAAO,YAAY,CAAC;IAEvC,SAAS,IAAI,cAAc;IAK3B,YAAY,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAIhC,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC;IAIjC,YAAY,IAAI,OAAO,CAAC,YAAY,CAAC;IAarC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;IA6BzB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAK7B,OAAO,CAAC,EACZ,MAAM,EACN,MAAM,GACP,EAAE;QACD,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;KACxB,GAAG,OAAO,CAAC,OAAO,CAAC;CAwBrB"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { __awaiter } from '../_virtual/_tslib.js';
|
|
2
|
+
import invariant from 'tiny-invariant';
|
|
3
|
+
import { JsonRpcBatchProvider } from '@ethersproject/providers';
|
|
4
|
+
import { LedgerHQSigner } from './signer.js';
|
|
5
|
+
import { checkError, convertToUnsigned } from './helpers.js';
|
|
6
|
+
|
|
7
|
+
class LedgerHQProvider extends JsonRpcBatchProvider {
|
|
8
|
+
getSigner() {
|
|
9
|
+
return new LedgerHQSigner(this);
|
|
10
|
+
}
|
|
11
|
+
// eslint-disable-next-line class-methods-use-this
|
|
12
|
+
listAccounts() {
|
|
13
|
+
throw new Error('method is not implemented');
|
|
14
|
+
}
|
|
15
|
+
detectNetwork() {
|
|
16
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
17
|
+
return this._network;
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
getTransport() {
|
|
21
|
+
var _a;
|
|
22
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
23
|
+
invariant(this.transport, 'Transport is not defined');
|
|
24
|
+
try {
|
|
25
|
+
const transport = yield (_a = this.transport) === null || _a === void 0 ? void 0 : _a.create();
|
|
26
|
+
this.device = transport.device;
|
|
27
|
+
return transport;
|
|
28
|
+
} catch (error) {
|
|
29
|
+
return checkError(error);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
enable() {
|
|
34
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
35
|
+
try {
|
|
36
|
+
// eslint-disable-next-line no-shadow
|
|
37
|
+
const {
|
|
38
|
+
default: TransportHID
|
|
39
|
+
} = yield import('@ledgerhq/hw-transport-webhid');
|
|
40
|
+
this.transport = TransportHID;
|
|
41
|
+
const {
|
|
42
|
+
hid
|
|
43
|
+
} = window.navigator;
|
|
44
|
+
const onDisconnect = event => {
|
|
45
|
+
if (this.device === event.device) {
|
|
46
|
+
hid.removeEventListener('disconnect', onDisconnect);
|
|
47
|
+
this.emit('disconnect');
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
hid.addEventListener('disconnect', onDisconnect);
|
|
51
|
+
if (!this.signer) {
|
|
52
|
+
this.signer = this.getSigner();
|
|
53
|
+
}
|
|
54
|
+
return yield this.getAddress();
|
|
55
|
+
} catch (error) {
|
|
56
|
+
return checkError(error);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
getAddress() {
|
|
61
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
62
|
+
invariant(this.signer, 'Signer is not defined');
|
|
63
|
+
return yield this.signer.getAddress();
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
request({
|
|
67
|
+
method,
|
|
68
|
+
params
|
|
69
|
+
}) {
|
|
70
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
71
|
+
invariant(this.signer, 'Signer is not defined');
|
|
72
|
+
switch (method) {
|
|
73
|
+
case 'eth_sendTransaction':
|
|
74
|
+
const sourceTx = params[0];
|
|
75
|
+
const unsignedTx = yield convertToUnsigned(sourceTx);
|
|
76
|
+
const signedTx = yield this.signer.signTransaction(unsignedTx);
|
|
77
|
+
return this.send('eth_sendRawTransaction', [signedTx]);
|
|
78
|
+
case 'eth_accounts':
|
|
79
|
+
return [yield this.getAddress()];
|
|
80
|
+
case 'eth_signTypedData_v4':
|
|
81
|
+
if (typeof params[1] !== 'string') throw new Error('eth_signTypedData_v4 arg 1 is not a string');
|
|
82
|
+
const payload = JSON.parse(params[1]);
|
|
83
|
+
return yield this.signer.__signEIP712Message({
|
|
84
|
+
domain: payload.domain,
|
|
85
|
+
types: payload.types,
|
|
86
|
+
primaryType: payload.primaryType,
|
|
87
|
+
message: payload.message
|
|
88
|
+
});
|
|
89
|
+
default:
|
|
90
|
+
return this.send(method, params);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export { LedgerHQProvider };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import Eth from '@ledgerhq/hw-app-eth';
|
|
2
|
+
import { LoadConfig, ResolutionConfig } from '@ledgerhq/hw-app-eth/lib/services/types';
|
|
3
|
+
import { EIP712Message } from '@ledgerhq/hw-app-eth/lib/modules/EIP712/EIP712.types';
|
|
4
|
+
import { JsonRpcSigner, TransactionRequest } from '@ethersproject/providers';
|
|
5
|
+
import { Signer, TypedDataDomain, TypedDataField, TypedDataSigner } from '@ethersproject/abstract-signer';
|
|
6
|
+
import { UnsignedTransaction } from '@ethersproject/transactions';
|
|
7
|
+
import { Bytes } from '@ethersproject/bytes';
|
|
8
|
+
import { LedgerHQProvider } from './provider';
|
|
9
|
+
import { UnsignedTransactionStrict } from './types';
|
|
10
|
+
export declare class LedgerHQSigner extends Signer implements TypedDataSigner {
|
|
11
|
+
readonly path: string;
|
|
12
|
+
readonly provider: LedgerHQProvider;
|
|
13
|
+
_index: number;
|
|
14
|
+
_address: string;
|
|
15
|
+
constructor(provider: LedgerHQProvider, path?: string);
|
|
16
|
+
withEthApp<T>(callback: (eth: Eth) => T): Promise<T>;
|
|
17
|
+
getAddress(): Promise<string>;
|
|
18
|
+
signMessage(message: Bytes | string): Promise<string>;
|
|
19
|
+
populateUnsigned(transaction: UnsignedTransactionStrict): Promise<UnsignedTransaction>;
|
|
20
|
+
signTransaction(transaction: TransactionRequest, loadConfig?: LoadConfig, resolutionConfig?: ResolutionConfig): Promise<string>;
|
|
21
|
+
connect(provider: LedgerHQProvider): JsonRpcSigner;
|
|
22
|
+
connectUnchecked(): JsonRpcSigner;
|
|
23
|
+
sendUncheckedTransaction(): Promise<string>;
|
|
24
|
+
unlock(): Promise<boolean>;
|
|
25
|
+
_legacySignMessage(message: Bytes | string): Promise<string>;
|
|
26
|
+
_signTypedData(domain: TypedDataDomain, _types: Record<string, Array<TypedDataField>>, value: Record<string, any>): Promise<string>;
|
|
27
|
+
__signEIP712Message(data: EIP712Message): Promise<string>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=signer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signer.d.ts","sourceRoot":"","sources":["../../src/hid/signer.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,sBAAsB,CAAC;AAEvC,OAAO,EACL,UAAU,EACV,gBAAgB,EACjB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAEL,aAAa,EACd,MAAM,sDAAsD,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE7E,OAAO,EACL,MAAM,EACN,eAAe,EACf,cAAc,EACd,eAAe,EAChB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,mBAAmB,EAAa,MAAM,6BAA6B,CAAC;AAE7E,OAAO,EAAE,KAAK,EAA0B,MAAM,sBAAsB,CAAC;AAGrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EAAE,yBAAyB,EAAE,MAAM,SAAS,CAAC;AAIpD,qBAAa,cAAe,SAAQ,MAAO,YAAW,eAAe;IACnE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IAEpC,MAAM,SAAK;IAEX,QAAQ,SAAM;gBAEF,QAAQ,EAAE,gBAAgB,EAAE,IAAI,GAAE,MAAoB;IAO5D,UAAU,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAepD,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAW7B,WAAW,CAAC,OAAO,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiBrD,gBAAgB,CACpB,WAAW,EAAE,yBAAyB,GACrC,OAAO,CAAC,mBAAmB,CAAC;IAczB,eAAe,CACnB,WAAW,EAAE,kBAAkB,EAC/B,UAAU,GAAE,UAAe,EAC3B,gBAAgB,GAAE,gBAAqB,GACtC,OAAO,CAAC,MAAM,CAAC;IAsBlB,OAAO,CAAC,QAAQ,EAAE,gBAAgB,GAAG,aAAa;IAKlD,gBAAgB,IAAI,aAAa;IAKjC,wBAAwB,IAAI,OAAO,CAAC,MAAM,CAAC;IAKrC,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;IAK1B,kBAAkB,CAAC,OAAO,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK5D,cAAc,CAClB,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC,EAC7C,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACzB,OAAO,CAAC,MAAM,CAAC;IA8BZ,mBAAmB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC;CAOhE"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { __awaiter } from '../_virtual/_tslib.js';
|
|
2
|
+
import Eth from '@ledgerhq/hw-app-eth';
|
|
3
|
+
import ledgerService from '@ledgerhq/hw-app-eth/lib/services/ledger';
|
|
4
|
+
import { BigNumber } from '@ethersproject/bignumber';
|
|
5
|
+
import { Signer } from '@ethersproject/abstract-signer';
|
|
6
|
+
import { serialize } from '@ethersproject/transactions';
|
|
7
|
+
import { toUtf8Bytes } from '@ethersproject/strings';
|
|
8
|
+
import { hexlify, joinSignature } from '@ethersproject/bytes';
|
|
9
|
+
import { _TypedDataEncoder } from '@ethersproject/hash';
|
|
10
|
+
import { checkError, toNumber, convertToUnsigned } from './helpers.js';
|
|
11
|
+
|
|
12
|
+
const defaultPath = "m/44'/60'/0'/0/0";
|
|
13
|
+
class LedgerHQSigner extends Signer {
|
|
14
|
+
constructor(provider, path = defaultPath) {
|
|
15
|
+
super();
|
|
16
|
+
this._index = 0;
|
|
17
|
+
this._address = '';
|
|
18
|
+
this.path = path;
|
|
19
|
+
this.provider = provider;
|
|
20
|
+
}
|
|
21
|
+
withEthApp(callback) {
|
|
22
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
23
|
+
const transport = yield this.provider.getTransport();
|
|
24
|
+
try {
|
|
25
|
+
const eth = new Eth(transport);
|
|
26
|
+
yield eth.getAppConfiguration();
|
|
27
|
+
return yield callback(eth);
|
|
28
|
+
} catch (error) {
|
|
29
|
+
return checkError(error);
|
|
30
|
+
} finally {
|
|
31
|
+
yield transport.close();
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
getAddress() {
|
|
36
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
37
|
+
if (!this._address) {
|
|
38
|
+
const account = yield this.withEthApp(eth => eth.getAddress(this.path));
|
|
39
|
+
const address = this.provider.formatter.address(account.address);
|
|
40
|
+
this._address = address;
|
|
41
|
+
}
|
|
42
|
+
return this._address;
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
signMessage(message) {
|
|
46
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
47
|
+
if (typeof message === 'string') {
|
|
48
|
+
// eslint-disable-next-line no-param-reassign
|
|
49
|
+
message = toUtf8Bytes(message);
|
|
50
|
+
}
|
|
51
|
+
const messageHex = hexlify(message).substring(2);
|
|
52
|
+
const sig = yield this.withEthApp(eth => eth.signPersonalMessage(this.path, messageHex));
|
|
53
|
+
sig.r = `0x${sig.r}`;
|
|
54
|
+
sig.s = `0x${sig.s}`;
|
|
55
|
+
return joinSignature(sig);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
populateUnsigned(transaction) {
|
|
59
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
60
|
+
const populated = yield this.populateTransaction(transaction);
|
|
61
|
+
const nonce = toNumber(populated.nonce);
|
|
62
|
+
if (populated.type === 0) {
|
|
63
|
+
const {
|
|
64
|
+
gasLimit,
|
|
65
|
+
type,
|
|
66
|
+
chainId,
|
|
67
|
+
gasPrice,
|
|
68
|
+
value,
|
|
69
|
+
data,
|
|
70
|
+
to
|
|
71
|
+
} = populated;
|
|
72
|
+
// Allowed transaction keys for Legacy and EIP-155 Transactions
|
|
73
|
+
return {
|
|
74
|
+
gasLimit,
|
|
75
|
+
type,
|
|
76
|
+
chainId,
|
|
77
|
+
gasPrice,
|
|
78
|
+
nonce,
|
|
79
|
+
value,
|
|
80
|
+
data,
|
|
81
|
+
to
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
return Object.assign(Object.assign({}, populated), {
|
|
85
|
+
nonce
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
signTransaction(transaction, loadConfig = {}, resolutionConfig = {}) {
|
|
90
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
91
|
+
const unsignedTx = yield convertToUnsigned(transaction);
|
|
92
|
+
const populatedTx = yield this.populateUnsigned(unsignedTx);
|
|
93
|
+
const serializedTx = serialize(populatedTx).substring(2);
|
|
94
|
+
const resolution = yield ledgerService.resolveTransaction(serializedTx, loadConfig, resolutionConfig);
|
|
95
|
+
const sig = yield this.withEthApp(eth => eth.signTransaction(this.path, serializedTx, resolution));
|
|
96
|
+
return serialize(populatedTx, {
|
|
97
|
+
v: BigNumber.from(`0x${sig.v}`).toNumber(),
|
|
98
|
+
r: `0x${sig.r}`,
|
|
99
|
+
s: `0x${sig.s}`
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
connect(provider) {
|
|
104
|
+
return new LedgerHQSigner(provider, this.path);
|
|
105
|
+
}
|
|
106
|
+
// eslint-disable-next-line class-methods-use-this
|
|
107
|
+
connectUnchecked() {
|
|
108
|
+
throw new Error('method is not implemented');
|
|
109
|
+
}
|
|
110
|
+
// eslint-disable-next-line class-methods-use-this
|
|
111
|
+
sendUncheckedTransaction() {
|
|
112
|
+
throw new Error('method is not implemented');
|
|
113
|
+
}
|
|
114
|
+
// eslint-disable-next-line class-methods-use-this
|
|
115
|
+
unlock() {
|
|
116
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
117
|
+
throw new Error('method is not implemented');
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
// eslint-disable-next-line class-methods-use-this
|
|
121
|
+
_legacySignMessage(message) {
|
|
122
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
123
|
+
throw new Error('method is not implemented');
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
// _signTypedData as per ethers Signer, cleans up types, replaces domain, calculates primaryType
|
|
127
|
+
_signTypedData(domain, _types, value) {
|
|
128
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
129
|
+
const types = Object.assign({}, _types);
|
|
130
|
+
delete types.EIP712Domain;
|
|
131
|
+
const encoder = new _TypedDataEncoder(types);
|
|
132
|
+
const data = {
|
|
133
|
+
domain: {
|
|
134
|
+
name: domain.name,
|
|
135
|
+
verifyingContract: domain.verifyingContract,
|
|
136
|
+
version: domain.version,
|
|
137
|
+
chainId: domain.chainId // eslint-disable-next-line radix
|
|
138
|
+
? parseInt(domain.chainId.toString()) : undefined
|
|
139
|
+
},
|
|
140
|
+
types: Object.assign(Object.assign({}, types), {
|
|
141
|
+
EIP712Domain: [{
|
|
142
|
+
name: 'name',
|
|
143
|
+
type: 'string'
|
|
144
|
+
}, {
|
|
145
|
+
name: 'version',
|
|
146
|
+
type: 'string'
|
|
147
|
+
}, {
|
|
148
|
+
name: 'chainId',
|
|
149
|
+
type: 'uint256'
|
|
150
|
+
}, {
|
|
151
|
+
name: 'verifyingContract',
|
|
152
|
+
type: 'address'
|
|
153
|
+
}]
|
|
154
|
+
}),
|
|
155
|
+
primaryType: encoder.primaryType,
|
|
156
|
+
message: value
|
|
157
|
+
};
|
|
158
|
+
return this.__signEIP712Message(data);
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
// custom method, also called directly on eth_signTypedData_v4 RPC request
|
|
162
|
+
__signEIP712Message(data) {
|
|
163
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
164
|
+
const {
|
|
165
|
+
r,
|
|
166
|
+
s,
|
|
167
|
+
v
|
|
168
|
+
} = yield this.withEthApp(eth => eth.signEIP712Message(this.path, data));
|
|
169
|
+
return joinSignature({
|
|
170
|
+
r: `0x${r}`,
|
|
171
|
+
s: `0x${s}`,
|
|
172
|
+
v
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export { LedgerHQSigner };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BigNumberish } from '@ethersproject/bignumber';
|
|
2
|
+
import { TransactionRequest } from '@ethersproject/providers';
|
|
3
|
+
import { UnsignedTransaction } from '@ethersproject/transactions';
|
|
4
|
+
export type UnsignedTransactionStrict = Omit<UnsignedTransaction, 'type'> & {
|
|
5
|
+
type?: number;
|
|
6
|
+
};
|
|
7
|
+
export type TransactionRequestExtended = TransactionRequest & {
|
|
8
|
+
gas?: BigNumberish;
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/hid/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAElE,MAAM,MAAM,yBAAyB,GAAG,IAAI,CAAC,mBAAmB,EAAE,MAAM,CAAC,GAAG;IAC1E,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG,kBAAkB,GAAG;IAC5D,GAAG,CAAC,EAAE,YAAY,CAAC;CACpB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { AbstractConnector } from '@web3-react/abstract-connector';
|
|
2
|
+
import type { ConnectorUpdate } from '@web3-react/types';
|
|
3
|
+
import type { IFrameEthereumProvider } from '@ledgerhq/iframe-provider';
|
|
4
|
+
type IFrameEthereumProviderOptions = ConstructorParameters<typeof IFrameEthereumProvider>[0] & {
|
|
5
|
+
supportedChainIds?: number[];
|
|
6
|
+
};
|
|
7
|
+
export declare class LedgerHQFrameConnector extends AbstractConnector {
|
|
8
|
+
private config;
|
|
9
|
+
provider?: IFrameEthereumProvider;
|
|
10
|
+
constructor(config?: IFrameEthereumProviderOptions);
|
|
11
|
+
private handleNetworkChanged;
|
|
12
|
+
private handleChainChanged;
|
|
13
|
+
private handleAccountsChanged;
|
|
14
|
+
private handleClose;
|
|
15
|
+
isLedgerApp(): boolean;
|
|
16
|
+
getProviderInstance(): Promise<IFrameEthereumProvider>;
|
|
17
|
+
activate(): Promise<ConnectorUpdate>;
|
|
18
|
+
getProvider(): Promise<IFrameEthereumProvider | undefined>;
|
|
19
|
+
getChainId(): Promise<number | string>;
|
|
20
|
+
getAccount(): Promise<null | string>;
|
|
21
|
+
deactivate(): void;
|
|
22
|
+
}
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=connector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connector.d.ts","sourceRoot":"","sources":["../../src/iframe/connector.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAEnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAGxE,KAAK,6BAA6B,GAAG,qBAAqB,CACxD,OAAO,sBAAsB,CAC9B,CAAC,CAAC,CAAC,GAAG;IAAE,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAIxC,qBAAa,sBAAuB,SAAQ,iBAAiB;IAC3D,OAAO,CAAC,MAAM,CAAgC;IAEvC,QAAQ,CAAC,EAAE,sBAAsB,CAAC;gBAE7B,MAAM,CAAC,EAAE,6BAA6B;IAalD,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,WAAW;IAKZ,WAAW,IAAI,OAAO;IAIhB,mBAAmB,IAAI,OAAO,CAAC,sBAAsB,CAAC;IAUtD,QAAQ,IAAI,OAAO,CAAC,eAAe,CAAC;IAgBpC,WAAW,IAAI,OAAO,CAAC,sBAAsB,GAAG,SAAS,CAAC;IAI1D,UAAU,IAAI,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC;IAKtC,UAAU,IAAI,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC;IAS1C,UAAU,IAAI,IAAI;CAQ1B"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { __awaiter } from '../_virtual/_tslib.js';
|
|
2
|
+
import invariant from 'tiny-invariant';
|
|
3
|
+
import { AbstractConnector } from '@web3-react/abstract-connector';
|
|
4
|
+
import { isLedgerDappBrowserProvider } from './helpers.js';
|
|
5
|
+
|
|
6
|
+
const MAINNET_CHAIN_ID = 1;
|
|
7
|
+
class LedgerHQFrameConnector extends AbstractConnector {
|
|
8
|
+
constructor(config) {
|
|
9
|
+
var _a;
|
|
10
|
+
super({
|
|
11
|
+
supportedChainIds: (_a = config === null || config === void 0 ? void 0 : config.supportedChainIds) !== null && _a !== void 0 ? _a : [MAINNET_CHAIN_ID]
|
|
12
|
+
});
|
|
13
|
+
this.config = config !== null && config !== void 0 ? config : {};
|
|
14
|
+
this.handleNetworkChanged = this.handleNetworkChanged.bind(this);
|
|
15
|
+
this.handleChainChanged = this.handleChainChanged.bind(this);
|
|
16
|
+
this.handleAccountsChanged = this.handleAccountsChanged.bind(this);
|
|
17
|
+
this.handleClose = this.handleClose.bind(this);
|
|
18
|
+
}
|
|
19
|
+
handleNetworkChanged(networkId) {
|
|
20
|
+
this.emitUpdate({
|
|
21
|
+
provider: this.provider,
|
|
22
|
+
chainId: networkId
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
handleChainChanged(chainId) {
|
|
26
|
+
this.emitUpdate({
|
|
27
|
+
chainId
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
handleAccountsChanged(accounts) {
|
|
31
|
+
this.emitUpdate({
|
|
32
|
+
account: accounts.length === 0 ? null : accounts[0]
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
handleClose() {
|
|
36
|
+
this.emitDeactivate();
|
|
37
|
+
}
|
|
38
|
+
// eslint-disable-next-line class-methods-use-this
|
|
39
|
+
isLedgerApp() {
|
|
40
|
+
return isLedgerDappBrowserProvider();
|
|
41
|
+
}
|
|
42
|
+
getProviderInstance() {
|
|
43
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
44
|
+
if (this.provider) return this.provider;
|
|
45
|
+
// eslint-disable-next-line no-shadow
|
|
46
|
+
const {
|
|
47
|
+
IFrameEthereumProvider
|
|
48
|
+
} = yield import('@ledgerhq/iframe-provider');
|
|
49
|
+
return new IFrameEthereumProvider(this.config);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
activate() {
|
|
53
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
54
|
+
if (!this.provider) {
|
|
55
|
+
this.provider = yield this.getProviderInstance();
|
|
56
|
+
}
|
|
57
|
+
this.provider.on('networkChanged', this.handleNetworkChanged);
|
|
58
|
+
this.provider.on('chainChanged', this.handleChainChanged);
|
|
59
|
+
this.provider.on('accountsChanged', this.handleAccountsChanged);
|
|
60
|
+
this.provider.on('close', this.handleClose);
|
|
61
|
+
const accounts = yield this.provider.enable();
|
|
62
|
+
const account = accounts[0];
|
|
63
|
+
return {
|
|
64
|
+
provider: this.provider,
|
|
65
|
+
account
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
getProvider() {
|
|
70
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
71
|
+
return this.provider;
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
getChainId() {
|
|
75
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
76
|
+
invariant(this.provider, 'Provider is not defined');
|
|
77
|
+
return this.provider.send('eth_chainId');
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
getAccount() {
|
|
81
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
82
|
+
invariant(this.provider, 'Provider is not defined');
|
|
83
|
+
const accounts = yield this.provider.send('eth_accounts');
|
|
84
|
+
const account = accounts[0];
|
|
85
|
+
return account;
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
deactivate() {
|
|
89
|
+
invariant(this.provider, 'Provider is not defined');
|
|
90
|
+
this.provider.removeListener('networkChanged', this.handleNetworkChanged);
|
|
91
|
+
this.provider.removeListener('chainChanged', this.handleChainChanged);
|
|
92
|
+
this.provider.removeListener('accountsChanged', this.handleAccountsChanged);
|
|
93
|
+
this.provider.removeListener('close', this.handleClose);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export { LedgerHQFrameConnector };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/iframe/helpers.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ,QAAO,OAM3B,CAAC;AAEF,eAAO,MAAM,2BAA2B,QAG3B,OAcT,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const isIframe = () => {
|
|
2
|
+
try {
|
|
3
|
+
return window.self !== window.top;
|
|
4
|
+
} catch (error) {
|
|
5
|
+
return false;
|
|
6
|
+
}
|
|
7
|
+
};
|
|
8
|
+
const isLedgerDappBrowserProvider = (() => {
|
|
9
|
+
let state = null;
|
|
10
|
+
return () => {
|
|
11
|
+
if (typeof state === 'boolean') return state;
|
|
12
|
+
if (typeof window === 'undefined') return false;
|
|
13
|
+
try {
|
|
14
|
+
const params = new URLSearchParams(window.self.location.search);
|
|
15
|
+
const isEmbed = !!params.get('embed');
|
|
16
|
+
state = isIframe() && isEmbed;
|
|
17
|
+
} catch (error) {
|
|
18
|
+
state = false;
|
|
19
|
+
}
|
|
20
|
+
return state;
|
|
21
|
+
};
|
|
22
|
+
})();
|
|
23
|
+
|
|
24
|
+
export { isIframe, isLedgerDappBrowserProvider };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/iframe/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAC1C,cAAc,UAAU,CAAC"}
|
package/dist/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@reef-knot/ledger-connector",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"main": "dist/index.js",
|
|
5
|
+
"types": "dist/index.d.ts",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"typesVersions": {
|
|
10
|
+
"*": {
|
|
11
|
+
".": [
|
|
12
|
+
"dist/index.d.ts"
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"type": "module",
|
|
17
|
+
"files": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"homepage": "https://github.com/lidofinance/reef-knot",
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/lidofinance/reef-knot/issues"
|
|
24
|
+
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"registry": "https://registry.npmjs.org/",
|
|
27
|
+
"access": "public"
|
|
28
|
+
},
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "rollup -c",
|
|
31
|
+
"dev": "dev=on rollup -c -w",
|
|
32
|
+
"lint": "eslint"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/w3c-web-hid": "^1.0.2"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@ethersproject/abstract-signer": "^5.5.0",
|
|
39
|
+
"@ethersproject/bignumber": "^5.5.0",
|
|
40
|
+
"@ethersproject/bytes": "^5.5.0",
|
|
41
|
+
"@ethersproject/properties": "^5.5.0",
|
|
42
|
+
"@ethersproject/providers": "^5.5.2",
|
|
43
|
+
"@ethersproject/strings": "^5.5.0",
|
|
44
|
+
"@ethersproject/transactions": "^5.5.0",
|
|
45
|
+
"@ledgerhq/hw-app-eth": "^6.33.1",
|
|
46
|
+
"@ledgerhq/hw-transport": "^6.28.2",
|
|
47
|
+
"@ledgerhq/hw-transport-webhid": "^6.27.13",
|
|
48
|
+
"@ledgerhq/iframe-provider": "0",
|
|
49
|
+
"@web3-react/abstract-connector": "^6.0.7",
|
|
50
|
+
"@web3-react/types": "^6.0.7",
|
|
51
|
+
"tiny-invariant": "^1.2.0"
|
|
52
|
+
}
|
|
53
|
+
}
|