@cityofzion/bs-ethereum 3.0.5 → 3.1.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.
@@ -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, type TTransactionDefault } 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({ senderAccount, intents }: TTransferParams<N>): Promise<TTransactionDefault<N>[]>;
45
+ calculateTransferFee(params: 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_BIP_DERIVATION_PATH;
70
70
  if (!evm)
71
71
  return;
72
72
  this.availableNetworks = BSEthereumConstants_1.BSEthereumConstants.NETWORKS_BY_EVM[evm];
@@ -105,22 +105,23 @@ 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')
109
- throw new Error('Your account must have bip44 path to use Ledger');
108
+ if (!account.bipPath) {
109
+ throw new Error('Account must have BIP path to use Ledger');
110
+ }
110
111
  const ledgerTransport = await this.ledgerService.getLedgerTransport(account);
111
- return this.ledgerService.getSigner(ledgerTransport, account.bip44Path, provider);
112
+ return this.ledgerService.getSigner(ledgerTransport, account.bipPath, provider);
112
113
  }
113
114
  return new ethers_1.ethers.Wallet(account.key, provider);
114
115
  }
115
116
  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);
117
+ const networkUrls = BSEthereumConstants_1.BSEthereumConstants.RPC_LIST_BY_NETWORK_ID[network.id] || [];
118
+ const isValidNetwork = blockchain_service_1.BSUtilsHelper.validateNetwork(network, this.availableNetworks, networkUrls);
118
119
  if (!isValidNetwork) {
119
120
  throw new Error(`Network with id ${network.id} is not available for ${this.name}`);
120
121
  }
121
122
  __classPrivateFieldGet(this, _BSEthereum_instances, "m", _BSEthereum_setTokens).call(this, network);
122
123
  this.network = network;
123
- this.rpcNetworkUrls = rpcNetworkUrls;
124
+ this.networkUrls = networkUrls;
124
125
  this.nftDataService = new GhostMarketNDSEthereum_1.GhostMarketNDSEthereum(this);
125
126
  this.explorerService = new BlockscoutESEthereum_1.BlockscoutESEthereum(this);
126
127
  this.exchangeDataService = new MoralisEDSEthereum_1.MoralisEDSEthereum(this);
@@ -130,7 +131,7 @@ class BSEthereum {
130
131
  this.fullTransactionsDataService = new MoralisFullTransactionsDataServiceEthereum_1.MoralisFullTransactionsDataServiceEthereum(this);
131
132
  }
132
133
  // This method is done manually because we need to ensure that the request is aborted after timeout
