@cityofzion/bs-ethereum 3.0.6 → 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,4 +1,4 @@
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';
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
4
  import type { IBSEthereum, TBSEthereumNetworkId, TSupportedEVM } from './types';
@@ -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: TTransferParams<N>): Promise<string[]>;
45
- calculateTransferFee(param: TTransferParams<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.bipDerivationPath = 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,8 +105,9 @@ 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.bipPath !== '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
112
  return this.ledgerService.getSigner(ledgerTransport, account.bipPath, provider);
112
113
  }
@@ -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);
@@ -3,7 +3,7 @@ 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,4 +1,4 @@
1
- import { type TBalanceResponse, type TBSToken, type TBSNetwork, type 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
3
  import type { IBSEthereum, TBSEthereumNetworkId } from '../../types';
4
4
  import { RpcBDSEthereum } from './RpcBDSEthereum';
@@ -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
  },
@@ -110,15 +110,14 @@ class MoralisBDSEthereum extends RpcBDSEthereum_1.RpcBDSEthereum {
110
110
  amount: blockchain_service_1.BSBigNumberHelper.format(blockchain_service_1.BSBigNumberHelper.fromDecimals(data.value, nativeToken.decimals), {
111
111
  decimals: nativeToken.decimals,
112
112
  }),
113
- from: data.from_address,
114
- to: data.to_address,
115
- token: nativeToken,
116
- contractHash: nativeToken.hash,
117
- tokenType: 'native',
118
113
  methodName: 'transfer',
119
- contractHashUrl: this._service.explorerService.buildContractUrl(nativeToken.hash),
114
+ from: data.from_address,
120
115
  fromUrl,
116
+ to: data.to_address,
121
117
  toUrl,
118
+ tokenType: 'native',
119
+ tokenUrl: this._service.explorerService.buildContractUrl(nativeToken.hash),
120
+ token: nativeToken,
122
121
  });
123
122
  }
124
123
  if (data.logs) {
@@ -129,27 +128,27 @@ class MoralisBDSEthereum extends RpcBDSEthereum_1.RpcBDSEthereum {
129
128
  return;
130
129
  const contractHash = log.address;
131
130
  const amount = log.decoded_event.params.find((param) => param.name === 'value')?.value;
132
- const from = log.decoded_event.params.find((param) => param.name === 'from')?.value;
133
- 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;
134
133
  if (!from || !to)
135
134
  return;
136
- const fromUrl = this._service.explorerService.buildAddressUrl(data.from_address);
137
- const toUrl = this._service.explorerService.buildAddressUrl(data.to_address);
135
+ const fromUrl = this._service.explorerService.buildAddressUrl(from);
136
+ const toUrl = this._service.explorerService.buildAddressUrl(to);
138
137
  if (amount) {
139
138
  const token = await this.getTokenInfo(contractHash);
140
139
  events.push({
141
- contractHash,
140
+ eventType: 'token',
142
141
  amount: blockchain_service_1.BSBigNumberHelper.format(blockchain_service_1.BSBigNumberHelper.fromDecimals(amount, token.decimals), {
143
142
  decimals: token.decimals,
144
143
  }),
144
+ methodName: 'transfer',
145
145
  from,
146
146
  fromUrl,
147
147
  to,
148
148
  toUrl,
149
- eventType: 'token',
150
- methodName: 'transfer',
151
149
  tokenType: 'erc-20',
152
- contractHashUrl: this._service.explorerService.buildContractUrl(contractHash),
150
+ tokenUrl: this._service.explorerService.buildContractUrl(contractHash),
151
+ token,
153
152
  });
154
153
  }
155
154
  const tokenHash = log.decoded_event.params.find((param) => param.name === 'tokenId')?.value;
@@ -157,37 +156,30 @@ class MoralisBDSEthereum extends RpcBDSEthereum_1.RpcBDSEthereum {
157
156
  return;
158
157
  const [nft] = await blockchain_service_1.BSUtilsHelper.tryCatch(() => this._service.nftDataService.getNft({ collectionHash: contractHash, tokenHash }));
159
158
  events.push({
160
- collectionHash: contractHash,
161
- tokenHash,
159
+ eventType: 'nft',
160
+ amount: '1',
161
+ methodName: 'transfer',
162
162
  from,
163
163
  fromUrl,
164
164
  to,
165
165
  toUrl,
166
- eventType: 'nft',
167
- methodName: 'transfer',
168
166
  tokenType: 'erc-721',
169
- amount: '1',
170
- nftImageUrl: nft?.image,
171
- nftUrl: nft?.explorerUri,
172
- name: nft?.name,
173
- collectionName: nft?.collection?.name,
174
- collectionHashUrl: nft?.collection?.url,
167
+ nft,
175
168
  });
176
169
  });
177
170
  await Promise.allSettled(promises);
178
171
  }
