@toruslabs/ethereum-controllers 5.3.4 → 5.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,7 @@ import { BasePreferencesController, CustomNft, CustomToken, InitPreferencesParam
2
2
  import { SafeEventEmitterProvider } from "@toruslabs/openlogin-jrpc";
3
3
  import KeyringController from "../Keyring/KeyringController";
4
4
  import NetworkController from "../Network/NetworkController";
5
- import type { AddChainMessageParams, CustomNetworkPayload, CustomNftInfo, CustomTokenInfo, ExtendedAddressPreferences, TransactionPayload } from "../utils/interfaces";
5
+ import type { AddChainMessageParams, CustomNetworkPayload, CustomNftInfo, CustomTokenInfo, EtherscanTransaction, ExtendedAddressPreferences, TransactionPayload } from "../utils/interfaces";
6
6
  export interface IPreferencesControllerOptions {
7
7
  config?: Partial<PreferencesConfig> & Pick<PreferencesConfig, "api" | "commonApiHost" | "signInPrefix">;
8
8
  state?: Partial<PreferencesState<ExtendedAddressPreferences>>;
@@ -24,7 +24,7 @@ export default class PreferencesController extends BasePreferencesController<Ext
24
24
  sync(address: string): Promise<boolean>;
25
25
  patchNewTx(tx: TransactionPayload, address: string): Promise<void>;
26
26
  recalculatePastTx(address?: string): void;
27
- refetchEtherscanTx(address?: string): Promise<unknown[]>;
27
+ refetchEtherscanTx(address?: string): Promise<EtherscanTransaction[]>;
28
28
  fetchEtherscanTx<T>(parameters: {
29
29
  selectedAddress: string;
30
30
  chainId: string;
@@ -1,6 +1,6 @@
1
1
  import { TransactionStatus } from "@toruslabs/base-controllers";
2
2
  import { SafeEventEmitterProvider } from "@toruslabs/openlogin-jrpc";
3
- import { FormattedTransactionActivity, TransactionPayload } from "./interfaces";
3
+ import { EtherscanTransaction, FormattedTransactionActivity, TransactionPayload } from "./interfaces";
4
4
  export declare function getEtherScanHashLink(txHash: string, chainId: string): string;
5
5
  export declare const formatPastTx: (x: TransactionPayload, lowerCaseSelectedAddress?: string) => FormattedTransactionActivity;
6
6
  /**
@@ -22,3 +22,4 @@ export declare function bnLessThan(a: string | number, b: string | number): bool
22
22
  export declare const getIpfsEndpoint: (path: string) => string;
23
23
  export declare function sanitizeNftMetdataUrl(url: string): string;
24
24
  export declare function getChainType(chainId: string): "mainnet" | "testnet" | "custom";
25
+ export declare const addEtherscanTransactions: (txn: EtherscanTransaction[], lowerCaseSelectedAddress: string, provider: SafeEventEmitterProvider, chainId: string) => Promise<any[]>;
@@ -330,6 +330,10 @@ export interface TransactionPayload {
330
330
  is_cancel: boolean;
331
331
  contract_address?: string;
332
332
  from_aa_address?: string;
333
+ isEtherscan?: boolean;
334
+ token_id?: string;
335
+ input?: string;
336
+ etherscanLink?: string;
333
337
  }
334
338
  export interface FetchedTransaction extends TransactionPayload {
335
339
  id: string;
@@ -379,6 +383,7 @@ export interface ExtendedAddressPreferences extends AddressPreferences {
379
383
  formattedPastTransactions?: FormattedTransactionActivity[];
380
384
  paymentTx: FetchCommonTransaction[];
381
385
  customNetworks: CustomNetworks[];
386
+ etherscanTransactions?: FormattedTransactionActivity[];
382
387
  }
383
388
  export interface ProviderChangeChannelEventData {
384
389
  newNetwork: EthereumProviderConfig;
@@ -404,3 +409,32 @@ export interface DecryptMessageParams extends BaseRequestParams {
404
409
  export interface DecryptMessage extends AbstractMessage {
405
410
  messageParams: DecryptMessageParams;
406
411
  }
412
+ export interface EtherscanTransaction {
413
+ blockNumber: string;
414
+ timeStamp: string;
415
+ hash: string;
416
+ nonce: string;
417
+ blockHash: string;
418
+ transactionIndex: string;
419
+ from: string;
420
+ to: string;
421
+ value: string;
422
+ gas: string;
423
+ gasPrice: string;
424
+ isError: string;
425
+ txreceipt_status: string;
426
+ input: string;
427
+ contractAddress: string;
428
+ cumulativeGasUsed: string;
429
+ gasUsed: string;
430
+ confirmations: string;
431
+ methodId: string;
432
+ functionName: string;
433
+ transaction_category: string;
434
+ type_name: string;
435
+ type: string;
436
+ type_image_link: string;
437
+ chainId: string;
438
+ tokenSymbol: string;
439
+ tokenID: string;
440
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toruslabs/ethereum-controllers",
3
- "version": "5.3.4",
3
+ "version": "5.3.6",
4
4
  "homepage": "https://github.com/torusresearch/controllers#readme",
5
5
  "license": "ISC",
6
6
  "main": "dist/ethereumControllers.cjs.js",
@@ -24,7 +24,7 @@
24
24
  "@ethereumjs/util": "^9.0.1",
25
25
  "@metamask/eth-sig-util": "^7.0.1",
26
26
  "@metamask/rpc-errors": "^6.1.0",
27
- "@toruslabs/base-controllers": "^5.3.3",
27
+ "@toruslabs/base-controllers": "^5.3.6",
28
28
  "@toruslabs/http-helpers": "^6.0.0",
29
29
  "@toruslabs/openlogin-jrpc": "^6.2.8",
30
30
  "async-mutex": "^0.4.1",
@@ -64,7 +64,7 @@
64
64
  "publishConfig": {
65
65
  "access": "public"
66
66
  },
67
- "gitHead": "475a9fbc714cf8ae618673fc15719d9d73d305be",
67
+ "gitHead": "2e5a28f0076f491fc67f5c837ee3c0acac66aa8c",
68
68
  "devDependencies": {
69
69
  "@nomicfoundation/hardhat-toolbox": "^4.0.0",
70
70
  "hardhat": "^2.19.4"
@@ -18,7 +18,7 @@ import log from "loglevel";
18
18
  import KeyringController from "../Keyring/KeyringController";
19
19
  import NetworkController from "../Network/NetworkController";
20
20
  import { ETHERSCAN_SUPPORTED_CHAINS, SUPPORTED_NETWORKS } from "../utils/constants";
21
- import { formatDate, formatPastTx, formatTime, getEthTxStatus } from "../utils/helpers";
21
+ import { addEtherscanTransactions, formatDate, formatPastTx, formatTime, getEthTxStatus } from "../utils/helpers";
22
22
  import type {
23
23
  AddChainMessageParams,
24
24
  CustomNetworkPayload,
@@ -27,6 +27,7 @@ import type {
27
27
  CustomTokenInfo,
28
28
  EthereumProviderConfig,
29
29
  EthereumUser,
30
+ EtherscanTransaction,
30
31
  ExtendedAddressPreferences,
31
32
  FetchedTransaction,
32
33
  FormattedTransactionActivity,
@@ -57,7 +58,12 @@ export default class PreferencesController
57
58
  private provider: SafeEventEmitterProvider;
58
59
 
59
60
  constructor({ config, state, provider, signAuthMessage, getProviderConfig, setProviderConfig }: IPreferencesControllerOptions) {
60
- super({ config, state, defaultPreferences: { formattedPastTransactions: [], fetchedPastTx: [], paymentTx: [] }, signAuthMessage });
61
+ super({
62
+ config,
63
+ state,
64
+ defaultPreferences: { formattedPastTransactions: [], fetchedPastTx: [], paymentTx: [], etherscanTransactions: [] },
65
+ signAuthMessage,
66
+ });
61
67
  this.provider = provider;
62
68
  this.getProviderConfig = getProviderConfig;
63
69
  this.setProviderConfig = setProviderConfig;
@@ -81,7 +87,7 @@ export default class PreferencesController
81
87
 
82
88
  public async initPreferences(params: InitPreferencesParams): Promise<void> {
83
89
  const { address, jwtToken, calledFromEmbed, userInfo, rehydrate, locale = "en-US", type, signatures, web3AuthClientId, web3AuthNetwork } = params;
84
- await super.init({ address, userInfo, idToken: jwtToken, type, metadata: { email: userInfo.email, signatures } });
90
+ await super.init({ address, userInfo, idToken: jwtToken, type, metadata: { email: userInfo.email, signatures, network: web3AuthNetwork } });
85
91
  const { aggregateVerifier, verifier, verifierId } = userInfo || {};
86
92
  const userExists = await this.sync(address);
87
93
  if (!userExists) {
@@ -204,7 +210,13 @@ export default class PreferencesController
204
210
  if (this.getAddressState(selectedAddress)?.jwtToken) {
205
211
  const { chainId } = this.getProviderConfig();
206
212
  if (ETHERSCAN_SUPPORTED_CHAINS.includes(chainId)) {
207
- return this.fetchEtherscanTx({ selectedAddress, chainId: this.getProviderConfig().chainId });
213
+ const etherscanTxn = await this.fetchEtherscanTx<EtherscanTransaction>({
214
+ selectedAddress,
215
+ chainId: this.getProviderConfig().chainId,
216
+ });
217
+ const finalEthScanTxn = await addEtherscanTransactions(etherscanTxn, selectedAddress, this.provider, chainId);
218
+ this.updateState({ etherscanTransactions: finalEthScanTxn });
219
+ return etherscanTxn;
208
220
  }
209
221
  }
210
222
  }
@@ -214,6 +226,7 @@ export default class PreferencesController
214
226
  const url = new URL(`${this.config.api}/etherscan`);
215
227
  url.searchParams.append("chainId", parameters.chainId);
216
228
  const response = await get<{ success: boolean; data: T[] }>(url.href, this.headers(parameters.selectedAddress));
229
+ log.info("Etherscan Response", response);
217
230
  return response.success ? response.data : [];
218
231
  } catch (error) {
219
232
  log.error("unable to fetch etherscan tx", error);
@@ -63,7 +63,7 @@ export const SUPPORTED_NETWORKS: Record<string, EthereumProviderConfig> = {
63
63
  blockExplorerUrl: "https://bscscan.com",
64
64
  chainId: BSC_MAINNET_CHAIN_ID,
65
65
  displayName: "Binance Smart Chain (BSC)",
66
- logo: "bnb_logo.png",
66
+ logo: "bnb_logo.svg",
67
67
  rpcTarget: `https://bsc-dataseed.binance.org`,
68
68
  ticker: "BNB",
69
69
  tickerName: "Binance Coin",
@@ -118,7 +118,7 @@ export const SUPPORTED_NETWORKS: Record<string, EthereumProviderConfig> = {
118
118
  blockExplorerUrl: "https://gnosis.blockscout.com",
119
119
  chainId: XDAI_CHAIN_ID,
120
120
  displayName: "xDai",
121
- logo: "xdai.svg",
121
+ logo: "xDai.svg",
122
122
  rpcTarget: `https://rpc.gnosischain.com`,
123
123
  ticker: "DAI",
124
124
  tickerName: "xDai Token",
@@ -164,7 +164,7 @@ export const SUPPORTED_NETWORKS: Record<string, EthereumProviderConfig> = {
164
164
  blockExplorerUrl: "https://testnet.bscscan.com",
165
165
  chainId: BSC_TESTNET_CHAIN_ID,
166
166
  displayName: "Binance Smart Chain Testnet",
167
- logo: "bnb_logo.png",
167
+ logo: "bnb_logo.svg",
168
168
  rpcTarget: `https://data-seed-prebsc-1-s1.binance.org:8545`,
169
169
  ticker: "BNB",
170
170
  tickerName: "Binance Coin",
@@ -9,18 +9,21 @@ import {
9
9
  } from "@toruslabs/base-controllers";
10
10
  import { SafeEventEmitterProvider } from "@toruslabs/openlogin-jrpc";
11
11
  import BigNumber from "bignumber.js";
12
+ import { formatEther } from "ethers";
12
13
  import log from "loglevel";
13
14
 
15
+ import { determineTransactionType } from "../Transaction/TransactionUtils";
14
16
  import {
15
17
  CONTRACT_TYPE_ERC20,
16
18
  CONTRACT_TYPE_ERC721,
17
19
  CONTRACT_TYPE_ERC1155,
20
+ CONTRACT_TYPE_ETH,
18
21
  MAINNET_CHAIN_ID,
19
22
  METHOD_TYPES,
20
23
  SUPPORTED_NETWORKS,
21
24
  TEST_CHAINS,
22
25
  } from "./constants";
23
- import { FormattedTransactionActivity, TransactionPayload, TransactionReceipt } from "./interfaces";
26
+ import { EtherscanTransaction, FormattedTransactionActivity, TransactionParams, TransactionPayload, TransactionReceipt } from "./interfaces";
24
27
 
25
28
  export function getEtherScanHashLink(txHash: string, chainId: string) {
26
29
  if (!SUPPORTED_NETWORKS[chainId]) return "";
@@ -64,9 +67,9 @@ export const formatPastTx = (x: TransactionPayload, lowerCaseSelectedAddress?: s
64
67
  transaction_hash: x.transaction_hash,
65
68
  transaction_category: x.transaction_category,
66
69
  // TODO: // figure out how to handle these values.
67
- // isEtherscan: x.isEtherscan,
68
- // input: x.input || "",
69
- // token_id: x.token_id || "",
70
+ isEtherscan: x.isEtherscan,
71
+ input: x.input || "",
72
+ token_id: x.token_id || "",
70
73
  contract_address: x.contract_address || "",
71
74
  nonce: x.nonce || "",
72
75
  is_cancel: !!x.is_cancel || false,
@@ -177,3 +180,55 @@ export function getChainType(chainId: string) {
177
180
  }
178
181
  return "custom";
179
182
  }
183
+
184
+ export const addEtherscanTransactions = async (
185
+ txn: EtherscanTransaction[],
186
+ lowerCaseSelectedAddress: string,
187
+ provider: SafeEventEmitterProvider,
188
+ chainId: string
189
+ ) => {
190
+ const transactionPromises = await Promise.all(
191
+ txn.map(async (tx: EtherscanTransaction) => {
192
+ const { category, type } = await determineTransactionType({ ...tx, data: tx.input } as TransactionParams, provider);
193
+ tx.transaction_category = tx.transaction_category || category;
194
+ tx.type_image_link = SUPPORTED_NETWORKS[chainId]?.logo || "";
195
+ tx.type_name = SUPPORTED_NETWORKS[chainId]?.ticker;
196
+ tx.type = type;
197
+ return tx;
198
+ })
199
+ );
200
+
201
+ const finalTxs = transactionPromises.reduce((accumulator, x) => {
202
+ const totalAmount = x.value ? formatEther(x.value) : "";
203
+ const etherscanTransaction: TransactionPayload = {
204
+ etherscanLink: getEtherScanHashLink(x.hash, chainId),
205
+ type: x.type || SUPPORTED_NETWORKS[chainId]?.ticker || CONTRACT_TYPE_ETH,
206
+ type_image_link: x.type_image_link || "n/a",
207
+ type_name: x.type_name || "n/a",
208
+ symbol: SUPPORTED_NETWORKS[chainId]?.ticker,
209
+ token_id: x.tokenID || "",
210
+ total_amount: totalAmount,
211
+ created_at: new Date(Number(x.timeStamp) * 1000),
212
+ from: x.from,
213
+ to: x.to,
214
+ transaction_hash: x.hash,
215
+ status: x.txreceipt_status && x.txreceipt_status === "0" ? TransactionStatus.failed : TransactionStatus.approved,
216
+ isEtherscan: true,
217
+ input: x.input,
218
+ contract_address: x.contractAddress,
219
+ transaction_category: x.transaction_category,
220
+ gas: x.gas,
221
+ gasPrice: x.gasPrice,
222
+ chain_id: chainId,
223
+ currency_amount: "",
224
+ nonce: x.nonce,
225
+ from_aa_address: "",
226
+ is_cancel: false,
227
+ selected_currency: "",
228
+ };
229
+ accumulator.push(formatPastTx(etherscanTransaction, lowerCaseSelectedAddress));
230
+ return accumulator;
231
+ }, []);
232
+
233
+ return finalTxs;
234
+ };
@@ -394,6 +394,10 @@ export interface TransactionPayload {
394
394
  is_cancel: boolean;
395
395
  contract_address?: string;
396
396
  from_aa_address?: string;
397
+ isEtherscan?: boolean;
398
+ token_id?: string;
399
+ input?: string;
400
+ etherscanLink?: string;
397
401
  }
398
402
 
399
403
  export interface FetchedTransaction extends TransactionPayload {
@@ -447,6 +451,7 @@ export interface ExtendedAddressPreferences extends AddressPreferences {
447
451
  formattedPastTransactions?: FormattedTransactionActivity[];
448
452
  paymentTx: FetchCommonTransaction[];
449
453
  customNetworks: CustomNetworks[];
454
+ etherscanTransactions?: FormattedTransactionActivity[];
450
455
  }
451
456
 
452
457
  export interface ProviderChangeChannelEventData {
@@ -479,3 +484,33 @@ export interface DecryptMessageParams extends BaseRequestParams {
479
484
  export interface DecryptMessage extends AbstractMessage {
480
485
  messageParams: DecryptMessageParams;
481
486
  }
487
+
488
+ export interface EtherscanTransaction {
489
+ blockNumber: string;
490
+ timeStamp: string;
491
+ hash: string;
492
+ nonce: string;
493
+ blockHash: string;
494
+ transactionIndex: string;
495
+ from: string;
496
+ to: string;
497
+ value: string;
498
+ gas: string;
499
+ gasPrice: string;
500
+ isError: string;
501
+ txreceipt_status: string;
502
+ input: string;
503
+ contractAddress: string;
504
+ cumulativeGasUsed: string;
505
+ gasUsed: string;
506
+ confirmations: string;
507
+ methodId: string;
508
+ functionName: string;
509
+ transaction_category: string;
510
+ type_name: string;
511
+ type: string;
512
+ type_image_link: string;
513
+ chainId: string;
514
+ tokenSymbol: string;
515
+ tokenID: string;
516
+ }