@cityofzion/bs-ethereum 2.2.13 → 2.3.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/BSEthereum.d.ts +6 -6
- package/dist/BSEthereum.js +66 -50
- package/dist/{BSEthereumHelper.d.ts → constants/BSEthereumConstants.d.ts} +6 -15
- package/dist/constants/BSEthereumConstants.js +235 -0
- package/dist/helpers/BSEthereumHelper.d.ts +16 -0
- package/dist/helpers/BSEthereumHelper.js +58 -0
- package/dist/index.d.ts +11 -7
- package/dist/index.js +11 -7
- package/dist/{BlockscoutNeoXBDSEthereum.d.ts → services/blockchain-data/BlockscoutBDSEthereum.d.ts} +2 -2
- package/dist/{BlockscoutNeoXBDSEthereum.js → services/blockchain-data/BlockscoutBDSEthereum.js} +23 -22
- package/dist/{MoralisBDSEthereum.d.ts → services/blockchain-data/MoralisBDSEthereum.d.ts} +1 -1
- package/dist/{MoralisBDSEthereum.js → services/blockchain-data/MoralisBDSEthereum.js} +2 -2
- package/dist/{RpcBDSEthereum.d.ts → services/blockchain-data/RpcBDSEthereum.d.ts} +1 -1
- package/dist/{RpcBDSEthereum.js → services/blockchain-data/RpcBDSEthereum.js} +2 -2
- package/dist/{BlockscoutNeoXEDSEthereum.d.ts → services/exchange-data/BlockscoutEDSEthereum.d.ts} +1 -1
- package/dist/{BlockscoutNeoXEDSEthereum.js → services/exchange-data/BlockscoutEDSEthereum.js} +17 -15
- package/dist/{MoralisEDSEthereum.d.ts → services/exchange-data/MoralisEDSEthereum.d.ts} +1 -1
- package/dist/{MoralisEDSEthereum.js → services/exchange-data/MoralisEDSEthereum.js} +2 -2
- package/dist/{BlockscoutNeoXESEthereum.d.ts → services/explorer/BlockscoutESEthereum.d.ts} +2 -2
- package/dist/{BlockscoutNeoXESEthereum.js → services/explorer/BlockscoutESEthereum.js} +25 -16
- package/dist/{EthersLedgerServiceEthereum.d.ts → services/ledger/EthersLedgerServiceEthereum.d.ts} +8 -7
- package/dist/{EthersLedgerServiceEthereum.js → services/ledger/EthersLedgerServiceEthereum.js} +40 -58
- package/dist/{GhostMarketNDSEthereum.d.ts → services/nft-data/GhostMarketNDSEthereum.d.ts} +1 -1
- package/dist/{RpcNDSEthereum.js → services/nft-data/RpcNDSEthereum.js} +1 -1
- package/package.json +2 -2
- package/dist/BSEthereumHelper.js +0 -259
- /package/dist/{GhostMarketNDSEthereum.js → services/nft-data/GhostMarketNDSEthereum.js} +0 -0
- /package/dist/{RpcNDSEthereum.d.ts → services/nft-data/RpcNDSEthereum.d.ts} +0 -0
package/dist/{BlockscoutNeoXBDSEthereum.js → services/blockchain-data/BlockscoutBDSEthereum.js}
RENAMED
|
@@ -12,18 +12,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.
|
|
15
|
+
exports.BlockscoutBDSEthereum = void 0;
|
|
16
16
|
const axios_1 = __importDefault(require("axios"));
|
|
17
17
|
const RpcBDSEthereum_1 = require("./RpcBDSEthereum");
|
|
18
|
-
const BSEthereumHelper_1 = require("./BSEthereumHelper");
|
|
19
18
|
const ethers_1 = require("ethers");
|
|
20
|
-
const ERC20_1 = require("
|
|
21
|
-
|
|
19
|
+
const ERC20_1 = require("../../assets/abis/ERC20");
|
|
20
|
+
const BSEthereumConstants_1 = require("../../constants/BSEthereumConstants");
|
|
21
|
+
const BSEthereumHelper_1 = require("../../helpers/BSEthereumHelper");
|
|
22
|
+
class BlockscoutBDSEthereum extends RpcBDSEthereum_1.RpcBDSEthereum {
|
|
22
23
|
static isSupported(network) {
|
|
23
|
-
return !!
|
|
24
|
+
return !!BlockscoutBDSEthereum.BASE_URL_BY_CHAIN_ID[network.id];
|
|
24
25
|
}
|
|
25
26
|
static getClient(network) {
|
|
26
|
-
const baseURL =
|
|
27
|
+
const baseURL = BlockscoutBDSEthereum.BASE_URL_BY_CHAIN_ID[network.id];
|
|
27
28
|
if (!baseURL) {
|
|
28
29
|
throw new Error('Unsupported network');
|
|
29
30
|
}
|
|
@@ -40,10 +41,10 @@ class BlockscoutNeoXBDSEthereum extends RpcBDSEthereum_1.RpcBDSEthereum {
|
|
|
40
41
|
getTransaction: { get: () => super.getTransaction }
|
|
41
42
|
});
|
|
42
43
|
return __awaiter(this, void 0, void 0, function* () {
|
|
43
|
-
if (!
|
|
44
|
+
if (!BlockscoutBDSEthereum.isSupported(this._network)) {
|
|
44
45
|
return _super.getTransaction.call(this, txid);
|
|
45
46
|
}
|
|
46
|
-
const client =
|
|
47
|
+
const client = BlockscoutBDSEthereum.getClient(this._network);
|
|
47
48
|
const { data } = yield client.get(`/transactions/${txid}`);
|
|
48
49
|
if (!data || 'message' in data) {
|
|
49
50
|
throw new Error('Transaction not found');
|
|
@@ -106,10 +107,10 @@ class BlockscoutNeoXBDSEthereum extends RpcBDSEthereum_1.RpcBDSEthereum {
|
|
|
106
107
|
getTransactionsByAddress: { get: () => super.getTransactionsByAddress }
|
|
107
108
|
});
|
|
108
109
|
return __awaiter(this, void 0, void 0, function* () {
|
|
109
|
-
if (!
|
|
110
|
+
if (!BlockscoutBDSEthereum.isSupported(this._network)) {
|
|
110
111
|
return _super.getTransactionsByAddress.call(this, params);
|
|
111
112
|
}
|
|
112
|
-
const client =
|
|
113
|
+
const client = BlockscoutBDSEthereum.getClient(this._network);
|
|
113
114
|
const { data } = yield client.get(`/addresses/${params.address}/transactions`, {
|
|
114
115
|
params: {
|
|
115
116
|
next_page_params: params.nextPageParams,
|
|
@@ -177,11 +178,11 @@ class BlockscoutNeoXBDSEthereum extends RpcBDSEthereum_1.RpcBDSEthereum {
|
|
|
177
178
|
getContract: { get: () => super.getContract }
|
|
178
179
|
});
|
|
179
180
|
return __awaiter(this, void 0, void 0, function* () {
|
|
180
|
-
if (!
|
|
181
|
+
if (!BlockscoutBDSEthereum.isSupported(this._network)) {
|
|
181
182
|
return _super.getContract.call(this, contractHash);
|
|
182
183
|
}
|
|
183
184
|
try {
|
|
184
|
-
const client =
|
|
185
|
+
const client = BlockscoutBDSEthereum.getClient(this._network);
|
|
185
186
|
const { data } = yield client.get(`/smart-contracts/${contractHash}`);
|
|
186
187
|
if (!data || 'message' in data) {
|
|
187
188
|
throw new Error('Contract not found');
|
|
@@ -216,7 +217,7 @@ class BlockscoutNeoXBDSEthereum extends RpcBDSEthereum_1.RpcBDSEthereum {
|
|
|
216
217
|
getTokenInfo: { get: () => super.getTokenInfo }
|
|
217
218
|
});
|
|
218
219
|
return __awaiter(this, void 0, void 0, function* () {
|
|
219
|
-
if (!
|
|
220
|
+
if (!BlockscoutBDSEthereum.isSupported(this._network)) {
|
|
220
221
|
return _super.getTokenInfo.call(this, tokenHash);
|
|
221
222
|
}
|
|
222
223
|
const nativeAsset = BSEthereumHelper_1.BSEthereumHelper.getNativeAsset(this._network);
|
|
@@ -226,7 +227,7 @@ class BlockscoutNeoXBDSEthereum extends RpcBDSEthereum_1.RpcBDSEthereum {
|
|
|
226
227
|
if (this._tokenCache.has(tokenHash)) {
|
|
227
228
|
return this._tokenCache.get(tokenHash);
|
|
228
229
|
}
|
|
229
|
-
const client =
|
|
230
|
+
const client = BlockscoutBDSEthereum.getClient(this._network);
|
|
230
231
|
const { data } = yield client.get(`/tokens/${tokenHash}`);
|
|
231
232
|
if (!data || 'message' in data) {
|
|
232
233
|
throw new Error('Token not found');
|
|
@@ -235,7 +236,7 @@ class BlockscoutNeoXBDSEthereum extends RpcBDSEthereum_1.RpcBDSEthereum {
|
|
|
235
236
|
throw new Error('Token is not an ERC-20 token');
|
|
236
237
|
}
|
|
237
238
|
return {
|
|
238
|
-
decimals: data.decimals ? parseInt(data.decimals) :
|
|
239
|
+
decimals: data.decimals ? parseInt(data.decimals) : BSEthereumConstants_1.BSEthereumConstants.DEFAULT_DECIMALS,
|
|
239
240
|
hash: tokenHash,
|
|
240
241
|
name: data.name,
|
|
241
242
|
symbol: data.symbol,
|
|
@@ -247,10 +248,10 @@ class BlockscoutNeoXBDSEthereum extends RpcBDSEthereum_1.RpcBDSEthereum {
|
|
|
247
248
|
getBalance: { get: () => super.getBalance }
|
|
248
249
|
});
|
|
249
250
|
return __awaiter(this, void 0, void 0, function* () {
|
|
250
|
-
if (!
|
|
251
|
+
if (!BlockscoutBDSEthereum.isSupported(this._network)) {
|
|
251
252
|
return _super.getBalance.call(this, address);
|
|
252
253
|
}
|
|
253
|
-
const client =
|
|
254
|
+
const client = BlockscoutBDSEthereum.getClient(this._network);
|
|
254
255
|
const { data: nativeBalance } = yield client.get(`/addresses/${address}`);
|
|
255
256
|
if (!nativeBalance || 'message' in nativeBalance) {
|
|
256
257
|
throw new Error('Native balance not found');
|
|
@@ -272,7 +273,7 @@ class BlockscoutNeoXBDSEthereum extends RpcBDSEthereum_1.RpcBDSEthereum {
|
|
|
272
273
|
return;
|
|
273
274
|
}
|
|
274
275
|
const token = {
|
|
275
|
-
decimals: balance.token.decimals ? parseInt(balance.token.decimals) :
|
|
276
|
+
decimals: balance.token.decimals ? parseInt(balance.token.decimals) : BSEthereumConstants_1.BSEthereumConstants.DEFAULT_DECIMALS,
|
|
276
277
|
hash: balance.token.address,
|
|
277
278
|
name: balance.token.symbol,
|
|
278
279
|
symbol: balance.token.symbol,
|
|
@@ -294,10 +295,10 @@ class BlockscoutNeoXBDSEthereum extends RpcBDSEthereum_1.RpcBDSEthereum {
|
|
|
294
295
|
getBlockHeight: { get: () => super.getBlockHeight }
|
|
295
296
|
});
|
|
296
297
|
return __awaiter(this, void 0, void 0, function* () {
|
|
297
|
-
if (!
|
|
298
|
+
if (!BlockscoutBDSEthereum.isSupported(this._network)) {
|
|
298
299
|
return _super.getBlockHeight.call(this);
|
|
299
300
|
}
|
|
300
|
-
const client =
|
|
301
|
+
const client = BlockscoutBDSEthereum.getClient(this._network);
|
|
301
302
|
const { data } = yield client.get('/blocks');
|
|
302
303
|
if (!data || 'message' in data) {
|
|
303
304
|
throw new Error('Block not found');
|
|
@@ -306,8 +307,8 @@ class BlockscoutNeoXBDSEthereum extends RpcBDSEthereum_1.RpcBDSEthereum {
|
|
|
306
307
|
});
|
|
307
308
|
}
|
|
308
309
|
}
|
|
309
|
-
exports.
|
|
310
|
-
|
|
310
|
+
exports.BlockscoutBDSEthereum = BlockscoutBDSEthereum;
|
|
311
|
+
BlockscoutBDSEthereum.BASE_URL_BY_CHAIN_ID = {
|
|
311
312
|
'12227332': 'https://dora-stage.coz.io/api/neox/testnet',
|
|
312
313
|
'47763': 'https://dora.coz.io/api/neox/mainnet',
|
|
313
314
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BalanceResponse, ContractResponse, Network, Token, TransactionResponse, TransactionsByAddressParams, TransactionsByAddressResponse } from '@cityofzion/blockchain-service';
|
|
2
2
|
import { RpcBDSEthereum } from './RpcBDSEthereum';
|
|
3
|
-
import { BSEthereumNetworkId } from '
|
|
3
|
+
import { BSEthereumNetworkId } from '../../constants/BSEthereumConstants';
|
|
4
4
|
export declare class MoralisBDSEthereum extends RpcBDSEthereum {
|
|
5
5
|
static BASE_URL: string;
|
|
6
6
|
static SUPPORTED_CHAINS: string[];
|
|
@@ -14,10 +14,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.MoralisBDSEthereum = void 0;
|
|
16
16
|
const RpcBDSEthereum_1 = require("./RpcBDSEthereum");
|
|
17
|
-
const BSEthereumHelper_1 = require("./BSEthereumHelper");
|
|
18
17
|
const axios_1 = __importDefault(require("axios"));
|
|
19
18
|
const ethers_1 = require("ethers");
|
|
20
|
-
const
|
|
19
|
+
const BSEthereumHelper_1 = require("../../helpers/BSEthereumHelper");
|
|
20
|
+
const ERC20_1 = require("../../assets/abis/ERC20");
|
|
21
21
|
class MoralisBDSEthereum extends RpcBDSEthereum_1.RpcBDSEthereum {
|
|
22
22
|
static getClient(network) {
|
|
23
23
|
return axios_1.default.create({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BalanceResponse, BlockchainDataService, ContractResponse, Network, RpcResponse, Token, TransactionResponse, TransactionsByAddressParams, TransactionsByAddressResponse } from '@cityofzion/blockchain-service';
|
|
2
|
-
import { BSEthereumNetworkId } from '
|
|
2
|
+
import { BSEthereumNetworkId } from '../../constants/BSEthereumConstants';
|
|
3
3
|
export declare class RpcBDSEthereum implements BlockchainDataService {
|
|
4
4
|
_network: Network<BSEthereumNetworkId>;
|
|
5
5
|
_tokenCache: Map<string, Token>;
|
|
@@ -11,8 +11,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.RpcBDSEthereum = void 0;
|
|
13
13
|
const ethers_1 = require("ethers");
|
|
14
|
-
const
|
|
15
|
-
const
|
|
14
|
+
const BSEthereumHelper_1 = require("../../helpers/BSEthereumHelper");
|
|
15
|
+
const ERC20_1 = require("../../assets/abis/ERC20");
|
|
16
16
|
class RpcBDSEthereum {
|
|
17
17
|
constructor(network) {
|
|
18
18
|
this._tokenCache = new Map();
|
package/dist/{BlockscoutNeoXEDSEthereum.d.ts → services/exchange-data/BlockscoutEDSEthereum.d.ts}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CryptoCompareEDS, ExchangeDataService, GetTokenPriceHistoryParams, GetTokenPricesParams, Network, TokenPricesHistoryResponse, TokenPricesResponse } from '@cityofzion/blockchain-service';
|
|
2
|
-
export declare class
|
|
2
|
+
export declare class BlockscoutEDSEthereum extends CryptoCompareEDS implements ExchangeDataService {
|
|
3
3
|
#private;
|
|
4
4
|
constructor(network: Network);
|
|
5
5
|
getTokenPrices(params: GetTokenPricesParams): Promise<TokenPricesResponse[]>;
|
package/dist/{BlockscoutNeoXEDSEthereum.js → services/exchange-data/BlockscoutEDSEthereum.js}
RENAMED
|
@@ -19,42 +19,44 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
19
19
|
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");
|
|
20
20
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
21
21
|
};
|
|
22
|
-
var
|
|
22
|
+
var _BlockscoutEDSEthereum_network;
|
|
23
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
-
exports.
|
|
24
|
+
exports.BlockscoutEDSEthereum = void 0;
|
|
25
25
|
const blockchain_service_1 = require("@cityofzion/blockchain-service");
|
|
26
|
-
const BSEthereumHelper_1 = require("
|
|
27
|
-
const
|
|
28
|
-
class
|
|
26
|
+
const BSEthereumHelper_1 = require("../../helpers/BSEthereumHelper");
|
|
27
|
+
const BlockscoutBDSEthereum_1 = require("../blockchain-data/BlockscoutBDSEthereum");
|
|
28
|
+
class BlockscoutEDSEthereum extends blockchain_service_1.CryptoCompareEDS {
|
|
29
29
|
constructor(network) {
|
|
30
30
|
super();
|
|
31
|
-
|
|
32
|
-
__classPrivateFieldSet(this,
|
|
31
|
+
_BlockscoutEDSEthereum_network.set(this, void 0);
|
|
32
|
+
__classPrivateFieldSet(this, _BlockscoutEDSEthereum_network, network, "f");
|
|
33
33
|
}
|
|
34
34
|
getTokenPrices(params) {
|
|
35
35
|
return __awaiter(this, void 0, void 0, function* () {
|
|
36
|
-
if (!BSEthereumHelper_1.BSEthereumHelper.isMainnet(__classPrivateFieldGet(this,
|
|
36
|
+
if (!BSEthereumHelper_1.BSEthereumHelper.isMainnet(__classPrivateFieldGet(this, _BlockscoutEDSEthereum_network, "f")))
|
|
37
37
|
throw new Error('Exchange is only available on mainnet');
|
|
38
|
-
if (!
|
|
38
|
+
if (!BlockscoutBDSEthereum_1.BlockscoutBDSEthereum.isSupported(__classPrivateFieldGet(this, _BlockscoutEDSEthereum_network, "f"))) {
|
|
39
39
|
throw new Error('Exchange is not supported on this network');
|
|
40
40
|
}
|
|
41
|
-
const client =
|
|
42
|
-
const nativeToken = BSEthereumHelper_1.BSEthereumHelper.getNativeAsset(__classPrivateFieldGet(this,
|
|
41
|
+
const client = BlockscoutBDSEthereum_1.BlockscoutBDSEthereum.getClient(__classPrivateFieldGet(this, _BlockscoutEDSEthereum_network, "f"));
|
|
42
|
+
const nativeToken = BSEthereumHelper_1.BSEthereumHelper.getNativeAsset(__classPrivateFieldGet(this, _BlockscoutEDSEthereum_network, "f"));
|
|
43
43
|
const prices = [];
|
|
44
44
|
const promises = params.tokens.map((token) => __awaiter(this, void 0, void 0, function* () {
|
|
45
45
|
try {
|
|
46
46
|
if (BSEthereumHelper_1.BSEthereumHelper.normalizeHash(token.hash) !== BSEthereumHelper_1.BSEthereumHelper.normalizeHash(nativeToken.hash)) {
|
|
47
47
|
const { data } = yield client.get(`/tokens/${token.hash}`);
|
|
48
|
+
const exchangeRateNumber = Number(data.exchange_rate);
|
|
48
49
|
prices.push({
|
|
49
50
|
token,
|
|
50
|
-
usdPrice:
|
|
51
|
+
usdPrice: isNaN(exchangeRateNumber) ? 0 : exchangeRateNumber,
|
|
51
52
|
});
|
|
52
53
|
return;
|
|
53
54
|
}
|
|
54
55
|
const { data } = yield client.get(`/stats`);
|
|
56
|
+
const coinPriceNumber = Number(data.coin_price);
|
|
55
57
|
prices.push({
|
|
56
58
|
token,
|
|
57
|
-
usdPrice:
|
|
59
|
+
usdPrice: isNaN(coinPriceNumber) ? 0 : coinPriceNumber,
|
|
58
60
|
});
|
|
59
61
|
}
|
|
60
62
|
catch (_a) {
|
|
@@ -72,5 +74,5 @@ class BlockscoutNeoXEDSEthereum extends blockchain_service_1.CryptoCompareEDS {
|
|
|
72
74
|
throw new Error('Blockscout does not support this feature');
|
|
73
75
|
}
|
|
74
76
|
}
|
|
75
|
-
exports.
|
|
76
|
-
|
|
77
|
+
exports.BlockscoutEDSEthereum = BlockscoutEDSEthereum;
|
|
78
|
+
_BlockscoutEDSEthereum_network = new WeakMap();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BlockchainDataService, CryptoCompareEDS, ExchangeDataService, GetTokenPriceHistoryParams, GetTokenPricesParams, Network, TokenPricesHistoryResponse, TokenPricesResponse } from '@cityofzion/blockchain-service';
|
|
2
|
-
import { BSEthereumNetworkId } from '
|
|
2
|
+
import { BSEthereumNetworkId } from '../../constants/BSEthereumConstants';
|
|
3
3
|
export declare class MoralisEDSEthereum extends CryptoCompareEDS implements ExchangeDataService {
|
|
4
4
|
#private;
|
|
5
5
|
constructor(network: Network<BSEthereumNetworkId>, blockchainDataService: BlockchainDataService);
|
|
@@ -23,8 +23,8 @@ var _MoralisEDSEthereum_instances, _MoralisEDSEthereum_network, _MoralisEDSEther
|
|
|
23
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
24
|
exports.MoralisEDSEthereum = void 0;
|
|
25
25
|
const blockchain_service_1 = require("@cityofzion/blockchain-service");
|
|
26
|
-
const BSEthereumHelper_1 = require("
|
|
27
|
-
const MoralisBDSEthereum_1 = require("
|
|
26
|
+
const BSEthereumHelper_1 = require("../../helpers/BSEthereumHelper");
|
|
27
|
+
const MoralisBDSEthereum_1 = require("../blockchain-data/MoralisBDSEthereum");
|
|
28
28
|
class MoralisEDSEthereum extends blockchain_service_1.CryptoCompareEDS {
|
|
29
29
|
constructor(network, blockchainDataService) {
|
|
30
30
|
super();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BuildNftUrlParams, ExplorerService, Network } from '@cityofzion/blockchain-service';
|
|
2
|
-
import { BSEthereumNetworkId } from '
|
|
3
|
-
export declare class
|
|
2
|
+
import { BSEthereumNetworkId } from '../../constants/BSEthereumConstants';
|
|
3
|
+
export declare class BlockscoutESEthereum implements ExplorerService {
|
|
4
4
|
#private;
|
|
5
5
|
static BASE_URL_BY_CHAIN_ID: Partial<Record<BSEthereumNetworkId, string>>;
|
|
6
6
|
static isSupported(network: Network<BSEthereumNetworkId>): boolean;
|
|
@@ -10,42 +10,51 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
10
10
|
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");
|
|
11
11
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
12
|
};
|
|
13
|
-
var
|
|
13
|
+
var _BlockscoutESEthereum_network;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.
|
|
16
|
-
class
|
|
15
|
+
exports.BlockscoutESEthereum = void 0;
|
|
16
|
+
class BlockscoutESEthereum {
|
|
17
17
|
static isSupported(network) {
|
|
18
|
-
return !!
|
|
18
|
+
return !!BlockscoutESEthereum.BASE_URL_BY_CHAIN_ID[network.id];
|
|
19
19
|
}
|
|
20
20
|
constructor(network) {
|
|
21
|
-
|
|
22
|
-
__classPrivateFieldSet(this,
|
|
21
|
+
_BlockscoutESEthereum_network.set(this, void 0);
|
|
22
|
+
__classPrivateFieldSet(this, _BlockscoutESEthereum_network, network, "f");
|
|
23
23
|
}
|
|
24
24
|
buildTransactionUrl(hash) {
|
|
25
|
-
if (!
|
|
25
|
+
if (!BlockscoutESEthereum.isSupported(__classPrivateFieldGet(this, _BlockscoutESEthereum_network, "f"))) {
|
|
26
26
|
throw new Error('Network not supported');
|
|
27
27
|
}
|
|
28
|
-
const baseURL =
|
|
28
|
+
const baseURL = BlockscoutESEthereum.BASE_URL_BY_CHAIN_ID[__classPrivateFieldGet(this, _BlockscoutESEthereum_network, "f").id];
|
|
29
29
|
return `${baseURL}/tx/${hash}`;
|
|
30
30
|
}
|
|
31
31
|
buildContractUrl(contractHash) {
|
|
32
|
-
if (!
|
|
32
|
+
if (!BlockscoutESEthereum.isSupported(__classPrivateFieldGet(this, _BlockscoutESEthereum_network, "f"))) {
|
|
33
33
|
throw new Error('Network not supported');
|
|
34
34
|
}
|
|
35
|
-
const baseURL =
|
|
35
|
+
const baseURL = BlockscoutESEthereum.BASE_URL_BY_CHAIN_ID[__classPrivateFieldGet(this, _BlockscoutESEthereum_network, "f").id];
|
|
36
36
|
return `${baseURL}/address/${contractHash}`;
|
|
37
37
|
}
|
|
38
38
|
buildNftUrl(params) {
|
|
39
|
-
if (!
|
|
39
|
+
if (!BlockscoutESEthereum.isSupported(__classPrivateFieldGet(this, _BlockscoutESEthereum_network, "f"))) {
|
|
40
40
|
throw new Error('Network not supported');
|
|
41
41
|
}
|
|
42
|
-
const baseURL =
|
|
42
|
+
const baseURL = BlockscoutESEthereum.BASE_URL_BY_CHAIN_ID[__classPrivateFieldGet(this, _BlockscoutESEthereum_network, "f").id];
|
|
43
43
|
return `${baseURL}/token/${params.contractHash}/instance/${params.tokenId}`;
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
|
-
exports.
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
'
|
|
46
|
+
exports.BlockscoutESEthereum = BlockscoutESEthereum;
|
|
47
|
+
_BlockscoutESEthereum_network = new WeakMap();
|
|
48
|
+
BlockscoutESEthereum.BASE_URL_BY_CHAIN_ID = {
|
|
49
|
+
'1': 'https://eth.blockscout.com',
|
|
50
|
+
'10': 'https://optimism.blockscout.com',
|
|
51
|
+
'137': 'https://polygon.blockscout.com',
|
|
52
|
+
'8453': 'https://base.blockscout.com',
|
|
53
|
+
'42161': 'https://arbitrum.blockscout.com',
|
|
54
|
+
'42220': 'https://explorer.celo.org/mainnet',
|
|
50
55
|
'47763': 'https://xexplorer.neo.org',
|
|
56
|
+
'59144': 'https://explorer.linea.build',
|
|
57
|
+
'1101': 'https://zkevm.blockscout.com',
|
|
58
|
+
'11155111': 'https://eth-sepolia.blockscout.com',
|
|
59
|
+
'12227332': 'https://xt4scan.ngd.network',
|
|
51
60
|
};
|
package/dist/{EthersLedgerServiceEthereum.d.ts → services/ledger/EthersLedgerServiceEthereum.d.ts}
RENAMED
|
@@ -2,21 +2,22 @@ import { Account, LedgerService, LedgerServiceEmitter } from '@cityofzion/blockc
|
|
|
2
2
|
import Transport from '@ledgerhq/hw-transport';
|
|
3
3
|
import { ethers, Signer } from 'ethers';
|
|
4
4
|
import { TypedDataSigner } from '@ethersproject/abstract-signer';
|
|
5
|
+
import { BSEthereum } from '../../BSEthereum';
|
|
5
6
|
export declare class EthersLedgerSigner extends Signer implements TypedDataSigner {
|
|
6
7
|
#private;
|
|
7
|
-
constructor(transport: Transport, provider?: ethers.providers.Provider, emitter?: LedgerServiceEmitter);
|
|
8
|
+
constructor(transport: Transport, bip44Path: string, provider?: ethers.providers.Provider, emitter?: LedgerServiceEmitter);
|
|
8
9
|
connect(provider: ethers.providers.Provider): EthersLedgerSigner;
|
|
9
10
|
getAddress(): Promise<string>;
|
|
10
|
-
getPublicKey(): Promise<string>;
|
|
11
11
|
signMessage(message: string | ethers.utils.Bytes): Promise<string>;
|
|
12
12
|
signTransaction(transaction: ethers.utils.Deferrable<ethers.providers.TransactionRequest>): Promise<string>;
|
|
13
13
|
_signTypedData(domain: ethers.TypedDataDomain, types: Record<string, ethers.TypedDataField[]>, value: Record<string, any>): Promise<string>;
|
|
14
14
|
}
|
|
15
15
|
export declare class EthersLedgerServiceEthereum implements LedgerService {
|
|
16
|
-
|
|
16
|
+
#private;
|
|
17
17
|
emitter: LedgerServiceEmitter;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
getLedgerTransport?: (account: Account) => Promise<Transport>;
|
|
19
|
+
constructor(blockchainService: BSEthereum, getLedgerTransport?: (account: Account) => Promise<Transport>);
|
|
20
|
+
getAccounts(transport: Transport): Promise<Account[]>;
|
|
21
|
+
getAccount(transport: Transport, index: number): Promise<Account>;
|
|
22
|
+
getSigner(transport: Transport, path: string, provider?: ethers.providers.Provider): EthersLedgerSigner;
|
|
22
23
|
}
|
package/dist/{EthersLedgerServiceEthereum.js → services/ledger/EthersLedgerServiceEthereum.js}
RENAMED
|
@@ -45,41 +45,35 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
45
45
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
46
46
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
47
47
|
};
|
|
48
|
-
var
|
|
48
|
+
var _EthersLedgerSigner_transport, _EthersLedgerSigner_emitter, _EthersLedgerSigner_bip44Path, _EthersLedgerSigner_ledgerApp, _EthersLedgerServiceEthereum_blockchainService;
|
|
49
49
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
50
|
exports.EthersLedgerServiceEthereum = exports.EthersLedgerSigner = void 0;
|
|
51
|
+
const blockchain_service_1 = require("@cityofzion/blockchain-service");
|
|
51
52
|
const hw_app_eth_1 = __importStar(require("@ledgerhq/hw-app-eth"));
|
|
52
53
|
const ethers_1 = require("ethers");
|
|
53
54
|
const properties_1 = require("@ethersproject/properties");
|
|
54
55
|
const events_1 = __importDefault(require("events"));
|
|
55
|
-
const BSEthereumHelper_1 = require("
|
|
56
|
+
const BSEthereumHelper_1 = require("../../helpers/BSEthereumHelper");
|
|
56
57
|
class EthersLedgerSigner extends ethers_1.Signer {
|
|
57
|
-
constructor(transport, provider, emitter) {
|
|
58
|
+
constructor(transport, bip44Path, provider, emitter) {
|
|
58
59
|
super();
|
|
59
|
-
_EthersLedgerSigner_instances.add(this);
|
|
60
60
|
_EthersLedgerSigner_transport.set(this, void 0);
|
|
61
61
|
_EthersLedgerSigner_emitter.set(this, void 0);
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
_EthersLedgerSigner_bip44Path.set(this, void 0);
|
|
63
|
+
_EthersLedgerSigner_ledgerApp.set(this, void 0);
|
|
64
|
+
__classPrivateFieldSet(this, _EthersLedgerSigner_bip44Path, bip44Path, "f");
|
|
64
65
|
__classPrivateFieldSet(this, _EthersLedgerSigner_transport, transport, "f");
|
|
65
66
|
__classPrivateFieldSet(this, _EthersLedgerSigner_emitter, emitter, "f");
|
|
67
|
+
__classPrivateFieldSet(this, _EthersLedgerSigner_ledgerApp, new hw_app_eth_1.default(transport), "f");
|
|
66
68
|
(0, properties_1.defineReadOnly)(this, 'provider', provider);
|
|
67
69
|
}
|
|
68
70
|
connect(provider) {
|
|
69
|
-
return new EthersLedgerSigner(__classPrivateFieldGet(this, _EthersLedgerSigner_transport, "f"), provider, __classPrivateFieldGet(this, _EthersLedgerSigner_emitter, "f"));
|
|
71
|
+
return new EthersLedgerSigner(__classPrivateFieldGet(this, _EthersLedgerSigner_transport, "f"), __classPrivateFieldGet(this, _EthersLedgerSigner_bip44Path, "f"), provider, __classPrivateFieldGet(this, _EthersLedgerSigner_emitter, "f"));
|
|
70
72
|
}
|
|
71
73
|
getAddress() {
|
|
72
74
|
return __awaiter(this, void 0, void 0, function* () {
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
return ethers_1.ethers.utils.getAddress(address);
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
getPublicKey() {
|
|
79
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
80
|
-
const ledgerApp = new hw_app_eth_1.default(__classPrivateFieldGet(this, _EthersLedgerSigner_transport, "f"));
|
|
81
|
-
const { publicKey } = yield __classPrivateFieldGet(this, _EthersLedgerSigner_instances, "m", _EthersLedgerSigner_retry).call(this, () => ledgerApp.getAddress(__classPrivateFieldGet(this, _EthersLedgerSigner_path, "f")));
|
|
82
|
-
return '0x' + publicKey;
|
|
75
|
+
const { address } = yield __classPrivateFieldGet(this, _EthersLedgerSigner_ledgerApp, "f").getAddress(__classPrivateFieldGet(this, _EthersLedgerSigner_bip44Path, "f"));
|
|
76
|
+
return address;
|
|
83
77
|
});
|
|
84
78
|
}
|
|
85
79
|
signMessage(message) {
|
|
@@ -89,9 +83,8 @@ class EthersLedgerSigner extends ethers_1.Signer {
|
|
|
89
83
|
if (typeof message === 'string') {
|
|
90
84
|
message = ethers_1.ethers.utils.toUtf8Bytes(message);
|
|
91
85
|
}
|
|
92
|
-
const ledgerApp = new hw_app_eth_1.default(__classPrivateFieldGet(this, _EthersLedgerSigner_transport, "f"));
|
|
93
86
|
(_a = __classPrivateFieldGet(this, _EthersLedgerSigner_emitter, "f")) === null || _a === void 0 ? void 0 : _a.emit('getSignatureStart');
|
|
94
|
-
const obj = yield __classPrivateFieldGet(this,
|
|
87
|
+
const obj = yield BSEthereumHelper_1.BSEthereumHelper.retry(() => __classPrivateFieldGet(this, _EthersLedgerSigner_ledgerApp, "f").signPersonalMessage(__classPrivateFieldGet(this, _EthersLedgerSigner_bip44Path, "f"), ethers_1.ethers.utils.hexlify(message).substring(2)));
|
|
95
88
|
(_b = __classPrivateFieldGet(this, _EthersLedgerSigner_emitter, "f")) === null || _b === void 0 ? void 0 : _b.emit('getSignatureEnd');
|
|
96
89
|
// Normalize the signature for Ethers
|
|
97
90
|
obj.r = '0x' + obj.r;
|
|
@@ -108,7 +101,6 @@ class EthersLedgerSigner extends ethers_1.Signer {
|
|
|
108
101
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
109
102
|
return __awaiter(this, void 0, void 0, function* () {
|
|
110
103
|
try {
|
|
111
|
-
const ledgerApp = new hw_app_eth_1.default(__classPrivateFieldGet(this, _EthersLedgerSigner_transport, "f"));
|
|
112
104
|
const tx = yield ethers_1.ethers.utils.resolveProperties(transaction);
|
|
113
105
|
const unsignedTransaction = {
|
|
114
106
|
chainId: (_a = tx.chainId) !== null && _a !== void 0 ? _a : undefined,
|
|
@@ -122,7 +114,7 @@ class EthersLedgerSigner extends ethers_1.Signer {
|
|
|
122
114
|
const serializedUnsignedTransaction = ethers_1.ethers.utils.serializeTransaction(unsignedTransaction).substring(2);
|
|
123
115
|
const resolution = yield hw_app_eth_1.ledgerService.resolveTransaction(serializedUnsignedTransaction, {}, {});
|
|
124
116
|
(_g = __classPrivateFieldGet(this, _EthersLedgerSigner_emitter, "f")) === null || _g === void 0 ? void 0 : _g.emit('getSignatureStart');
|
|
125
|
-
const signature = yield __classPrivateFieldGet(this,
|
|
117
|
+
const signature = yield BSEthereumHelper_1.BSEthereumHelper.retry(() => __classPrivateFieldGet(this, _EthersLedgerSigner_ledgerApp, "f").signTransaction(__classPrivateFieldGet(this, _EthersLedgerSigner_bip44Path, "f"), serializedUnsignedTransaction, resolution));
|
|
126
118
|
(_h = __classPrivateFieldGet(this, _EthersLedgerSigner_emitter, "f")) === null || _h === void 0 ? void 0 : _h.emit('getSignatureEnd');
|
|
127
119
|
return ethers_1.ethers.utils.serializeTransaction(unsignedTransaction, {
|
|
128
120
|
v: ethers_1.ethers.BigNumber.from('0x' + signature.v).toNumber(),
|
|
@@ -149,16 +141,15 @@ class EthersLedgerSigner extends ethers_1.Signer {
|
|
|
149
141
|
return resolved;
|
|
150
142
|
}));
|
|
151
143
|
const payload = ethers_1.ethers.utils._TypedDataEncoder.getPayload(populated.domain, types, populated.value);
|
|
152
|
-
const ledgerApp = new hw_app_eth_1.default(__classPrivateFieldGet(this, _EthersLedgerSigner_transport, "f"));
|
|
153
144
|
(_a = __classPrivateFieldGet(this, _EthersLedgerSigner_emitter, "f")) === null || _a === void 0 ? void 0 : _a.emit('getSignatureStart');
|
|
154
145
|
let obj;
|
|
155
146
|
try {
|
|
156
|
-
obj = yield __classPrivateFieldGet(this,
|
|
147
|
+
obj = yield BSEthereumHelper_1.BSEthereumHelper.retry(() => __classPrivateFieldGet(this, _EthersLedgerSigner_ledgerApp, "f").signEIP712Message(__classPrivateFieldGet(this, _EthersLedgerSigner_bip44Path, "f"), payload));
|
|
157
148
|
}
|
|
158
149
|
catch (_d) {
|
|
159
150
|
const domainSeparatorHex = ethers_1.ethers.utils._TypedDataEncoder.hashDomain(payload.domain);
|
|
160
151
|
const hashStructMessageHex = ethers_1.ethers.utils._TypedDataEncoder.hashStruct(payload.primaryType, types, payload.message);
|
|
161
|
-
obj = yield __classPrivateFieldGet(this,
|
|
152
|
+
obj = yield BSEthereumHelper_1.BSEthereumHelper.retry(() => __classPrivateFieldGet(this, _EthersLedgerSigner_ledgerApp, "f").signEIP712HashedMessage(__classPrivateFieldGet(this, _EthersLedgerSigner_bip44Path, "f"), domainSeparatorHex, hashStructMessageHex));
|
|
162
153
|
}
|
|
163
154
|
(_b = __classPrivateFieldGet(this, _EthersLedgerSigner_emitter, "f")) === null || _b === void 0 ? void 0 : _b.emit('getSignatureEnd');
|
|
164
155
|
// Normalize the signature for Ethers
|
|
@@ -174,49 +165,40 @@ class EthersLedgerSigner extends ethers_1.Signer {
|
|
|
174
165
|
}
|
|
175
166
|
}
|
|
176
167
|
exports.EthersLedgerSigner = EthersLedgerSigner;
|
|
177
|
-
_EthersLedgerSigner_transport = new WeakMap(), _EthersLedgerSigner_emitter = new WeakMap(),
|
|
178
|
-
// eslint-disable-next-line no-async-promise-executor
|
|
179
|
-
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
|
180
|
-
// Wait up to 5 seconds
|
|
181
|
-
for (let i = 0; i < 50; i++) {
|
|
182
|
-
try {
|
|
183
|
-
const result = yield callback();
|
|
184
|
-
return resolve(result);
|
|
185
|
-
}
|
|
186
|
-
catch (error) {
|
|
187
|
-
if (error.id !== 'TransportLocked') {
|
|
188
|
-
return reject(error);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
yield wait(100);
|
|
192
|
-
}
|
|
193
|
-
return reject(new Error('timeout'));
|
|
194
|
-
}));
|
|
195
|
-
};
|
|
168
|
+
_EthersLedgerSigner_transport = new WeakMap(), _EthersLedgerSigner_emitter = new WeakMap(), _EthersLedgerSigner_bip44Path = new WeakMap(), _EthersLedgerSigner_ledgerApp = new WeakMap();
|
|
196
169
|
class EthersLedgerServiceEthereum {
|
|
197
|
-
constructor(getLedgerTransport) {
|
|
198
|
-
this
|
|
170
|
+
constructor(blockchainService, getLedgerTransport) {
|
|
171
|
+
_EthersLedgerServiceEthereum_blockchainService.set(this, void 0);
|
|
199
172
|
this.emitter = new events_1.default();
|
|
173
|
+
__classPrivateFieldSet(this, _EthersLedgerServiceEthereum_blockchainService, blockchainService, "f");
|
|
174
|
+
this.getLedgerTransport = getLedgerTransport;
|
|
200
175
|
}
|
|
201
|
-
|
|
176
|
+
getAccounts(transport) {
|
|
202
177
|
return __awaiter(this, void 0, void 0, function* () {
|
|
203
|
-
const
|
|
204
|
-
|
|
178
|
+
const accountsByBlockchainService = yield (0, blockchain_service_1.fetchAccountsForBlockchainServices)([__classPrivateFieldGet(this, _EthersLedgerServiceEthereum_blockchainService, "f")], (_service, index) => __awaiter(this, void 0, void 0, function* () {
|
|
179
|
+
return this.getAccount(transport, index);
|
|
180
|
+
}));
|
|
181
|
+
const accounts = accountsByBlockchainService.get(__classPrivateFieldGet(this, _EthersLedgerServiceEthereum_blockchainService, "f").blockchainName);
|
|
182
|
+
return accounts !== null && accounts !== void 0 ? accounts : [];
|
|
205
183
|
});
|
|
206
184
|
}
|
|
207
|
-
|
|
185
|
+
getAccount(transport, index) {
|
|
208
186
|
return __awaiter(this, void 0, void 0, function* () {
|
|
209
|
-
const
|
|
210
|
-
|
|
187
|
+
const ledgerApp = new hw_app_eth_1.default(transport);
|
|
188
|
+
const bip44Path = __classPrivateFieldGet(this, _EthersLedgerServiceEthereum_blockchainService, "f").bip44DerivationPath.replace('?', index.toString());
|
|
189
|
+
const { publicKey, address } = yield BSEthereumHelper_1.BSEthereumHelper.retry(() => ledgerApp.getAddress(bip44Path));
|
|
190
|
+
const publicKeyWithPrefix = '0x' + publicKey;
|
|
191
|
+
return {
|
|
192
|
+
address,
|
|
193
|
+
key: publicKeyWithPrefix,
|
|
194
|
+
type: 'publicKey',
|
|
195
|
+
bip44Path,
|
|
196
|
+
};
|
|
211
197
|
});
|
|
212
198
|
}
|
|
213
|
-
getSigner(transport, provider) {
|
|
214
|
-
return new EthersLedgerSigner(transport, provider, this.emitter);
|
|
199
|
+
getSigner(transport, path, provider) {
|
|
200
|
+
return new EthersLedgerSigner(transport, path, provider, this.emitter);
|
|
215
201
|
}
|
|
216
202
|
}
|
|
217
203
|
exports.EthersLedgerServiceEthereum = EthersLedgerServiceEthereum;
|
|
218
|
-
|
|
219
|
-
return new Promise(resolve => {
|
|
220
|
-
setTimeout(resolve, duration);
|
|
221
|
-
});
|
|
222
|
-
}
|
|
204
|
+
_EthersLedgerServiceEthereum_blockchainService = new WeakMap();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NftResponse, NftsResponse, GetNftParam, GetNftsByAddressParams, Network } from '@cityofzion/blockchain-service';
|
|
2
2
|
import { RpcNDSEthereum } from './RpcNDSEthereum';
|
|
3
|
-
import { BSEthereumNetworkId } from '
|
|
3
|
+
import { BSEthereumNetworkId } from '../../constants/BSEthereumConstants';
|
|
4
4
|
export declare class GhostMarketNDSEthereum extends RpcNDSEthereum {
|
|
5
5
|
#private;
|
|
6
6
|
static CONFIG_BY_NETWORK_ID: Partial<Record<BSEthereumNetworkId, {
|
|
@@ -23,7 +23,7 @@ var _RpcNDSEthereum_network;
|
|
|
23
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
24
|
exports.RpcNDSEthereum = void 0;
|
|
25
25
|
const ethers_1 = require("ethers");
|
|
26
|
-
const ERC20_1 = require("
|
|
26
|
+
const ERC20_1 = require("../../assets/abis/ERC20");
|
|
27
27
|
class RpcNDSEthereum {
|
|
28
28
|
constructor(network) {
|
|
29
29
|
_RpcNDSEthereum_network.set(this, void 0);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cityofzion/bs-ethereum",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"repository": "https://github.com/CityOfZion/blockchain-services",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"@ledgerhq/hw-app-eth": "~6.35.7",
|
|
21
21
|
"@ethersproject/abstract-signer": "~5.7.0",
|
|
22
22
|
"@ethersproject/properties": "~5.7.0",
|
|
23
|
-
"@cityofzion/blockchain-service": "1.
|
|
23
|
+
"@cityofzion/blockchain-service": "1.4.0"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@ledgerhq/hw-transport-node-hid": "~6.28.5",
|