179
172
  return {
180
173
  txId: hash,
174
+ txIdUrl: this._service.explorerService.buildTransactionUrl(hash),
181
175
  block: Number(data.block_number),
182
176
  date: new Date(data.block_timestamp).toJSON(),
183
- invocationCount: 0,
184
- notificationCount: 0,
185
177
  networkFeeAmount: blockchain_service_1.BSBigNumberHelper.format(blockchain_service_1.BSBigNumberHelper.fromNumber(data.transaction_fee), {
186
178
  decimals: this._service.feeToken.decimals,
187
179
  }),
188
- txIdUrl: this._service.explorerService.buildTransactionUrl(hash),
189
- events,
190
180
  type: 'default',
181
+ view: 'default',
182
+ events,
191
183
  };
192
184
  }
193
185
  async getTransactionsByAddress(params) {
@@ -208,19 +200,18 @@ class MoralisBDSEthereum extends RpcBDSEthereum_1.RpcBDSEthereum {
208
200
  const fromUrl = this._service.explorerService.buildAddressUrl(transfer.from_address);
209
201
  const toUrl = this._service.explorerService.buildAddressUrl(transfer.to_address);
210
202
  events.push({
203
+ eventType: 'token',
211
204
  amount: blockchain_service_1.BSBigNumberHelper.format(blockchain_service_1.BSBigNumberHelper.fromDecimals(transfer.value, nativeAsset.decimals), {
212
205
  decimals: nativeAsset.decimals,
213
206
  }),
207
+ methodName: 'transfer',
214
208
  from: transfer.from_address,
215
209
  fromUrl,
216
210
  to: transfer.to_address,
217
211
  toUrl,
218
- eventType: 'token',
219
- token: nativeAsset,
220
- contractHash: nativeAsset.hash,
221
- methodName: 'transfer',
222
212
  tokenType: 'native',
223
- contractHashUrl: this._service.explorerService.buildContractUrl(nativeAsset.hash),
213
+ tokenUrl: this._service.explorerService.buildContractUrl(nativeAsset.hash),
214
+ token: nativeAsset,
224
215
  });
225
216
  });
