@cityofzion/bs-ethereum 3.0.5 → 3.0.6

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.
@@ -1,19 +1,19 @@
1
- import { TBSAccount, TIntentTransferParam, TBSToken, TTransferParam, TGetLedgerTransport, ITokenService, TBSNetwork, IBlockchainDataService, IExchangeDataService, INftDataService, IExplorerService, TPingNetworkResponse, IWalletConnectService, type IFullTransactionsDataService } from '@cityofzion/blockchain-service';
1
+ import { type TBSAccount, type TTransferIntent, type TBSToken, type TTransferParams, type TGetLedgerTransport, type ITokenService, type TBSNetwork, type IBlockchainDataService, type IExchangeDataService, type INftDataService, type IExplorerService, type TPingNetworkResponse, type IWalletConnectService, type IFullTransactionsDataService } from '@cityofzion/blockchain-service';
2
2
  import { ethers } from 'ethers';
3
3
  import { EthersLedgerServiceEthereum } from './services/ledger/EthersLedgerServiceEthereum';
4
- import { IBSEthereum, TBSEthereumNetworkId, TSupportedEVM } from './types';
4
+ import type { IBSEthereum, TBSEthereumNetworkId, TSupportedEVM } from './types';
5
5
  import { TypedDataSigner } from '@ethersproject/abstract-signer';