133
- async pingNode(url) {
134
+ async pingNetwork(url) {
134
135
  const abortController = new AbortController();
135
136
  const timeout = setTimeout(() => {
136
137
  abortController.abort();
@@ -166,13 +167,13 @@ class BSEthereum {
166
167
  return domainName.endsWith('.eth');
167
168
  }
168
169
  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);
170
+ const bipPath = blockchain_service_1.BSKeychainHelper.getBipPath(this.bipDerivationPath, index);
171
+ const hd = ethers_1.ethers.utils.HDNode.fromMnemonic(Array.isArray(mnemonic) ? mnemonic.join(' ') : mnemonic).derivePath(bipPath);
171
172
  return {
172
173
  address: hd.address,
173
174
  key: hd.privateKey,
174
175
  type: 'privateKey',
175
- bip44Path,
176
+ bipPath,
176
177
  blockchain: this.name,
177
178
  };
178
179
  }
@@ -207,12 +208,14 @@ class BSEthereum {
207
208
  const wallet = new ethers_1.ethers.Wallet(key);
208
209
  return wallet.encrypt(password);
209
210
  }
210
- async transfer(param) {
211
- const signer = await this.generateSigner(param.senderAccount);
212
- const sentTransactionHashes = [];
211
+ async transfer({ senderAccount, intents }) {
212
+ const signer = await this.generateSigner(senderAccount);
213
+ const { address } = senderAccount;
214
+ const addressUrl = this.explorerService.buildAddressUrl(address);
215
+ const nativeTokenHash = BSEthereumHelper_1.BSEthereumHelper.getNativeAsset(this.network).hash;
216
+ const transactions = [];
213
217
  let error;
214
- for (const intent of param.intents) {
215
- let transactionHash = '';
218
+ for (const intent of intents) {
216
219
  try {
217
220
  const { transactionParams, gasPrice } = await this._buildTransferParams(intent);
218
221
  let gasLimit;
@@ -222,29 +225,56 @@ class BSEthereum {
222
225
  catch {
223
226
  gasLimit = BSEthereumConstants_1.BSEthereumConstants.DEFAULT_GAS_LIMIT;
224
227
  }
228
+ const fee = ethers_1.ethers.utils.formatEther(gasPrice.mul(gasLimit));
225
229
  const transaction = await signer.sendTransaction({
226
230
  ...transactionParams,
227
231
  gasLimit,
228
232
  maxPriorityFeePerGas: gasPrice,
229
233
  maxFeePerGas: gasPrice,
230
234
  });
231
- transactionHash = transaction.hash;
235
+ const txId = transaction.hash;
236
+ if (txId) {
237
+ const { receiverAddress, token } = intent;
238
+ const tokenHash = token.hash;
239
+ const isNativeToken = this.tokenService.predicateByHash(nativeTokenHash, tokenHash);
240
+ transactions.push({
241
+ txId,
242
+ txIdUrl: this.explorerService.buildTransactionUrl(txId),
243
+ date: new Date().toJSON(),
244
+ networkFeeAmount: fee,
245
+ type: 'default',
246
+ view: 'default',
247
+ events: [
248
+ {
249
+ eventType: 'token',
250
+ amount: intent.amount,
251
+ methodName: 'transfer',
252
+ from: address,
253
+ fromUrl: addressUrl,
254
+ to: receiverAddress,
255
+ toUrl: this.explorerService.buildAddressUrl(receiverAddress),
256
+ tokenType: isNativeToken ? 'native' : 'erc-20',
257
+ tokenUrl: this.explorerService.buildContractUrl(tokenHash),
258
+ token,
259
+ },
260
+ ],
261
+ });
262
+ }
232
263
  }
233
- catch (err) {
264
+ catch (currentError) {
234
265
  if (!error)
235
- error = err;
266
+ error = currentError;
236
267
  }
237
- sentTransactionHashes.push(transactionHash);
238
268
  }
239
- if (error && sentTransactionHashes.every(hash => !hash)) {
269
+ if (!!error && transactions.length === 0) {
240
270
  throw error;
241
271
  }
242
- return sentTransactionHashes;
272
+ return transactions;
243
273
  }
244
- async calculateTransferFee(param) {
245
- const signer = await this.generateSigner(param.senderAccount);
274
+ async calculateTransferFee(params) {
275
+ const signer = await this.generateSigner(params.senderAccount);
246
276
  let fee = ethers_1.ethers.utils.parseEther('0');
247
- for (const intent of param.intents) {
277
+ for (const intent of params.intents) {
248
278
  const { gasPrice, transactionParams } = await this._buildTransferParams(intent);
249
279
  const estimated = await signer.estimateGas(transactionParams);
250
280
  const intentFee = gasPrice.mul(estimated);
@@ -1,9 +1,9 @@
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;
6
- static readonly DEFAULT_BIP44_DERIVATION_PATH = "m/44'/60'/0'/0/?";
6
+ static readonly DEFAULT_BIP_DERIVATION_PATH = "m/44'/60'/0'/0/?";
7
7
  static readonly NATIVE_SYMBOL_BY_NETWORK_ID: Record<TBSEthereumNetworkId, string>;
8
8
  static readonly NATIVE_WRAPPED_HASH_BY_NETWORK_ID: Partial<Record<TBSEthereumNetworkId, string>>;
9
9
  static readonly RPC_LIST_BY_NETWORK_ID: Record<TBSEthereumNetworkId, string[]>;
@@ -8,7 +8,7 @@ exports.BSEthereumConstants = BSEthereumConstants;
8
8
  _a = BSEthereumConstants;
9
9
  BSEthereumConstants.DEFAULT_DECIMALS = 18;
10
10
  BSEthereumConstants.DEFAULT_GAS_LIMIT = 0x5208;
11
- BSEthereumConstants.DEFAULT_BIP44_DERIVATION_PATH = "m/44'/60'/0'/0/?";
11
+ BSEthereumConstants.DEFAULT_BIP_DERIVATION_PATH = "m/44'/60'/0'/0/?";
12
12
  BSEthereumConstants.NATIVE_SYMBOL_BY_NETWORK_ID = {
13
13
  '1': 'ETH',
14
14
  '10': 'ETH',
@@ -40,8 +40,8 @@ BSEthereumConstants.NATIVE_WRAPPED_HASH_BY_NETWORK_ID = {
40
40
  };
41
41
  BSEthereumConstants.RPC_LIST_BY_NETWORK_ID = {
42
42
  '1': [
43
- 'https://eth.llamarpc.com',
44
43
  'https://ethereum-rpc.publicnode.com',
44
+ 'https://eth.llamarpc.com',
45
45
  'https://rpc.mevblocker.io',
46
46
  'https://rpc.flashbots.net',
47
47
  'https://endpoints.omniatech.io/v1/eth/mainnet/public',
@@ -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 TGetTransactionsByAddressResponse, type TGetTransactionsByAddressParams, type TTransactionDefault } 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;
@@ -11,7 +11,7 @@ export declare class MoralisBDSEthereum<N extends string, A extends TBSNetworkId
11
11
  constructor(service: IBSEthereum<N, A>);
12
12
  getBalance(address: string): Promise<TBalanceResponse[]>;
13
13
  getTokenInfo(hash: string): Promise<TBSToken>;
14
- getTransaction(hash: string): Promise<TTransaction<N>>;
15
- getTransactionsByAddress(params: TGetTransactionsByAddressParams): Promise<TGetTransactionsByAddressResponse<N>>;
14
+ getTransaction(hash: string): Promise<TTransactionDefault<N>>;
15
+ getTransactionsByAddress(params: TGetTransactionsByAddressParams): Promise<TGetTransactionsByAddressResponse<N, TTransactionDefault<N>>>;
16
16
  getContract(hash: string): Promise<TContractResponse>;
17
17
  }
@@ -80,7 +80,7 @@ class MoralisBDSEthereum extends RpcBDSEthereum_1.RpcBDSEthereum {
80
80
  if (this._tokenCache.has(hash)) {
81
81
  return this._tokenCache.get(hash);
82
82
  }
83
- const response = await __classPrivateFieldGet(this, _MoralisBDSEthereum_instances, "a", _MoralisBDSEthereum_api_get).get(`/erc20/metadata`, {
83
+ const response = await __classPrivateFieldGet(this, _MoralisBDSEthereum_instances, "a", _MoralisBDSEthereum_api_get).get('/erc20/metadata', {
84
84
  params: {
85
85
  addresses: [hash],
86
86
  },
@@ -101,29 +101,23 @@ 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), {
116
111
  decimals: nativeToken.decimals,
117
112
  }),
118
- from: data.from_address,
119
- to: data.to_address,
120
- token: nativeToken,
121
- contractHash: nativeToken.hash,
122
- tokenType: 'native',
123
113
  methodName: 'transfer',
124
- contractHashUrl,
114
+ from: data.from_address,
125
115
  fromUrl,
116
+ to: data.to_address,
126
117
  toUrl,
118
+ tokenType: 'native',
119
+ tokenUrl: this._service.explorerService.buildContractUrl(nativeToken.hash),
120
+ token: nativeToken,
127
121
  });
128
122
  }
129
123
  if (data.logs) {
@@ -134,70 +128,58 @@ class MoralisBDSEthereum extends RpcBDSEthereum_1.RpcBDSEthereum {
134
128
  return;
135
129
  const contractHash = log.address;
136
130
  const amount = log.decoded_event.params.find((param) => param.name === 'value')?.value;
137
- const from = log.decoded_event.params.find((param) => param.name === 'from')?.value;
138
- const to = log.decoded_event.params.find((param) => param.name === 'to')?.value;
131
+ const from = log.decoded_event.params.find((param) => param.name === 'from')?.value || data.from_address;
132
+ const to = log.decoded_event.params.find((param) => param.name === 'to')?.value || data.to_address;
139
133
  if (!from || !to)
140
134
  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);
135
+ const fromUrl = this._service.explorerService.buildAddressUrl(from);
136
+ const toUrl = this._service.explorerService.buildAddressUrl(to);
144
137
  if (amount) {
145
138
  const token = await this.getTokenInfo(contractHash);
146
139
  events.push({
147
- contractHash,
140
+ eventType: 'token',
148
141
  amount: blockchain_service_1.BSBigNumberHelper.format(blockchain_service_1.BSBigNumberHelper.fromDecimals(amount, token.decimals), {
149
142
  decimals: token.decimals,
150
143
  }),
144
+ methodName: 'transfer',
151
145
  from,
152
146
  fromUrl,
153
147
  to,
154
148
  toUrl,
155
- eventType: 'token',
156
- methodName: 'transfer',
157
149
  tokenType: 'erc-20',
158
- contractHashUrl,
150
+ tokenUrl: this._service.explorerService.buildContractUrl(contractHash),
151
+ token,
159
152
  });
160
153
  }
161
154
  const tokenHash = log.decoded_event.params.find((param) => param.name === 'tokenId')?.value;
162
155
  if (!tokenHash)
163
156
  return;
164
157
  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
158
  events.push({
169
- collectionHash: contractHash,
170
- tokenHash,
159
+ eventType: 'nft',
160
+ amount: '1',
161
+ methodName: 'transfer',
171
162
  from,
172
163
  fromUrl,
173
164
  to,
174
165
  toUrl,
175
- eventType: 'nft',
176
- methodName: 'transfer',
177
166
  tokenType: 'erc-721',
178
- amount: '1',
179
- nftImageUrl: nft?.image,
180
- nftUrl,
181
- name: nft?.name,
182
- collectionName: nft?.collection?.name,
183
- collectionHashUrl: contractHashUrl,
167
+ nft,
184
168
  });
185
169
  });
186
170
  await Promise.allSettled(promises);
187
171
  }
188
- const txIdUrl = txTemplateUrl?.replace('{txId}', hash);
189
172
  return {
190
173
  txId: hash,
174
+ txIdUrl: this._service.explorerService.buildTransactionUrl(hash),
191
175
  block: Number(data.block_number),
192
- date: new Date(data.block_timestamp).toISOString(),
193
- invocationCount: 0,
194
- notificationCount: 0,
176
+ date: new Date(data.block_timestamp).toJSON(),
195
177
  networkFeeAmount: blockchain_service_1.BSBigNumberHelper.format(blockchain_service_1.BSBigNumberHelper.fromNumber(data.transaction_fee), {
196
178
  decimals: this._service.feeToken.decimals,
197
179
  }),
198
- txIdUrl,
199
- events,
200
180
  type: 'default',
181
+ view: 'default',
182
+ events,
201
183
  };
202
184
  }
203
185
  async getTransactionsByAddress(params) {
@@ -212,113 +194,93 @@ class MoralisBDSEthereum extends RpcBDSEthereum_1.RpcBDSEthereum {
212
194
  });
213
195
  const transactions = [];
214
196
  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) => {
197
+ const promises = data.result.map(async (item, index) => {
220
198
  const events = [];
221
- const nativeContractHashUrl = contractTemplateUrl?.replace('{hash}', nativeAsset.hash);
222
199
  item.native_transfers.forEach(transfer => {
223
- const fromUrl = addressTemplateUrl?.replace('{address}', transfer.from_address);
224
- const toUrl = addressTemplateUrl?.replace('{address}', transfer.to_address);
200
+ const fromUrl = this._service.explorerService.buildAddressUrl(transfer.from_address);
201
+ const toUrl = this._service.explorerService.buildAddressUrl(transfer.to_address);
225
202
  events.push({
203
+ eventType: 'token',
226
204
  amount: blockchain_service_1.BSBigNumberHelper.format(blockchain_service_1.BSBigNumberHelper.fromDecimals(transfer.value, nativeAsset.decimals), {
227
205
  decimals: nativeAsset.decimals,
228
206
  }),
207
+ methodName: 'transfer',
229
208
  from: transfer.from_address,
230
209
  fromUrl,
231
210
  to: transfer.to_address,
232
211
  toUrl,
233
- eventType: 'token',
234
- token: nativeAsset,
235
- contractHash: nativeAsset.hash,
236
- methodName: 'transfer',
237
212
  tokenType: 'native',
238
- contractHashUrl: nativeContractHashUrl,
213
+ tokenUrl: this._service.explorerService.buildContractUrl(nativeAsset.hash),
214
+ token: nativeAsset,
239
215
  });
240
216
  });
241
217
  item.erc20_transfers.forEach(transfer => {
242
218
  if (transfer.possible_spam)
243
219
  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);
220
+ const fromUrl = this._service.explorerService.buildAddressUrl(transfer.from_address);
221
+ const toUrl = this._service.explorerService.buildAddressUrl(transfer.to_address);
222
+ const tokenHash = transfer.address;
223
+ const tokenDecimals = transfer.token_decimals;
247
224
  events.push({
248
- amount: blockchain_service_1.BSBigNumberHelper.format(blockchain_service_1.BSBigNumberHelper.fromDecimals(transfer.value, transfer.token_decimals), {
249
- decimals: transfer.token_decimals,
225
+ eventType: 'token',
226
+ amount: blockchain_service_1.BSBigNumberHelper.format(blockchain_service_1.BSBigNumberHelper.fromDecimals(transfer.value, tokenDecimals), {
227
+ decimals: tokenDecimals,
250
228
  }),
229
+ methodName: 'transfer',
251
230
  from: transfer.from_address,
252
231
  fromUrl,
253
232
  to: transfer.to_address,
254
233
  toUrl,
255
- eventType: 'token',
234
+ tokenType: 'erc-20',
235
+ tokenUrl: this._service.explorerService.buildContractUrl(tokenHash),
256
236
  token: this._service.tokenService.normalizeToken({
257
- decimals: Number(transfer.token_decimals),
258
- hash: transfer.address,
237
+ decimals: Number(tokenDecimals),
238
+ hash: tokenHash,
259
239
  name: transfer.token_name,
260
240
  symbol: transfer.token_symbol,
261
241
  }),
262
- contractHash: transfer.address,
263
- methodName: 'transfer',
264
- tokenType: 'erc-20',
265
- contractHashUrl,
266
242
  });
267
243
  });
268
244
  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);
272
- 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);
245
+ const fromUrl = this._service.explorerService.buildAddressUrl(transfer.from_address);
246
+ const toUrl = this._service.explorerService.buildAddressUrl(transfer.to_address);
247
+ const tokenHash = transfer.token_id;
248
+ const [nft] = await blockchain_service_1.BSUtilsHelper.tryCatch(() => this._service.nftDataService.getNft({ collectionHash: transfer.token_address, tokenHash }));
276
249
  events.push({
277
- collectionHash: transfer.token_address,
278
- collectionHashUrl,
279
- tokenHash: transfer.token_id,
250
+ eventType: 'nft',
251
+ amount: '1',
252
+ methodName: 'transfer',
280
253
  from: transfer.from_address,
281
254
  fromUrl,
282
255
  to: transfer.to_address,
283
256
  toUrl,
284
- eventType: 'nft',
285
- methodName: 'transfer',
286
257
  tokenType: 'erc-721',
287
- amount: '1',
288
- nftImageUrl: nft?.image,
289
- nftUrl,
290
- name: nft?.name,
291
- collectionName: nft?.collection?.name,
258
+ nft,
292
259
  });
293
260
  });
294
261
  await Promise.allSettled(nftPromises);
295
- const txIdUrl = txTemplateUrl?.replace('{txId}', item.hash);
296
- transactions.push({
297
- block: Number(item.block_number),
262
+ transactions.splice(index, 0, {
298
263
  txId: item.hash,
299
- txIdUrl,
300
- notificationCount: 0,
301
- invocationCount: 0,
264
+ txIdUrl: this._service.explorerService.buildTransactionUrl(item.hash),
265
+ block: Number(item.block_number),
266
+ date: new Date(item.block_timestamp).toJSON(),
302
267
  networkFeeAmount: blockchain_service_1.BSBigNumberHelper.format(blockchain_service_1.BSBigNumberHelper.fromNumber(item.transaction_fee), {
303
268
  decimals: this._service.feeToken.decimals,
304
269
  }),
305
- date: new Date(item.block_timestamp).toISOString(),
306
- events,
307
270
  type: 'default',
271
+ view: 'default',
272
+ events,
308
273
  });
309
274
  });
310
275
  await Promise.allSettled(promises);
311
- return {
312
- nextPageParams: data.cursor,
313
- transactions,
314
- };
276
+ return { nextPageParams: data.cursor, transactions };
315
277
  }
316
278
  async getContract(hash) {
317
279
  if (!_a.isSupported(this._service.network)) {
318
280
  return super.getContract(hash);
319
281
  }
320
282
  try {
321
- const { data } = await __classPrivateFieldGet(this, _MoralisBDSEthereum_instances, "a", _MoralisBDSEthereum_api_get).get(`erc20/metadata`, {
283
+ const { data } = await __classPrivateFieldGet(this, _MoralisBDSEthereum_instances, "a", _MoralisBDSEthereum_api_get).get('erc20/metadata', {
322
284
  params: {
323
285
  addresses: [hash],
324
286
  },
@@ -1,13 +1,13 @@
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 TTransactionDefault } 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;
6
6
  readonly _tokenCache: Map<string, TBSToken>;
7
7
  readonly _service: S;
8
8
  constructor(service: S);
9
- getTransaction(hash: string): Promise<TTransaction<N>>;
10
- getTransactionsByAddress(_params: TGetTransactionsByAddressParams): Promise<TGetTransactionsByAddressResponse<N>>;
9
+ getTransaction(hash: string): Promise<TTransactionDefault<N>>;
10
+ getTransactionsByAddress(_params: TGetTransactionsByAddressParams): Promise<TGetTransactionsByAddressResponse<N, TTransactionDefault<N>>>;
11
11
  getContract(_hash: string): Promise<TContractResponse>;
12
12
  getTokenInfo(hash: string): Promise<TBSToken>;
13
13
  getBalance(address: string): Promise<TBalanceResponse[]>;
@@ -35,24 +35,19 @@ 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(),
51
- invocationCount: 0,
52
- notificationCount: 0,
45
+ date: new Date(timestamp).toJSON(),
53
46
  networkFeeAmount: blockchain_service_1.BSBigNumberHelper.format(blockchain_service_1.BSBigNumberHelper.fromDecimals(fee.toString(), this._service.feeToken.decimals), {
54
47
  decimals: this._service.feeToken.decimals,
55
48
  }),
49
+ type: 'default',
50
+ view: 'default',
56
51
  events: [
57
52
  {
58
53
  eventType: 'token',
@@ -64,13 +59,11 @@ class RpcBDSEthereum {
64
59
  fromUrl,
65
60
  to: transaction.to,
66
61
  toUrl,
67
- contractHash: token.hash,
68
- contractHashUrl,
69
- token: token ?? undefined,
70
62
  tokenType: 'native',
63
+ tokenUrl: this._service.explorerService.buildContractUrl(token.hash),
64
+ token,
71
65
  },
72
66
  ],
73
- type: 'default',
74
67
  };
75
68
  }
76
69
  async getTransactionsByAddress(_params) {
@@ -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,16 +1,16 @@
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>>;
6
6
  readonly _service: IBSEthereum<N, A>;
7
7
  constructor(service: IBSEthereum<N, A>, baseUrl?: string);
8
- buildTransactionUrl(hash: string): string | undefined;
8
+ buildTransactionUrl(transactionId: 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
- getTxTemplateUrl(): string | undefined;
13
+ getTransactionTemplateUrl(): string | undefined;
14
14
  getNftTemplateUrl(): string | undefined;
15
15
  getContractTemplateUrl(): string | undefined;
16
16
  }
@@ -10,41 +10,44 @@ 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 _BlockscoutESEthereum_baseUrl;
13
+ var _BlockscoutESEthereum_instances, _BlockscoutESEthereum_baseUrl, _BlockscoutESEthereum_validateValueLength;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.BlockscoutESEthereum = void 0;
16
16
  class BlockscoutESEthereum {
17
17
  constructor(service, baseUrl) {
18
+ _BlockscoutESEthereum_instances.add(this);
18
19
  _BlockscoutESEthereum_baseUrl.set(this, void 0);
19
20
  this._service = service;
20
21
  __classPrivateFieldSet(this, _BlockscoutESEthereum_baseUrl, baseUrl ?? BlockscoutESEthereum.DEFAULT_BASE_URL_BY_NETWORK_ID[this._service.network.id], "f");
21
22
  }
22
- buildTransactionUrl(hash) {
23
- if (!__classPrivateFieldGet(this, _BlockscoutESEthereum_baseUrl, "f"))
23
+ buildTransactionUrl(transactionId) {
24
+ if (!__classPrivateFieldGet(this, _BlockscoutESEthereum_instances, "m", _BlockscoutESEthereum_validateValueLength).call(this, transactionId))
24
25
  return undefined;
25
- return `${__classPrivateFieldGet(this, _BlockscoutESEthereum_baseUrl, "f")}/tx/${this._service.tokenService.normalizeHash(hash)}`;
26
+ return this.getTransactionTemplateUrl()?.replace('{txId}', this._service.tokenService.normalizeHash(transactionId));
26
27
  }
27
28
  buildContractUrl(contractHash) {
28
- if (!__classPrivateFieldGet(this, _BlockscoutESEthereum_baseUrl, "f"))
29
+ if (!__classPrivateFieldGet(this, _BlockscoutESEthereum_instances, "m", _BlockscoutESEthereum_validateValueLength).call(this, contractHash))
29
30
  return undefined;
30
- return `${__classPrivateFieldGet(this, _BlockscoutESEthereum_baseUrl, "f")}/address/${this._service.tokenService.normalizeHash(contractHash)}`;
31
+ return this.getContractTemplateUrl()?.replace('{hash}', this._service.tokenService.normalizeHash(contractHash));
31
32
  }
32
- buildNftUrl(params) {
33
- if (!__classPrivateFieldGet(this, _BlockscoutESEthereum_baseUrl, "f") || !params.collectionHash)
33
+ buildNftUrl({ tokenHash, collectionHash }) {
34
+ if (!__classPrivateFieldGet(this, _BlockscoutESEthereum_instances, "m", _BlockscoutESEthereum_validateValueLength).call(this, tokenHash, 1) || !__classPrivateFieldGet(this, _BlockscoutESEthereum_instances, "m", _BlockscoutESEthereum_validateValueLength).call(this, collectionHash))
34
35
  return undefined;
35
- return `${__classPrivateFieldGet(this, _BlockscoutESEthereum_baseUrl, "f")}/token/${this._service.tokenService.normalizeHash(params.collectionHash)}/instance/${params.tokenHash}`;
36
+ return this.getNftTemplateUrl()
37
+ ?.replace('{tokenHash}', tokenHash)
38
+ ?.replace('{collectionHash}', this._service.tokenService.normalizeHash(collectionHash));
36
39
  }
37
40
  buildAddressUrl(address) {
38
- if (!__classPrivateFieldGet(this, _BlockscoutESEthereum_baseUrl, "f"))
41
+ if (!__classPrivateFieldGet(this, _BlockscoutESEthereum_instances, "m", _BlockscoutESEthereum_validateValueLength).call(this, address))
39
42
  return undefined;
40
- return `${__classPrivateFieldGet(this, _BlockscoutESEthereum_baseUrl, "f")}/address/${address}`;
43
+ return this.getAddressTemplateUrl()?.replace('{address}', address);
41
44
  }
42
45
  getAddressTemplateUrl() {
43
46
  if (!__classPrivateFieldGet(this, _BlockscoutESEthereum_baseUrl, "f"))
44
47
  return undefined;
45
48
  return `${__classPrivateFieldGet(this, _BlockscoutESEthereum_baseUrl, "f")}/address/{address}`;
46
49
  }
47
- getTxTemplateUrl() {
50
+ getTransactionTemplateUrl() {
48
51
  if (!__classPrivateFieldGet(this, _BlockscoutESEthereum_baseUrl, "f"))
49
52
  return undefined;
50
53
  return `${__classPrivateFieldGet(this, _BlockscoutESEthereum_baseUrl, "f")}/tx/{txId}`;
@@ -61,7 +64,9 @@ class BlockscoutESEthereum {
61
64
  }
62
65
  }
63
66
  exports.BlockscoutESEthereum = BlockscoutESEthereum;
64
- _BlockscoutESEthereum_baseUrl = new WeakMap();
67
+ _BlockscoutESEthereum_baseUrl = new WeakMap(), _BlockscoutESEthereum_instances = new WeakSet(), _BlockscoutESEthereum_validateValueLength = function _BlockscoutESEthereum_validateValueLength(value, minimumLength) {
68
+ return !!value?.length && value.length >= (minimumLength || 4);
69
+ };
65
70
  BlockscoutESEthereum.DEFAULT_BASE_URL_BY_NETWORK_ID = {
66
71
  '1': 'https://eth.blockscout.com',
67
72
  '10': 'https://optimism.blockscout.com',
@@ -1,4 +1,4 @@
1
- import { type IFullTransactionsDataService, type TBSNetworkId, type TExportFullTransactionsByAddressParams, type TGetFullTransactionsByAddressParams, type TGetTransactionsByAddressResponse } from '@cityofzion/blockchain-service';
1
+ import { type IFullTransactionsDataService, type TBSNetworkId, type TExportFullTransactionsByAddressParams, type TGetFullTransactionsByAddressParams, type TGetTransactionsByAddressResponse, type TTransactionDefault } from '@cityofzion/blockchain-service';
2
2
  import type { IBSEthereum, TBSEthereumNetworkId } from '../../types';
3
3
  export declare class MoralisFullTransactionsDataServiceEthereum<N extends string, A extends TBSNetworkId> implements IFullTransactionsDataService<N> {
4
4
  #private;
@@ -7,6 +7,6 @@ export declare class MoralisFullTransactionsDataServiceEthereum<N extends string
7
7
  static readonly ERC1155_STANDARDS: string[];
8
8
  static readonly ERC20_STANDARDS: string[];
9
9
  constructor(service: IBSEthereum<N, A>);
10
- getFullTransactionsByAddress({ nextPageParams, ...params }: TGetFullTransactionsByAddressParams): Promise<TGetTransactionsByAddressResponse<N>>;
10
+ getFullTransactionsByAddress({ nextPageParams, ...params }: TGetFullTransactionsByAddressParams): Promise<TGetTransactionsByAddressResponse<N, TTransactionDefault<N>>>;
11
11
  exportFullTransactionsByAddress(params: TExportFullTransactionsByAddressParams): Promise<string>;
12
12
  }
@@ -38,27 +38,19 @@ 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
- const itemPromises = items.map(async ({ networkFeeAmount, systemFeeAmount, ...item }, index) => {
41
+ const itemPromises = items.map(async ({ networkFeeAmount, ...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: __classPrivateFieldGet(this, _MoralisFullTransactionsDataServiceEthereum_service, "f").explorerService.buildTransactionUrl(txId),
50
46
  block: item.block,
51
47
  date: item.date,
52
- invocationCount: item.invocationCount,
53
- notificationCount: item.notificationCount,
54
48
  networkFeeAmount: networkFeeAmount
55
49
  ? blockchain_service_1.BSBigNumberHelper.format(networkFeeAmount, { decimals: nativeToken.decimals })
56
50
  : undefined,
57
- systemFeeAmount: systemFeeAmount
58
- ? blockchain_service_1.BSBigNumberHelper.format(systemFeeAmount, { decimals: nativeToken.decimals })
59
- : undefined,
60
- events: [],
61
51
  type: 'default',
52
+ view: 'default',
53
+ events: [],
62
54
  };
63
55
  const eventPromises = item.events.map(async (event, eventIndex) => {
64
56
  const { methodName, tokenID: tokenHash, contractHash } = event;
@@ -69,30 +61,20 @@ class MoralisFullTransactionsDataServiceEthereum {
69
61
  const isErc721 = MoralisFullTransactionsDataServiceEthereum.ERC721_STANDARDS.includes(standard);
70
62
  const isErc20 = MoralisFullTransactionsDataServiceEthereum.ERC20_STANDARDS.includes(standard);
71
63
  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;
64
+ const fromUrl = from ? __classPrivateFieldGet(this, _MoralisFullTransactionsDataServiceEthereum_service, "f").explorerService.buildAddressUrl(from) : undefined;
65
+ const toUrl = to ? __classPrivateFieldGet(this, _MoralisFullTransactionsDataServiceEthereum_service, "f").explorerService.buildAddressUrl(to) : undefined;
75
66
  if (isNft) {
76
67
  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
68
  newItem.events.splice(eventIndex, 0, {
81
69
  eventType: 'nft',
82
- amount: undefined,
70
+ amount: '1',
83
71
  methodName,
84
72
  from,
85
73
  fromUrl,
86
74
  to,
87
75
  toUrl,
88
- collectionHash: contractHash,
89
- collectionHashUrl: contractHashUrl,
90
- tokenHash,
91
76
  tokenType: isErc1155 ? 'erc-1155' : 'erc-721',
92
- nftImageUrl: nft?.image,
93
- nftUrl,
94
- name: nft?.name,
95
- collectionName: nft?.collection?.name,
77
+ nft,
96
78
  });
97
79
  return;
98
80
  }
@@ -107,10 +89,9 @@ class MoralisFullTransactionsDataServiceEthereum {
107
89
  fromUrl,
108
90
  to,
109
91
  toUrl,
110
- contractHash,
111
- contractHashUrl,
112
- token: token ?? undefined,
113
92
  tokenType: isErc20 ? 'erc-20' : 'generic',
93
+ tokenUrl: __classPrivateFieldGet(this, _MoralisFullTransactionsDataServiceEthereum_service, "f").explorerService.buildContractUrl(contractHash),
94
+ token,
114
95
  });
115
96
  });
116
97
  await Promise.allSettled(eventPromises);
@@ -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';
@@ -6,7 +6,7 @@ import { BSEthereum } from '../../BSEthereum';
6
6
  export declare class EthersLedgerSigner extends Signer implements TypedDataSigner {
7
7
  #private;
8
8
  static shouldRetry: (error: any) => boolean;
9
- constructor(transport: Transport, bip44Path: string, provider?: ethers.providers.Provider, emitter?: TLedgerServiceEmitter);
9
+ constructor(transport: Transport, bipPath: string, provider?: ethers.providers.Provider, emitter?: TLedgerServiceEmitter);
10
10
  connect(provider: ethers.providers.Provider): EthersLedgerSigner;
11
11
  getAddress(): Promise<string>;
12
12
  signMessage(message: string | ethers.utils.Bytes): Promise<string>;
@@ -46,7 +46,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
46
46
  var __importDefault = (this && this.__importDefault) || function (mod) {
47
47
  return (mod && mod.__esModule) ? mod : { "default": mod };
48
48
  };
49
- var _EthersLedgerSigner_transport, _EthersLedgerSigner_emitter, _EthersLedgerSigner_bip44Path, _EthersLedgerSigner_ledgerApp, _EthersLedgerServiceEthereum_blockchainService;
49
+ var _EthersLedgerSigner_transport, _EthersLedgerSigner_emitter, _EthersLedgerSigner_bipPath, _EthersLedgerSigner_ledgerApp, _EthersLedgerServiceEthereum_blockchainService;
50
50
  Object.defineProperty(exports, "__esModule", { value: true });
51
51
  exports.EthersLedgerServiceEthereum = exports.EthersLedgerSigner = void 0;
52
52
  const blockchain_service_1 = require("@cityofzion/blockchain-service");
@@ -55,23 +55,23 @@ const ethers_1 = require("ethers");
55
55
  const properties_1 = require("@ethersproject/properties");
56
56
  const events_1 = __importDefault(require("events"));
57
57
  class EthersLedgerSigner extends ethers_1.Signer {
58
- constructor(transport, bip44Path, provider, emitter) {
58
+ constructor(transport, bipPath, provider, emitter) {
59
59
  super();
60
60
  _EthersLedgerSigner_transport.set(this, void 0);
61
61
  _EthersLedgerSigner_emitter.set(this, void 0);
62
- _EthersLedgerSigner_bip44Path.set(this, void 0);
62
+ _EthersLedgerSigner_bipPath.set(this, void 0);
63
63
  _EthersLedgerSigner_ledgerApp.set(this, void 0);
64
- __classPrivateFieldSet(this, _EthersLedgerSigner_bip44Path, bip44Path, "f");
64
+ __classPrivateFieldSet(this, _EthersLedgerSigner_bipPath, bipPath, "f");
65
65
  __classPrivateFieldSet(this, _EthersLedgerSigner_transport, transport, "f");
66
66
  __classPrivateFieldSet(this, _EthersLedgerSigner_emitter, emitter, "f");
67
67
  __classPrivateFieldSet(this, _EthersLedgerSigner_ledgerApp, new hw_app_eth_1.default(transport), "f");
68
68
  (0, properties_1.defineReadOnly)(this, 'provider', provider);
69
69
  }
70
70
  connect(provider) {
71
- return new EthersLedgerSigner(__classPrivateFieldGet(this, _EthersLedgerSigner_transport, "f"), __classPrivateFieldGet(this, _EthersLedgerSigner_bip44Path, "f"), provider, __classPrivateFieldGet(this, _EthersLedgerSigner_emitter, "f"));
71
+ return new EthersLedgerSigner(__classPrivateFieldGet(this, _EthersLedgerSigner_transport, "f"), __classPrivateFieldGet(this, _EthersLedgerSigner_bipPath, "f"), provider, __classPrivateFieldGet(this, _EthersLedgerSigner_emitter, "f"));
72
72
  }
73
73
  async getAddress() {
74
- const { address } = await blockchain_service_1.BSUtilsHelper.retry(() => __classPrivateFieldGet(this, _EthersLedgerSigner_ledgerApp, "f").getAddress(__classPrivateFieldGet(this, _EthersLedgerSigner_bip44Path, "f")), {
74
+ const { address } = await blockchain_service_1.BSUtilsHelper.retry(() => __classPrivateFieldGet(this, _EthersLedgerSigner_ledgerApp, "f").getAddress(__classPrivateFieldGet(this, _EthersLedgerSigner_bipPath, "f")), {
75
75
  shouldRetry: EthersLedgerSigner.shouldRetry,
76
76
  });
77
77
  return address;
@@ -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_bipPath, "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_bipPath, "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_bipPath, "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_bipPath, "f"), domainSeparatorHex, hashStructMessageHex);
140
138
  }
141
139
  __classPrivateFieldGet(this, _EthersLedgerSigner_emitter, "f")?.emit('getSignatureEnd');
142
140
  // Normalize the signature for Ethers
@@ -151,7 +149,7 @@ class EthersLedgerSigner extends ethers_1.Signer {
151
149
  }
152
150
  }
153
151
  exports.EthersLedgerSigner = EthersLedgerSigner;
154
- _EthersLedgerSigner_transport = new WeakMap(), _EthersLedgerSigner_emitter = new WeakMap(), _EthersLedgerSigner_bip44Path = new WeakMap(), _EthersLedgerSigner_ledgerApp = new WeakMap();
152
+ _EthersLedgerSigner_transport = new WeakMap(), _EthersLedgerSigner_emitter = new WeakMap(), _EthersLedgerSigner_bipPath = new WeakMap(), _EthersLedgerSigner_ledgerApp = new WeakMap();
155
153
  EthersLedgerSigner.shouldRetry = (error) => {
156
154
  return error?.id === 'TransportLocked';
157
155
  };
@@ -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.1.0",
4
4
  "repository": "https://github.com/CityOfZion/blockchain-services",
5
5
  "license": "GPL-3.0-only",
6
6
  "author": "Coz",
@@ -17,16 +17,16 @@
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.1.0"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@ledgerhq/hw-transport": "~6.32.0",
26
26
  "@ledgerhq/hw-transport-node-hid": "~6.30.0",
27
27
  "date-fns": "~4.1.0",
28
28
  "dotenv": "~17.3.1",
29
- "eslint": "~9.36.0",
29
+ "eslint": "~9.37.0",
30
30
  "typescript": "~5.9.2",
31
31
  "vitest": "~4.0.18"
32
32
  },