226
217
  item.erc20_transfers.forEach(transfer => {
@@ -228,76 +219,68 @@ class MoralisBDSEthereum extends RpcBDSEthereum_1.RpcBDSEthereum {
228
219
  return;
229
220
  const fromUrl = this._service.explorerService.buildAddressUrl(transfer.from_address);
230
221
  const toUrl = this._service.explorerService.buildAddressUrl(transfer.to_address);
222
+ const tokenHash = transfer.address;
223
+ const tokenDecimals = transfer.token_decimals;
231
224
  events.push({
232
- amount: blockchain_service_1.BSBigNumberHelper.format(blockchain_service_1.BSBigNumberHelper.fromDecimals(transfer.value, transfer.token_decimals), {
233
- 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,
234
228
  }),
229
+ methodName: 'transfer',
235
230
  from: transfer.from_address,
236
231
  fromUrl,
237
232
  to: transfer.to_address,
238
233
  toUrl,
239
- eventType: 'token',
234
+ tokenType: 'erc-20',
235
+ tokenUrl: this._service.explorerService.buildContractUrl(tokenHash),
240
236
  token: this._service.tokenService.normalizeToken({
241
- decimals: Number(transfer.token_decimals),
242
- hash: transfer.address,
237
+ decimals: Number(tokenDecimals),
238
+ hash: tokenHash,
243
239
  name: transfer.token_name,
244
240
  symbol: transfer.token_symbol,
245
241
  }),
246
- contractHash: transfer.address,
247
- methodName: 'transfer',
248
- tokenType: 'erc-20',
249
- contractHashUrl: this._service.explorerService.buildContractUrl(transfer.address),
250
242
  });
251
243
  });
252
244
  const nftPromises = item.nft_transfers.map(async (transfer) => {
253
245
  const fromUrl = this._service.explorerService.buildAddressUrl(transfer.from_address);
254
246
  const toUrl = this._service.explorerService.buildAddressUrl(transfer.to_address);
255
- const [nft] = await blockchain_service_1.BSUtilsHelper.tryCatch(() => this._service.nftDataService.getNft({ collectionHash: transfer.token_address, tokenHash: transfer.token_id }));
247
+ const tokenHash = transfer.token_id;
248
+ const [nft] = await blockchain_service_1.BSUtilsHelper.tryCatch(() => this._service.nftDataService.getNft({ collectionHash: transfer.token_address, tokenHash }));
256
249
  events.push({
257
- collectionHash: transfer.token_address,
258
- collectionHashUrl: nft?.collection?.url,
259
- tokenHash: transfer.token_id,
250
+ eventType: 'nft',
251
+ amount: '1',
252
+ methodName: 'transfer',
260
253
  from: transfer.from_address,
261
254
  fromUrl,
262
255
  to: transfer.to_address,
263
256
  toUrl,
264
- eventType: 'nft',
265
- methodName: 'transfer',
266
257
  tokenType: 'erc-721',
267
- amount: '1',
268
- nftImageUrl: nft?.image,
269
- nftUrl: nft?.explorerUri,
270
- name: nft?.name,
271
- collectionName: nft?.collection?.name,
258
+ nft,
272
259
  });
273
260
  });
274
261
  await Promise.allSettled(nftPromises);
275
262
  transactions.splice(index, 0, {
276
- block: Number(item.block_number),
277
263
  txId: item.hash,
278
264
  txIdUrl: this._service.explorerService.buildTransactionUrl(item.hash),
279
- notificationCount: 0,
280
- invocationCount: 0,
265
+ block: Number(item.block_number),
266
+ date: new Date(item.block_timestamp).toJSON(),
281
267
  networkFeeAmount: blockchain_service_1.BSBigNumberHelper.format(blockchain_service_1.BSBigNumberHelper.fromNumber(item.transaction_fee), {
282
268
  decimals: this._service.feeToken.decimals,
283
269
  }),
284
- date: new Date(item.block_timestamp).toJSON(),
285
- events,
286
270
  type: 'default',
271
+ view: 'default',
272
+ events,
287
273
  });
288
274
  });
289
275
  await Promise.allSettled(promises);
290
- return {
291
- nextPageParams: data.cursor,
292
- transactions,
293
- };
276
+ return { nextPageParams: data.cursor, transactions };
294
277
  }