6
6
  export declare class BSEthereum<N extends string = string, A extends string = TBSEthereumNetworkId> implements IBSEthereum<N, A> {
7
7
  #private;
8
8
  readonly name: N;
9
- readonly bip44DerivationPath: string;
9
+ readonly bipDerivationPath: string;
10
10
  readonly isMultiTransferSupported = false;
11
11
  readonly isCustomNetworkSupported = false;
12
12
  tokens: TBSToken[];
13
13
  nativeTokens: TBSToken[];
14
14
  feeToken: TBSToken;
15
15
  network: TBSNetwork<A>;
16
- rpcNetworkUrls: string[];
16
+ networkUrls: string[];
17
17
  readonly defaultNetwork: TBSNetwork<A>;
18
18
  readonly availableNetworks: TBSNetwork<A>[];
19
19
  blockchainDataService: IBlockchainDataService<N>;
@@ -25,13 +25,13 @@ export declare class BSEthereum<N extends string = string, A extends string = TB
25
25
  walletConnectService: IWalletConnectService<N>;
26
26
  fullTransactionsDataService: IFullTransactionsDataService<N>;
27
27
  constructor(name: N, evm?: TSupportedEVM, network?: TBSNetwork<A>, getLedgerTransport?: TGetLedgerTransport<N>);
28
- protected _buildTransferParams(intent: TIntentTransferParam): Promise<{
28
+ protected _buildTransferParams(intent: TTransferIntent): Promise<{
29
29
  transactionParams: ethers.utils.Deferrable<ethers.providers.TransactionRequest>;
30
30
  gasPrice: ethers.BigNumber;
31
31
  }>;
32
32
  generateSigner(account: TBSAccount<N>): Promise<ethers.Signer & TypedDataSigner>;
33
33
  setNetwork(network: TBSNetwork<A>): void;
34
- pingNode(url: string): Promise<TPingNetworkResponse>;
34
+ pingNetwork(url: string): Promise<TPingNetworkResponse>;
35
35
  validateAddress(address: string): boolean;
36
36
  validateEncrypted(json: string): boolean;
37
37
  validateKey(key: string): boolean;
@@ -41,7 +41,7 @@ export declare class BSEthereum<N extends string = string, A extends string = TB
41
41
  generateAccountFromPublicKey(publicKey: string): Promise<TBSAccount<N>>;
42
42
  decrypt(json: string, password: string): Promise<TBSAccount<N>>;
43
43
  encrypt(key: string, password: string): Promise<string>;
44
- transfer(param: TTransferParam<N>): Promise<string[]>;
45
- calculateTransferFee(param: TTransferParam<N>): Promise<string>;
44
+ transfer(param: TTransferParams<N>): Promise<string[]>;
45
+ calculateTransferFee(param: TTransferParams<N>): Promise<string>;
46
46
  resolveNameServiceDomain(domainName: string): Promise<string>;
47
47
  }
@@ -66,7 +66,7 @@ class BSEthereum {
66
66
  this.isCustomNetworkSupported = false;
67
67
  this.name = name;
68
68
  this.ledgerService = new EthersLedgerServiceEthereum_1.EthersLedgerServiceEthereum(this, getLedgerTransport);
69
- this.bip44DerivationPath = BSEthereumConstants_1.BSEthereumConstants.DEFAULT_BIP44_DERIVATION_PATH;
69
+ this.bipDerivationPath = BSEthereumConstants_1.BSEthereumConstants.DEFAULT_BIP44_DERIVATION_PATH;
70
70
  if (!evm)
71
71
  return;
72
72
  this.availableNetworks = BSEthereumConstants_1.BSEthereumConstants.NETWORKS_BY_EVM[evm];
@@ -105,22 +105,22 @@ class BSEthereum {
105
105
  if (account.isHardware) {
106
106
  if (!this.ledgerService.getLedgerTransport)
107
107
  throw new Error('You must provide getLedgerTransport function to use Ledger');
108
- if (typeof account.bip44Path !== 'string')
108
+ if (typeof account.bipPath !== 'string')
109
109
  throw new Error('Your account must have bip44 path to use Ledger');
110
110
  const ledgerTransport = await this.ledgerService.getLedgerTransport(account);
111
- return this.ledgerService.getSigner(ledgerTransport, account.bip44Path, provider);
111
+ return this.ledgerService.getSigner(ledgerTransport, account.bipPath, provider);
112
112
  }
113
113
  return new ethers_1.ethers.Wallet(account.key, provider);
114
114
  }
115
115
  setNetwork(network) {
116
- const rpcNetworkUrls = BSEthereumConstants_1.BSEthereumConstants.RPC_LIST_BY_NETWORK_ID[network.id] || [];
117
- const isValidNetwork = blockchain_service_1.BSUtilsHelper.validateNetwork(network, this.availableNetworks, rpcNetworkUrls);
116
+ const networkUrls = BSEthereumConstants_1.BSEthereumConstants.RPC_LIST_BY_NETWORK_ID[network.id] || [];
117
+ const isValidNetwork = blockchain_service_1.BSUtilsHelper.validateNetwork(network, this.availableNetworks, networkUrls);
118
118
  if (!isValidNetwork) {
119
119
  throw new Error(`Network with id ${network.id} is not available for ${this.name}`);
120
120
  }
121
121
  __classPrivateFieldGet(this, _BSEthereum_instances, "m", _BSEthereum_setTokens).call(this, network);
122
122
  this.network = network;
123
- this.rpcNetworkUrls = rpcNetworkUrls;
123
+ this.networkUrls = networkUrls;
124
124
  this.nftDataService = new GhostMarketNDSEthereum_1.GhostMarketNDSEthereum(this);
125
125
  this.explorerService = new BlockscoutESEthereum_1.BlockscoutESEthereum(this);
126
126
  this.exchangeDataService = new MoralisEDSEthereum_1.MoralisEDSEthereum(this);
@@ -130,7 +130,7 @@ class BSEthereum {
130
130
  this.fullTransactionsDataService = new MoralisFullTransactionsDataServiceEthereum_1.MoralisFullTransactionsDataServiceEthereum(this);
131
131
  }
132
132
  // This method is done manually because we need to ensure that the request is aborted after timeout
133
- async pingNode(url) {
133
+ async pingNetwork(url) {
134
134
  const abortController = new AbortController();
135
135
  const timeout = setTimeout(() => {
136
136
  abortController.abort();
@@ -166,13 +166,13 @@ class BSEthereum {
166
166
  return domainName.endsWith('.eth');
167
167
  }
168
168
  async generateAccountFromMnemonic(mnemonic, index) {
169
- const bip44Path = this.bip44DerivationPath.replace('?', index.toString());
170
- const hd = ethers_1.ethers.utils.HDNode.fromMnemonic(Array.isArray(mnemonic) ? mnemonic.join(' ') : mnemonic).derivePath(bip44Path);
169
+ const bipPath = blockchain_service_1.BSKeychainHelper.getBipPath(this.bipDerivationPath, index);
170
+ const hd = ethers_1.ethers.utils.HDNode.fromMnemonic(Array.isArray(mnemonic) ? mnemonic.join(' ') : mnemonic).derivePath(bipPath);
171
171
  return {
172
172
  address: hd.address,
173
173
  key: hd.privateKey,
174
174
  type: 'privateKey',
175
- bip44Path,
175
+ bipPath,
176
176
  blockchain: this.name,
177
177
  };
178
178
  }
@@ -1,5 +1,5 @@
1
- import { TBSNetwork } from '@cityofzion/blockchain-service';
2
- import { TBSEthereumNetworkId, TSupportedEVM } from '../types';
1
+ import type { TBSNetwork } from '@cityofzion/blockchain-service';
2
+ import type { TBSEthereumNetworkId, TSupportedEVM } from '../types';
3
3
  export declare class BSEthereumConstants {
4
4
  static readonly DEFAULT_DECIMALS = 18;
5
5
  static readonly DEFAULT_GAS_LIMIT = 21000;
@@ -1,5 +1,5 @@
1
- import { TBSNetwork, TBSNetworkId } from '@cityofzion/blockchain-service';
2
- import { IBSEthereum, TBSEthereumNetworkId } from '../types';
1
+ import type { TBSNetwork, TBSNetworkId } from '@cityofzion/blockchain-service';
2
+ import type { IBSEthereum, TBSEthereumNetworkId } from '../types';
3
3
  export declare class BSEthereumHelper {
4
4
  static getNativeAsset(network: TBSNetwork<TBSEthereumNetworkId>): {
5
5
  symbol: string;
@@ -1,6 +1,6 @@
1
- import { TBalanceResponse, TBSToken, TBSNetwork, TBSNetworkId, type TContractResponse, type TTransaction, type TGetTransactionsByAddressResponse, type TGetTransactionsByAddressParams } from '@cityofzion/blockchain-service';
1
+ import { type TBalanceResponse, type TBSToken, type TBSNetwork, type TBSNetworkId, type TContractResponse, type TTransaction, type TGetTransactionsByAddressResponse, type TGetTransactionsByAddressParams } from '@cityofzion/blockchain-service';
2
2
  import axios from 'axios';
3
- import { IBSEthereum, TBSEthereumNetworkId } from '../../types';
3
+ import type { IBSEthereum, TBSEthereumNetworkId } from '../../types';
4
4
  import { RpcBDSEthereum } from './RpcBDSEthereum';
5
5
  export declare class MoralisBDSEthereum<N extends string, A extends TBSNetworkId> extends RpcBDSEthereum<N, A> {
6
6
  #private;
@@ -101,15 +101,10 @@ class MoralisBDSEthereum extends RpcBDSEthereum_1.RpcBDSEthereum {
101
101
  }
102
102
  const { data } = await __classPrivateFieldGet(this, _MoralisBDSEthereum_instances, "a", _MoralisBDSEthereum_api_get).get(`/transaction/${hash}/verbose`);
103
103
  const events = [];
104
- const txTemplateUrl = this._service.explorerService.getTxTemplateUrl();
105
- const addressTemplateUrl = this._service.explorerService.getAddressTemplateUrl();
106
- const contractTemplateUrl = this._service.explorerService.getContractTemplateUrl();
107
- const nftTemplateUrl = this._service.explorerService.getNftTemplateUrl();
108
104
  if (data.value && Number(data.value) > 0) {
109
105
  const nativeToken = BSEthereumHelper_1.BSEthereumHelper.getNativeAsset(this._service.network);
110
- const fromUrl = addressTemplateUrl?.replace('{address}', data.from_address);
111
- const toUrl = addressTemplateUrl?.replace('{address}', data.to_address);
112
- const contractHashUrl = contractTemplateUrl?.replace('{hash}', nativeToken.hash);
106
+ const fromUrl = this._service.explorerService.buildAddressUrl(data.from_address);
107
+ const toUrl = this._service.explorerService.buildAddressUrl(data.to_address);
113
108
  events.push({
114
109
  eventType: 'token',
115
110
  amount: blockchain_service_1.BSBigNumberHelper.format(blockchain_service_1.BSBigNumberHelper.fromDecimals(data.value, nativeToken.decimals), {
@@ -121,7 +116,7 @@ class MoralisBDSEthereum extends RpcBDSEthereum_1.RpcBDSEthereum {
121
116
  contractHash: nativeToken.hash,
122
117
  tokenType: 'native',
123
118
  methodName: 'transfer',
124
- contractHashUrl,
119
+ contractHashUrl: this._service.explorerService.buildContractUrl(nativeToken.hash),
125
120
  fromUrl,
126
121
  toUrl,
127
122
  });
@@ -138,9 +133,8 @@ class MoralisBDSEthereum extends RpcBDSEthereum_1.RpcBDSEthereum {
138
133
  const to = log.decoded_event.params.find((param) => param.name === 'to')?.value;
139
134
  if (!from || !to)
140
135
  return;
141
- const fromUrl = addressTemplateUrl?.replace('{address}', data.from_address);
142
- const toUrl = addressTemplateUrl?.replace('{address}', data.to_address);
143
- const contractHashUrl = contractTemplateUrl?.replace('{hash}', contractHash);
136
+ const fromUrl = this._service.explorerService.buildAddressUrl(data.from_address);
137
+ const toUrl = this._service.explorerService.buildAddressUrl(data.to_address);
144
138
  if (amount) {
145
139
  const token = await this.getTokenInfo(contractHash);
146
140
  events.push({
@@ -155,16 +149,13 @@ class MoralisBDSEthereum extends RpcBDSEthereum_1.RpcBDSEthereum {
155
149
  eventType: 'token',
156
150
  methodName: 'transfer',
157
151
  tokenType: 'erc-20',
158
- contractHashUrl,
152
+ contractHashUrl: this._service.explorerService.buildContractUrl(contractHash),
159
153
  });
160
154
  }
161
155
  const tokenHash = log.decoded_event.params.find((param) => param.name === 'tokenId')?.value;
162
156
  if (!tokenHash)
163
157
  return;
164
158
  const [nft] = await blockchain_service_1.BSUtilsHelper.tryCatch(() => this._service.nftDataService.getNft({ collectionHash: contractHash, tokenHash }));
165
- const nftUrl = contractHash
166
- ? nftTemplateUrl?.replace('{collectionHash}', contractHash).replace('{tokenHash}', tokenHash)
167
- : undefined;
168
159
  events.push({
169
160
  collectionHash: contractHash,
170
161
  tokenHash,
@@ -177,25 +168,24 @@ class MoralisBDSEthereum extends RpcBDSEthereum_1.RpcBDSEthereum {
177
168
  tokenType: 'erc-721',
178
169
  amount: '1',
179
170
  nftImageUrl: nft?.image,
180
- nftUrl,
171
+ nftUrl: nft?.explorerUri,
181
172
  name: nft?.name,
182
173
  collectionName: nft?.collection?.name,
183
- collectionHashUrl: contractHashUrl,
174
+ collectionHashUrl: nft?.collection?.url,
184
175
  });
185
176
  });
186
177
  await Promise.allSettled(promises);
187
178
  }
188
- const txIdUrl = txTemplateUrl?.replace('{txId}', hash);
189
179
  return {
190
180
  txId: hash,
191
181
  block: Number(data.block_number),
192
- date: new Date(data.block_timestamp).toISOString(),
182
+ date: new Date(data.block_timestamp).toJSON(),
193
183
  invocationCount: 0,
194
184
  notificationCount: 0,
195
185
  networkFeeAmount: blockchain_service_1.BSBigNumberHelper.format(blockchain_service_1.BSBigNumberHelper.fromNumber(data.transaction_fee), {
196
186
  decimals: this._service.feeToken.decimals,
197
187
  }),
198
- txIdUrl,
188
+ txIdUrl: this._service.explorerService.buildTransactionUrl(hash),
199
189
  events,
200
190
  type: 'default',
201
191
  };
@@ -212,16 +202,11 @@ class MoralisBDSEthereum extends RpcBDSEthereum_1.RpcBDSEthereum {
212
202
  });
213
203
  const transactions = [];
214
204
  const nativeAsset = BSEthereumHelper_1.BSEthereumHelper.getNativeAsset(this._service.network);
215
- const txTemplateUrl = this._service.explorerService.getTxTemplateUrl();
216
- const addressTemplateUrl = this._service.explorerService.getAddressTemplateUrl();
217
- const contractTemplateUrl = this._service.explorerService.getContractTemplateUrl();
218
- const nftTemplateUrl = this._service.explorerService.getNftTemplateUrl();
219
- const promises = data.result.map(async (item) => {
205
+ const promises = data.result.map(async (item, index) => {
220
206
  const events = [];
221
- const nativeContractHashUrl = contractTemplateUrl?.replace('{hash}', nativeAsset.hash);
222
207
  item.native_transfers.forEach(transfer => {
223
- const fromUrl = addressTemplateUrl?.replace('{address}', transfer.from_address);
224
- const toUrl = addressTemplateUrl?.replace('{address}', transfer.to_address);
208
+ const fromUrl = this._service.explorerService.buildAddressUrl(transfer.from_address);
209
+ const toUrl = this._service.explorerService.buildAddressUrl(transfer.to_address);
225
210
  events.push({
226
211
  amount: blockchain_service_1.BSBigNumberHelper.format(blockchain_service_1.BSBigNumberHelper.fromDecimals(transfer.value, nativeAsset.decimals), {
227
212
  decimals: nativeAsset.decimals,
@@ -235,15 +220,14 @@ class MoralisBDSEthereum extends RpcBDSEthereum_1.RpcBDSEthereum {
235
220
  contractHash: nativeAsset.hash,
236
221
  methodName: 'transfer',
237
222
  tokenType: 'native',
238
- contractHashUrl: nativeContractHashUrl,
223
+ contractHashUrl: this._service.explorerService.buildContractUrl(nativeAsset.hash),
239
224
  });
240
225
  });
241
226
  item.erc20_transfers.forEach(transfer => {
242
227
  if (transfer.possible_spam)
243
228
  return;
244
- const fromUrl = addressTemplateUrl?.replace('{address}', transfer.from_address);
245
- const toUrl = addressTemplateUrl?.replace('{address}', transfer.to_address);
246
- const contractHashUrl = contractTemplateUrl?.replace('{hash}', transfer.address);
229
+ const fromUrl = this._service.explorerService.buildAddressUrl(transfer.from_address);
230
+ const toUrl = this._service.explorerService.buildAddressUrl(transfer.to_address);
247
231
  events.push({
248
232
  amount: blockchain_service_1.BSBigNumberHelper.format(blockchain_service_1.BSBigNumberHelper.fromDecimals(transfer.value, transfer.token_decimals), {
249
233
  decimals: transfer.token_decimals,
@@ -262,20 +246,16 @@ class MoralisBDSEthereum extends RpcBDSEthereum_1.RpcBDSEthereum {
262
246
  contractHash: transfer.address,
263
247
  methodName: 'transfer',
264
248
  tokenType: 'erc-20',
265
- contractHashUrl,
249
+ contractHashUrl: this._service.explorerService.buildContractUrl(transfer.address),
266
250
  });
267
251
  });
268
252
  const nftPromises = item.nft_transfers.map(async (transfer) => {
269
- const fromUrl = addressTemplateUrl?.replace('{address}', transfer.from_address);
270
- const toUrl = addressTemplateUrl?.replace('{address}', transfer.to_address);
271
- const collectionHashUrl = contractTemplateUrl?.replace('{contractHash}', transfer.token_address);
253
+ const fromUrl = this._service.explorerService.buildAddressUrl(transfer.from_address);
254
+ const toUrl = this._service.explorerService.buildAddressUrl(transfer.to_address);
272
255
  const [nft] = await blockchain_service_1.BSUtilsHelper.tryCatch(() => this._service.nftDataService.getNft({ collectionHash: transfer.token_address, tokenHash: transfer.token_id }));
273
- const nftUrl = nftTemplateUrl
274
- ?.replace('{collectionHash}', transfer.token_address)
275
- .replace('{tokenHash}', transfer.token_id);
276
256
  events.push({
277
257
  collectionHash: transfer.token_address,
278
- collectionHashUrl,
258
+ collectionHashUrl: nft?.collection?.url,
279
259
  tokenHash: transfer.token_id,
280
260
  from: transfer.from_address,
281
261
  fromUrl,
@@ -286,23 +266,22 @@ class MoralisBDSEthereum extends RpcBDSEthereum_1.RpcBDSEthereum {
286
266
  tokenType: 'erc-721',
287
267
  amount: '1',
288
268
  nftImageUrl: nft?.image,
289
- nftUrl,
269
+ nftUrl: nft?.explorerUri,
290
270
  name: nft?.name,
291
271
  collectionName: nft?.collection?.name,
292
272
  });
293
273
  });
294
274
  await Promise.allSettled(nftPromises);
295
- const txIdUrl = txTemplateUrl?.replace('{txId}', item.hash);
296
- transactions.push({
275
+ transactions.splice(index, 0, {
297
276
  block: Number(item.block_number),
298
277
  txId: item.hash,
299
- txIdUrl,
278
+ txIdUrl: this._service.explorerService.buildTransactionUrl(item.hash),
300
279
  notificationCount: 0,
301
280
  invocationCount: 0,
302
281
  networkFeeAmount: blockchain_service_1.BSBigNumberHelper.format(blockchain_service_1.BSBigNumberHelper.fromNumber(item.transaction_fee), {
303
282
  decimals: this._service.feeToken.decimals,
304
283
  }),
305
- date: new Date(item.block_timestamp).toISOString(),
284
+ date: new Date(item.block_timestamp).toJSON(),
306
285
  events,
307
286
  type: 'default',
308
287
  });
@@ -1,5 +1,5 @@
1
- import { TBalanceResponse, IBlockchainDataService, TBSNetworkId, TBSToken, type TContractResponse, type TGetTransactionsByAddressParams, type TGetTransactionsByAddressResponse, type TTransaction } from '@cityofzion/blockchain-service';
2
- import { IBSEthereum } from '../../types';
1
+ import { type TBalanceResponse, type IBlockchainDataService, type TBSNetworkId, type TBSToken, type TContractResponse, type TGetTransactionsByAddressParams, type TGetTransactionsByAddressResponse, type TTransaction } from '@cityofzion/blockchain-service';
2
+ import type { IBSEthereum } from '../../types';
3
3
  export declare class RpcBDSEthereum<N extends string, A extends TBSNetworkId, S extends IBSEthereum<N, A> = IBSEthereum<N, A>> implements IBlockchainDataService<N> {
4
4
  #private;
5
5
  readonly maxTimeToConfirmTransactionInMs: number;
@@ -35,19 +35,14 @@ class RpcBDSEthereum {
35
35
  const effectiveGasPrice = receipt.effectiveGasPrice ?? transaction.gasPrice;
36
36
  const fee = effectiveGasPrice.mul(receipt.gasUsed);
37
37
  const token = BSEthereumHelper_1.BSEthereumHelper.getNativeAsset(this._service.network);
38
- const txTemplateUrl = this._service.explorerService.getTxTemplateUrl();
39
- const addressTemplateUrl = this._service.explorerService.getAddressTemplateUrl();
40
- const contractTemplateUrl = this._service.explorerService.getContractTemplateUrl();
41
- const fromUrl = addressTemplateUrl?.replace('{address}', transaction.from);
42
- const toUrl = addressTemplateUrl?.replace('{address}', transaction.to);
43
- const contractHashUrl = contractTemplateUrl?.replace('{hash}', token.hash);
44
- const txIdUrl = txTemplateUrl?.replace('{txId}', hash);
38
+ const fromUrl = this._service.explorerService.buildAddressUrl(transaction.from);
39
+ const toUrl = this._service.explorerService.buildAddressUrl(transaction.to);
45
40
  const timestamp = transaction.timestamp ?? 0;
46
41
  return {
47
42
  txId: hash,
48
- txIdUrl,
43
+ txIdUrl: this._service.explorerService.buildTransactionUrl(hash),
49
44
  block: receipt.blockNumber,
50
- date: new Date(timestamp).toISOString(),
45
+ date: new Date(timestamp).toJSON(),
51
46
  invocationCount: 0,
52
47
  notificationCount: 0,
53
48
  networkFeeAmount: blockchain_service_1.BSBigNumberHelper.format(blockchain_service_1.BSBigNumberHelper.fromDecimals(fee.toString(), this._service.feeToken.decimals), {
@@ -65,7 +60,7 @@ class RpcBDSEthereum {
65
60
  to: transaction.to,
66
61
  toUrl,
67
62
  contractHash: token.hash,
68
- contractHashUrl,
63
+ contractHashUrl: this._service.explorerService.buildContractUrl(token.hash),
69
64
  token: token ?? undefined,
70
65
  tokenType: 'native',
71
66
  },
@@ -1,5 +1,5 @@
1
- import { CryptoCompareEDS, TGetTokenPriceHistoryParams, TGetTokenPricesParams, TBSNetworkId, TTokenPricesHistoryResponse, TTokenPricesResponse } from '@cityofzion/blockchain-service';
2
- import { IBSEthereum } from '../../types';
1
+ import { CryptoCompareEDS, type TGetTokenPriceHistoryParams, type TGetTokenPricesParams, type TBSNetworkId, type TTokenPricesHistoryResponse, type TTokenPricesResponse } from '@cityofzion/blockchain-service';
2
+ import type { IBSEthereum } from '../../types';
3
3
  export declare class MoralisEDSEthereum<N extends string, A extends TBSNetworkId> extends CryptoCompareEDS {
4
4
  #private;
5
5
  static readonly NUMBERS_OF_BLOCK_BY_HOUR: number;
@@ -1,5 +1,5 @@
1
- import { TBuildNftUrlParams, IExplorerService, TBSNetworkId } from '@cityofzion/blockchain-service';
2
- import { IBSEthereum, TBSEthereumNetworkId } from '../../types';
1
+ import type { TBuildNftUrlParams, IExplorerService, TBSNetworkId } from '@cityofzion/blockchain-service';
2
+ import type { IBSEthereum, TBSEthereumNetworkId } from '../../types';
3
3
  export declare class BlockscoutESEthereum<N extends string, A extends TBSNetworkId> implements IExplorerService {
4
4
  #private;
5
5
  static readonly DEFAULT_BASE_URL_BY_NETWORK_ID: Partial<Record<TBSEthereumNetworkId, string>>;
@@ -7,7 +7,7 @@ export declare class BlockscoutESEthereum<N extends string, A extends TBSNetwork
7
7
  constructor(service: IBSEthereum<N, A>, baseUrl?: string);
8
8
  buildTransactionUrl(hash: string): string | undefined;
9
9
  buildContractUrl(contractHash: string): string | undefined;
10
- buildNftUrl(params: TBuildNftUrlParams): string | undefined;
10
+ buildNftUrl({ tokenHash, collectionHash }: TBuildNftUrlParams): string | undefined;
11
11
  buildAddressUrl(address: string): string | undefined;
12
12
  getAddressTemplateUrl(): string | undefined;
13
13
  getTxTemplateUrl(): string | undefined;
@@ -20,22 +20,22 @@ class BlockscoutESEthereum {
20
20
  __classPrivateFieldSet(this, _BlockscoutESEthereum_baseUrl, baseUrl ?? BlockscoutESEthereum.DEFAULT_BASE_URL_BY_NETWORK_ID[this._service.network.id], "f");
21
21
  }
22
22
  buildTransactionUrl(hash) {
23
- if (!__classPrivateFieldGet(this, _BlockscoutESEthereum_baseUrl, "f"))
23
+ if (!__classPrivateFieldGet(this, _BlockscoutESEthereum_baseUrl, "f") || !hash?.length)
24
24
  return undefined;
25
25
  return `${__classPrivateFieldGet(this, _BlockscoutESEthereum_baseUrl, "f")}/tx/${this._service.tokenService.normalizeHash(hash)}`;
26
26
  }
27
27
  buildContractUrl(contractHash) {
28
- if (!__classPrivateFieldGet(this, _BlockscoutESEthereum_baseUrl, "f"))
28
+ if (!__classPrivateFieldGet(this, _BlockscoutESEthereum_baseUrl, "f") || !contractHash?.length)
29
29
  return undefined;
30
30
  return `${__classPrivateFieldGet(this, _BlockscoutESEthereum_baseUrl, "f")}/address/${this._service.tokenService.normalizeHash(contractHash)}`;
31
31
  }
32
- buildNftUrl(params) {
33
- if (!__classPrivateFieldGet(this, _BlockscoutESEthereum_baseUrl, "f") || !params.collectionHash)
32
+ buildNftUrl({ tokenHash, collectionHash }) {
33
+ if (!__classPrivateFieldGet(this, _BlockscoutESEthereum_baseUrl, "f") || !tokenHash?.length || !collectionHash?.length)
34
34
  return undefined;
35
- return `${__classPrivateFieldGet(this, _BlockscoutESEthereum_baseUrl, "f")}/token/${this._service.tokenService.normalizeHash(params.collectionHash)}/instance/${params.tokenHash}`;
35
+ return `${__classPrivateFieldGet(this, _BlockscoutESEthereum_baseUrl, "f")}/token/${this._service.tokenService.normalizeHash(collectionHash)}/instance/${tokenHash}`;
36
36
  }
37
37
  buildAddressUrl(address) {
38
- if (!__classPrivateFieldGet(this, _BlockscoutESEthereum_baseUrl, "f"))
38
+ if (!__classPrivateFieldGet(this, _BlockscoutESEthereum_baseUrl, "f") || !address?.length)
39
39
  return undefined;
40
40
  return `${__classPrivateFieldGet(this, _BlockscoutESEthereum_baseUrl, "f")}/address/${address}`;
41
41
  }
@@ -38,15 +38,11 @@ class MoralisFullTransactionsDataServiceEthereum {
38
38
  });
39
39
  const items = response.data ?? [];
40
40
  const nativeToken = BSEthereumHelper_1.BSEthereumHelper.getNativeAsset(__classPrivateFieldGet(this, _MoralisFullTransactionsDataServiceEthereum_service, "f").network);
41
- const addressTemplateUrl = __classPrivateFieldGet(this, _MoralisFullTransactionsDataServiceEthereum_service, "f").explorerService.getAddressTemplateUrl();
42
- const txTemplateUrl = __classPrivateFieldGet(this, _MoralisFullTransactionsDataServiceEthereum_service, "f").explorerService.getTxTemplateUrl();
43
- const nftTemplateUrl = __classPrivateFieldGet(this, _MoralisFullTransactionsDataServiceEthereum_service, "f").explorerService.getNftTemplateUrl();
44
- const contractTemplateUrl = __classPrivateFieldGet(this, _MoralisFullTransactionsDataServiceEthereum_service, "f").explorerService.getContractTemplateUrl();
45
41
  const itemPromises = items.map(async ({ networkFeeAmount, systemFeeAmount, ...item }, index) => {
46
42
  const txId = item.transactionID;
47
43
  const newItem = {
48
44
  txId,
49
- txIdUrl: txId ? txTemplateUrl?.replace('{txId}', txId) : undefined,
45
+ txIdUrl: txId ? __classPrivateFieldGet(this, _MoralisFullTransactionsDataServiceEthereum_service, "f").explorerService.buildTransactionUrl(txId) : undefined,
50
46
  block: item.block,
51
47
  date: item.date,
52
48
  invocationCount: item.invocationCount,
@@ -69,14 +65,10 @@ class MoralisFullTransactionsDataServiceEthereum {
69
65
  const isErc721 = MoralisFullTransactionsDataServiceEthereum.ERC721_STANDARDS.includes(standard);
70
66
  const isErc20 = MoralisFullTransactionsDataServiceEthereum.ERC20_STANDARDS.includes(standard);
71
67
  const isNft = (isErc1155 || isErc721) && !!tokenHash;
72
- const fromUrl = from ? addressTemplateUrl?.replace('{address}', from) : undefined;
73
- const toUrl = to ? addressTemplateUrl?.replace('{address}', to) : undefined;
74
- const contractHashUrl = contractHash ? contractTemplateUrl?.replace('{hash}', contractHash) : undefined;
68
+ const fromUrl = from ? __classPrivateFieldGet(this, _MoralisFullTransactionsDataServiceEthereum_service, "f").explorerService.buildAddressUrl(from) : undefined;
69
+ const toUrl = to ? __classPrivateFieldGet(this, _MoralisFullTransactionsDataServiceEthereum_service, "f").explorerService.buildAddressUrl(to) : undefined;
75
70
  if (isNft) {
76
71
  const [nft] = await blockchain_service_1.BSUtilsHelper.tryCatch(() => __classPrivateFieldGet(this, _MoralisFullTransactionsDataServiceEthereum_service, "f").nftDataService.getNft({ collectionHash: contractHash, tokenHash }));
77
- const nftUrl = contractHash
78
- ? nftTemplateUrl?.replace('{collectionHash}', contractHash).replace('{tokenHash}', tokenHash)
79
- : undefined;
80
72
  newItem.events.splice(eventIndex, 0, {
81
73
  eventType: 'nft',
82
74
  amount: undefined,
@@ -86,11 +78,11 @@ class MoralisFullTransactionsDataServiceEthereum {
86
78
  to,
87
79
  toUrl,
88
80
  collectionHash: contractHash,
89
- collectionHashUrl: contractHashUrl,
81
+ collectionHashUrl: nft?.collection?.url,
90
82
  tokenHash,
91
83
  tokenType: isErc1155 ? 'erc-1155' : 'erc-721',
92
84
  nftImageUrl: nft?.image,
93
- nftUrl,
85
+ nftUrl: nft?.explorerUri,
94
86
  name: nft?.name,
95
87
  collectionName: nft?.collection?.name,
96
88
  });
@@ -108,7 +100,7 @@ class MoralisFullTransactionsDataServiceEthereum {
108
100
  to,
109
101
  toUrl,
110
102
  contractHash,
111
- contractHashUrl,
103
+ contractHashUrl: __classPrivateFieldGet(this, _MoralisFullTransactionsDataServiceEthereum_service, "f").explorerService.buildContractUrl(contractHash),
112
104
  token: token ?? undefined,
113
105
  tokenType: isErc20 ? 'erc-20' : 'generic',
114
106
  });
@@ -1,4 +1,4 @@
1
- import { TBSAccount, TLedgerServiceEmitter, TGetLedgerTransport, TUntilIndexRecord, ILedgerService } from '@cityofzion/blockchain-service';
1
+ import { type TBSAccount, type TLedgerServiceEmitter, type TGetLedgerTransport, type TUntilIndexRecord, type ILedgerService } 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';
@@ -82,7 +82,7 @@ class EthersLedgerSigner extends ethers_1.Signer {
82
82
  message = ethers_1.ethers.utils.toUtf8Bytes(message);
83
83
  }
84
84
  __classPrivateFieldGet(this, _EthersLedgerSigner_emitter, "f")?.emit('getSignatureStart');
85
- const obj = await blockchain_service_1.BSUtilsHelper.retry(() => __classPrivateFieldGet(this, _EthersLedgerSigner_ledgerApp, "f").signPersonalMessage(__classPrivateFieldGet(this, _EthersLedgerSigner_bip44Path, "f"), ethers_1.ethers.utils.hexlify(message).substring(2)), { shouldRetry: EthersLedgerSigner.shouldRetry });
85
+ const obj = await __classPrivateFieldGet(this, _EthersLedgerSigner_ledgerApp, "f").signPersonalMessage(__classPrivateFieldGet(this, _EthersLedgerSigner_bip44Path, "f"), ethers_1.ethers.utils.hexlify(message).substring(2));
86
86
  __classPrivateFieldGet(this, _EthersLedgerSigner_emitter, "f")?.emit('getSignatureEnd');
87
87
  // Normalize the signature for Ethers
88
88
  obj.r = '0x' + obj.r;
@@ -102,7 +102,7 @@ class EthersLedgerSigner extends ethers_1.Signer {
102
102
  .substring(2);
103
103
  const resolution = await hw_app_eth_1.ledgerService.resolveTransaction(serializedUnsignedTransaction, {}, {});
104
104
  __classPrivateFieldGet(this, _EthersLedgerSigner_emitter, "f")?.emit('getSignatureStart');
105
- const signature = await blockchain_service_1.BSUtilsHelper.retry(() => __classPrivateFieldGet(this, _EthersLedgerSigner_ledgerApp, "f").signTransaction(__classPrivateFieldGet(this, _EthersLedgerSigner_bip44Path, "f"), serializedUnsignedTransaction, resolution), { shouldRetry: EthersLedgerSigner.shouldRetry });
105
+ const signature = await __classPrivateFieldGet(this, _EthersLedgerSigner_ledgerApp, "f").signTransaction(__classPrivateFieldGet(this, _EthersLedgerSigner_bip44Path, "f"), serializedUnsignedTransaction, resolution);
106
106
  __classPrivateFieldGet(this, _EthersLedgerSigner_emitter, "f")?.emit('getSignatureEnd');
107
107
  return ethers_1.ethers.utils.serializeTransaction(tx, {
108
108
  v: ethers_1.ethers.BigNumber.from('0x' + signature.v).toNumber(),
@@ -129,14 +129,12 @@ class EthersLedgerSigner extends ethers_1.Signer {
129
129
  __classPrivateFieldGet(this, _EthersLedgerSigner_emitter, "f")?.emit('getSignatureStart');
130
130
  let obj;
131
131
  try {
132
- obj = await blockchain_service_1.BSUtilsHelper.retry(() => __classPrivateFieldGet(this, _EthersLedgerSigner_ledgerApp, "f").signEIP712Message(__classPrivateFieldGet(this, _EthersLedgerSigner_bip44Path, "f"), payload), {
133
- shouldRetry: EthersLedgerSigner.shouldRetry,
134
- });
132
+ obj = await __classPrivateFieldGet(this, _EthersLedgerSigner_ledgerApp, "f").signEIP712Message(__classPrivateFieldGet(this, _EthersLedgerSigner_bip44Path, "f"), payload);
135
133
  }
136
134
  catch {
137
135
  const domainSeparatorHex = ethers_1.ethers.utils._TypedDataEncoder.hashDomain(payload.domain);
138
136
  const hashStructMessageHex = ethers_1.ethers.utils._TypedDataEncoder.hashStruct(payload.primaryType, types, payload.message);
139
- obj = await blockchain_service_1.BSUtilsHelper.retry(() => __classPrivateFieldGet(this, _EthersLedgerSigner_ledgerApp, "f").signEIP712HashedMessage(__classPrivateFieldGet(this, _EthersLedgerSigner_bip44Path, "f"), domainSeparatorHex, hashStructMessageHex), { shouldRetry: EthersLedgerSigner.shouldRetry });
137
+ obj = await __classPrivateFieldGet(this, _EthersLedgerSigner_ledgerApp, "f").signEIP712HashedMessage(__classPrivateFieldGet(this, _EthersLedgerSigner_bip44Path, "f"), domainSeparatorHex, hashStructMessageHex);
140
138
  }
141
139
  __classPrivateFieldGet(this, _EthersLedgerSigner_emitter, "f")?.emit('getSignatureEnd');
142
140
  // Normalize the signature for Ethers
@@ -171,8 +169,8 @@ class EthersLedgerServiceEthereum {
171
169
  }
172
170
  async getAccount(transport, index) {
173
171
  const ledgerApp = new hw_app_eth_1.default(transport);
174
- const bip44Path = __classPrivateFieldGet(this, _EthersLedgerServiceEthereum_blockchainService, "f").bip44DerivationPath.replace('?', index.toString());
175
- const { publicKey, address } = await blockchain_service_1.BSUtilsHelper.retry(() => ledgerApp.getAddress(bip44Path), {
172
+ const bipPath = blockchain_service_1.BSKeychainHelper.getBipPath(__classPrivateFieldGet(this, _EthersLedgerServiceEthereum_blockchainService, "f").bipDerivationPath, index);
173
+ const { publicKey, address } = await blockchain_service_1.BSUtilsHelper.retry(() => ledgerApp.getAddress(bipPath), {
176
174
  shouldRetry: EthersLedgerSigner.shouldRetry,
177
175
  });
178
176
  const publicKeyWithPrefix = '0x' + publicKey;
@@ -180,7 +178,7 @@ class EthersLedgerServiceEthereum {
180
178
  address,
181
179
  key: publicKeyWithPrefix,
182
180
  type: 'publicKey',
183
- bip44Path,
181
+ bipPath,
184
182
  blockchain: __classPrivateFieldGet(this, _EthersLedgerServiceEthereum_blockchainService, "f").name,
185
183
  isHardware: true,
186
184
  };
@@ -1,8 +1,8 @@
1
- import { TBSNetworkId, GhostMarketNDS, THasTokenParam } from '@cityofzion/blockchain-service';
2
- import { IBSEthereum, TBSEthereumNetworkId } from '../../types';
1
+ import { GhostMarketNDS, type TBSNetworkId, type THasTokenParams } from '@cityofzion/blockchain-service';
2
+ import type { IBSEthereum, TBSEthereumNetworkId } from '../../types';
3
3
  export declare class GhostMarketNDSEthereum<N extends string, A extends TBSNetworkId> extends GhostMarketNDS<N, A, IBSEthereum<N, A>> {
4
4
  static readonly CHAIN_BY_NETWORK_ID: Partial<Record<TBSEthereumNetworkId, string>>;
5
5
  constructor(service: IBSEthereum<N, A>);
6
- hasToken({ collectionHash, address }: THasTokenParam): Promise<boolean>;
6
+ hasToken({ address, collectionHash }: THasTokenParams): Promise<boolean>;
7
7
  getChain(): string;
8
8
  }
@@ -8,7 +8,7 @@ class GhostMarketNDSEthereum extends blockchain_service_1.GhostMarketNDS {
8
8
  constructor(service) {
9
9
  super(service);
10
10
  }
11
- async hasToken({ collectionHash, address }) {
11
+ async hasToken({ address, collectionHash }) {
12
12
  try {
13
13
  if (!collectionHash)
14
14
  return false;
@@ -1,5 +1,5 @@
1
- import { IWalletConnectService, TBSNetworkId, TWalletConnectServiceRequestMethodParams } from '@cityofzion/blockchain-service';
2
- import { IBSEthereum } from '../../types';
1
+ import type { IWalletConnectService, TBSNetworkId, TWalletConnectServiceRequestMethodParams } from '@cityofzion/blockchain-service';
2
+ import type { IBSEthereum } from '../../types';
3
3
  import { ethers } from 'ethers';
4
4
  export declare class WalletConnectServiceEthereum<N extends string, A extends TBSNetworkId> implements IWalletConnectService<N> {
5
5
  #private;
@@ -50,11 +50,9 @@ class WalletConnectServiceEthereum {
50
50
  if (typeof param !== 'object') {
51
51
  throw new Error('Invalid params');
52
52
  }
53
- if (!param.chainId) {
54
- const chainId = parseInt(this._service.network.id);
55
- if (!isNaN(chainId))
56
- param.chainId = chainId;
57
- }
53
+ const chainId = parseInt(param.chainId ?? this._service.network.id);
54
+ if (!isNaN(chainId))
55
+ param.chainId = chainId;
58
56
  if (param.gas) {
59
57
  param.gasLimit = param.gas;
60
58
  delete param.gas;
package/dist/types.d.ts CHANGED
@@ -1,9 +1,9 @@
1
- import { IBlockchainService, IBSWithEncryption, IBSWithExplorer, IBSWithFee, IBSWithLedger, IBSWithNameService, IBSWithNft, IBSWithWalletConnect, TBSAccount, TBSNetworkId, type IBSWithFullTransactions } from '@cityofzion/blockchain-service';
1
+ import type { IBlockchainService, IBSWithEncryption, IBSWithExplorer, IBSWithFee, IBSWithLedger, IBSWithNameService, IBSWithNft, IBSWithWalletConnect, TBSAccount, TBSNetworkId, IBSWithFullTransactions } from '@cityofzion/blockchain-service';
2
2
  import { TypedDataSigner } from '@ethersproject/abstract-signer';
3
3
  import { ethers } from 'ethers';
4
4
  export type TBSEthereumNetworkId = TBSNetworkId<'1' | '10' | '25' | '56' | '137' | '250' | '1101' | '8453' | '80002' | '42161' | '42220' | '43114' | '59144' | '11155111'>;
5
5
  export type TSupportedEVM = 'ethereum' | 'polygon' | 'base' | 'arbitrum';
6
- export interface IBSEthereum<N extends string = string, A extends string = TBSEthereumNetworkId> extends IBlockchainService<N, A>, IBSWithNft, IBSWithNameService, IBSWithFee<N>, IBSWithLedger<N>, IBSWithExplorer, IBSWithEncryption<N>, IBSWithWalletConnect<N>, IBSWithFullTransactions<N> {
6
+ export interface IBSEthereum<N extends string = string, A extends string = TBSEthereumNetworkId> extends IBlockchainService<N, A>, IBSWithNameService, IBSWithNft, IBSWithFee<N>, IBSWithLedger<N>, IBSWithExplorer, IBSWithEncryption<N>, IBSWithWalletConnect<N>, IBSWithFullTransactions<N> {
7
7
  generateSigner(account: TBSAccount<N>): Promise<ethers.Signer & TypedDataSigner>;
8
8
  }
9
9
  export type TMoralisBDSEthereumNativeBalanceApiResponse = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cityofzion/bs-ethereum",
3
- "version": "3.0.5",
3
+ "version": "3.0.6",
4
4
  "repository": "https://github.com/CityOfZion/blockchain-services",
5
5
  "license": "GPL-3.0-only",
6
6
  "author": "Coz",
@@ -17,9 +17,9 @@
17
17
  "@ethersproject/json-wallets": "5.8.0",
18
18
  "@ethersproject/properties": "5.8.0",
19
19
  "@ledgerhq/hw-app-eth": "~7.3.0",
20
- "axios": "~1.13.2",
20
+ "axios": "~1.13.5",
21
21
  "ethers": "5.8.0",
22
- "@cityofzion/blockchain-service": "3.0.5"
22
+ "@cityofzion/blockchain-service": "3.0.6"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@ledgerhq/hw-transport": "~6.32.0",