295
278
  async getContract(hash) {
296
279
  if (!_a.isSupported(this._service.network)) {
297
280
  return super.getContract(hash);
298
281
  }
299
282
  try {
300
- 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', {
301
284
  params: {
302
285
  addresses: [hash],
303
286
  },
@@ -1,4 +1,4 @@
1
- import { type TBalanceResponse, type IBlockchainDataService, type TBSNetworkId, type TBSToken, type TContractResponse, type TGetTransactionsByAddressParams, type TGetTransactionsByAddressResponse, type TTransaction } from '@cityofzion/blockchain-service';
1
+ import { type TBalanceResponse, type IBlockchainDataService, type TBSNetworkId, type TBSToken, type TContractResponse, type TGetTransactionsByAddressParams, type TGetTransactionsByAddressResponse, type TTransactionDefault } from '@cityofzion/blockchain-service';
2
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;
@@ -6,8 +6,8 @@ export declare class RpcBDSEthereum<N extends string, A extends TBSNetworkId, S
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[]>;
@@ -43,11 +43,11 @@ class RpcBDSEthereum {
43
43
  txIdUrl: this._service.explorerService.buildTransactionUrl(hash),
44
44
  block: receipt.blockNumber,
45
45
  date: new Date(timestamp).toJSON(),
46
- invocationCount: 0,
47
- notificationCount: 0,
48
46
  networkFeeAmount: blockchain_service_1.BSBigNumberHelper.format(blockchain_service_1.BSBigNumberHelper.fromDecimals(fee.toString(), this._service.feeToken.decimals), {
49
47
  decimals: this._service.feeToken.decimals,
50
48
  }),
49
+ type: 'default',
50
+ view: 'default',
51
51
  events: [
52
52
  {
53
53
  eventType: 'token',
@@ -59,13 +59,11 @@ class RpcBDSEthereum {
59
59
  fromUrl,
60
60
  to: transaction.to,
61
61
  toUrl,
62
- contractHash: token.hash,
63
- contractHashUrl: this._service.explorerService.buildContractUrl(token.hash),
64
- token: token ?? undefined,
65
62
  tokenType: 'native',
63
+ tokenUrl: this._service.explorerService.buildContractUrl(token.hash),
64
+ token,
66
65
  },
67
66
  ],
68
- type: 'default',
69
67
  };
70
68
  }
71
69
  async getTransactionsByAddress(_params) {
@@ -5,12 +5,12 @@ export declare class BlockscoutESEthereum<N extends string, A extends TBSNetwork
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
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") || !hash?.length)
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") || !contractHash?.length)
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
33
  buildNftUrl({ tokenHash, collectionHash }) {
33
- if (!__classPrivateFieldGet(this, _BlockscoutESEthereum_baseUrl, "f") || !tokenHash?.length || !collectionHash?.length)
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(collectionHash)}/instance/${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") || !address?.length)
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,23 +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 itemPromises = items.map(async ({ networkFeeAmount, systemFeeAmount, ...item }, index) => {
41
+ const itemPromises = items.map(async ({ networkFeeAmount, ...item }, index) => {
42
42
  const txId = item.transactionID;
43
43
  const newItem = {
44
44
  txId,
45
- txIdUrl: txId ? __classPrivateFieldGet(this, _MoralisFullTransactionsDataServiceEthereum_service, "f").explorerService.buildTransactionUrl(txId) : undefined,
45
+ txIdUrl: __classPrivateFieldGet(this, _MoralisFullTransactionsDataServiceEthereum_service, "f").explorerService.buildTransactionUrl(txId),
46
46
  block: item.block,
47
47
  date: item.date,
48
- invocationCount: item.invocationCount,
49
- notificationCount: item.notificationCount,
50
48
  networkFeeAmount: networkFeeAmount
51
49
  ? blockchain_service_1.BSBigNumberHelper.format(networkFeeAmount, { decimals: nativeToken.decimals })
52
50
  : undefined,
53
- systemFeeAmount: systemFeeAmount
54
- ? blockchain_service_1.BSBigNumberHelper.format(systemFeeAmount, { decimals: nativeToken.decimals })
55
- : undefined,
56
- events: [],
57
51
  type: 'default',
52
+ view: 'default',
53
+ events: [],
58
54
  };
59
55
  const eventPromises = item.events.map(async (event, eventIndex) => {
60
56
  const { methodName, tokenID: tokenHash, contractHash } = event;
@@ -71,20 +67,14 @@ class MoralisFullTransactionsDataServiceEthereum {
71
67
  const [nft] = await blockchain_service_1.BSUtilsHelper.tryCatch(() => __classPrivateFieldGet(this, _MoralisFullTransactionsDataServiceEthereum_service, "f").nftDataService.getNft({ collectionHash: contractHash, tokenHash }));
72
68
  newItem.events.splice(eventIndex, 0, {
73
69
  eventType: 'nft',
74
- amount: undefined,
70
+ amount: '1',
75
71
  methodName,
76
72
  from,
77
73
  fromUrl,
78
74
  to,
79
75
  toUrl,
80
- collectionHash: contractHash,
81
- collectionHashUrl: nft?.collection?.url,
82
- tokenHash,
83
76
  tokenType: isErc1155 ? 'erc-1155' : 'erc-721',
84
- nftImageUrl: nft?.image,
85
- nftUrl: nft?.explorerUri,
86
- name: nft?.name,
87
- collectionName: nft?.collection?.name,
77
+ nft,
88
78
  });
89
79
  return;
90
80
  }
@@ -99,10 +89,9 @@ class MoralisFullTransactionsDataServiceEthereum {
99
89
  fromUrl,
100
90
  to,
101
91
  toUrl,
102
- contractHash,
103
- contractHashUrl: __classPrivateFieldGet(this, _MoralisFullTransactionsDataServiceEthereum_service, "f").explorerService.buildContractUrl(contractHash),
104
- token: token ?? undefined,
105
92
  tokenType: isErc20 ? 'erc-20' : 'generic',
93
+ tokenUrl: __classPrivateFieldGet(this, _MoralisFullTransactionsDataServiceEthereum_service, "f").explorerService.buildContractUrl(contractHash),
94
+ token,
106
95
  });
107
96
  });
108
97
  await Promise.allSettled(eventPromises);
@@ -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 __classPrivateFieldGet(this, _EthersLedgerSigner_ledgerApp, "f").signPersonalMessage(__classPrivateFieldGet(this, _EthersLedgerSigner_bip44Path, "f"), ethers_1.ethers.utils.hexlify(message).substring(2));
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 __classPrivateFieldGet(this, _EthersLedgerSigner_ledgerApp, "f").signTransaction(__classPrivateFieldGet(this, _EthersLedgerSigner_bip44Path, "f"), serializedUnsignedTransaction, resolution);
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,12 +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 __classPrivateFieldGet(this, _EthersLedgerSigner_ledgerApp, "f").signEIP712Message(__classPrivateFieldGet(this, _EthersLedgerSigner_bip44Path, "f"), payload);
132
+ obj = await __classPrivateFieldGet(this, _EthersLedgerSigner_ledgerApp, "f").signEIP712Message(__classPrivateFieldGet(this, _EthersLedgerSigner_bipPath, "f"), payload);
133
133
  }
134
134
  catch {
135
135
  const domainSeparatorHex = ethers_1.ethers.utils._TypedDataEncoder.hashDomain(payload.domain);
136
136
  const hashStructMessageHex = ethers_1.ethers.utils._TypedDataEncoder.hashStruct(payload.primaryType, types, payload.message);
137
- obj = await __classPrivateFieldGet(this, _EthersLedgerSigner_ledgerApp, "f").signEIP712HashedMessage(__classPrivateFieldGet(this, _EthersLedgerSigner_bip44Path, "f"), domainSeparatorHex, hashStructMessageHex);
137
+ obj = await __classPrivateFieldGet(this, _EthersLedgerSigner_ledgerApp, "f").signEIP712HashedMessage(__classPrivateFieldGet(this, _EthersLedgerSigner_bipPath, "f"), domainSeparatorHex, hashStructMessageHex);
138
138
  }
139
139
  __classPrivateFieldGet(this, _EthersLedgerSigner_emitter, "f")?.emit('getSignatureEnd');
140
140
  // Normalize the signature for Ethers
@@ -149,7 +149,7 @@ class EthersLedgerSigner extends ethers_1.Signer {
149
149
  }
150
150
  }
151
151
  exports.EthersLedgerSigner = EthersLedgerSigner;
152
- _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();
153
153
  EthersLedgerSigner.shouldRetry = (error) => {
154
154
  return error?.id === 'TransportLocked';
155
155
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cityofzion/bs-ethereum",
3
- "version": "3.0.6",
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",
@@ -19,14 +19,14 @@
19
19
  "@ledgerhq/hw-app-eth": "~7.3.0",
20
20
  "axios": "~1.13.5",
21
21
  "ethers": "5.8.0",
22
- "@cityofzion/blockchain-service": "3.0.6"
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
  },