/* This file is part of web3.js. web3.js is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. web3.js is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with web3.js. If not, see . */ // eslint-disable-next-line max-classes-per-file import { Web3Context, Web3ContextInitOptions, Web3ContextObject, Web3SubscriptionConstructor, isSupportedProvider } from 'web3-core'; import { Web3Eth, RegisteredSubscription, registeredSubscriptions } from 'web3-eth'; import Contract from 'web3-eth-contract'; import { ENS, registryAddresses } from 'web3-eth-ens'; import { Iban } from 'web3-eth-iban'; import { Personal } from 'web3-eth-personal'; import { Net } from 'web3-net'; import * as utils from 'web3-utils'; import { isNullish, isDataFormat, isContractInitOptions } from 'web3-utils'; import { Address, ContractAbi, ContractInitOptions, EthExecutionAPI, SupportedProviders, DataFormat, DEFAULT_RETURN_FORMAT } from 'web3-types'; import { InvalidMethodParamsError } from 'web3-errors'; import abi from './abi.js'; import { initAccountsForContext } from './accounts.js'; import { Web3EthInterface } from './types.js'; import { Web3PkgInfo } from './version.js'; import { onNewProviderDiscovered, requestEIP6963Providers } from './web3_eip6963.js'; export class Web3< CustomRegisteredSubscription extends { [key: string]: Web3SubscriptionConstructor; } = RegisteredSubscription, > extends Web3Context { public static version = Web3PkgInfo.version; public static utils = utils; public static requestEIP6963Providers = requestEIP6963Providers; public static onNewProviderDiscovered = onNewProviderDiscovered; public static modules = { Web3Eth, Iban, Net, ENS, Personal, }; public utils: typeof utils; public eth: Web3EthInterface; public constructor( providerOrContext?: | string | SupportedProviders | Web3ContextInitOptions, ) { if ( isNullish(providerOrContext) || (typeof providerOrContext === 'string' && providerOrContext.trim() === '') || (typeof providerOrContext !== 'string' && !isSupportedProvider(providerOrContext as SupportedProviders) && !(providerOrContext as Web3ContextInitOptions).provider) ) { console.warn( 'NOTE: web3.js is running without provider. You need to pass a provider in order to interact with the network!', ); } let contextInitOptions: Web3ContextInitOptions = {}; if ( typeof providerOrContext === 'string' || isSupportedProvider(providerOrContext as SupportedProviders) ) { contextInitOptions.provider = providerOrContext as | undefined | string | SupportedProviders; } else if (providerOrContext) { contextInitOptions = providerOrContext as Web3ContextInitOptions; } else { contextInitOptions = {}; } contextInitOptions.registeredSubscriptions = { // all the Eth standard subscriptions ...registeredSubscriptions, // overridden and combined with any custom subscriptions ...(contextInitOptions.registeredSubscriptions ?? {}), } as CustomRegisteredSubscription; super(contextInitOptions); const accounts = initAccountsForContext(this); // Init protected properties this._wallet = accounts.wallet; this._accountProvider = accounts; this.utils = utils; // Have to use local alias to initiate contract context // eslint-disable-next-line @typescript-eslint/no-this-alias const self = this; class ContractBuilder extends Contract { public constructor(jsonInterface: Abi); public constructor(jsonInterface: Abi, addressOrOptionsOrContext?: Address | ContractInitOptions | Web3Context, ); public constructor( jsonInterface: Abi, addressOrOptionsOrContext?: Address | ContractInitOptions | Web3Context, optionsOrContextOrReturnFormat?: ContractInitOptions | Web3Context | DataFormat, ); public constructor(jsonInterface: Abi, addressOrOptionsOrContext?: Address | ContractInitOptions, optionsOrContextOrReturnFormat?: ContractInitOptions, contextOrReturnFormat?: Web3Context | DataFormat, ); public constructor(jsonInterface: Abi, addressOrOptionsOrContext?: Address | ContractInitOptions, optionsOrContextOrReturnFormat?: ContractInitOptions, contextOrReturnFormat?: Web3Context | DataFormat, ); public constructor(jsonInterface: Abi, addressOrOptionsOrContext?: Address | ContractInitOptions, optionsOrContextOrReturnFormat?: ContractInitOptions, contextOrReturnFormat?: Web3Context | DataFormat, returnFormat?: DataFormat ) { if (isContractInitOptions(addressOrOptionsOrContext) && isContractInitOptions(optionsOrContextOrReturnFormat)) { throw new InvalidMethodParamsError( 'Should not provide options at both 2nd and 3rd parameters', ); } let address: string | undefined; let options: object = {}; let context: Web3ContextObject; let dataFormat: DataFormat = DEFAULT_RETURN_FORMAT; // add validation so its not a breaking change if (!isNullish(addressOrOptionsOrContext) && typeof addressOrOptionsOrContext !== 'object' && typeof addressOrOptionsOrContext !== 'string') { throw new InvalidMethodParamsError(); } if (typeof addressOrOptionsOrContext === 'string') { address = addressOrOptionsOrContext; } if (isContractInitOptions(addressOrOptionsOrContext)){ options = addressOrOptionsOrContext as object; } else if (isContractInitOptions(optionsOrContextOrReturnFormat)) { options = optionsOrContextOrReturnFormat as object; } else { options = {} } if (addressOrOptionsOrContext instanceof Web3Context) { context = addressOrOptionsOrContext; } else if (optionsOrContextOrReturnFormat instanceof Web3Context) { context = optionsOrContextOrReturnFormat; } else if (contextOrReturnFormat instanceof Web3Context) { context = contextOrReturnFormat; } else { context = self.getContextObject() as Web3ContextObject; } if (returnFormat){ dataFormat = returnFormat; } else if (isDataFormat(optionsOrContextOrReturnFormat)) { dataFormat = optionsOrContextOrReturnFormat as DataFormat; } else if (isDataFormat(contextOrReturnFormat)) { dataFormat = contextOrReturnFormat; } super(jsonInterface,address, options, context, dataFormat) super.subscribeToContextEvents(self); } } const eth = self.use(Web3Eth); // Eth Module this.eth = Object.assign(eth, { // ENS module ens: self.use(ENS, registryAddresses.main), // registry address defaults to main network // Iban helpers Iban, net: self.use(Net), personal: self.use(Personal), // Contract helper and module Contract: ContractBuilder, // ABI Helpers abi, // Accounts helper accounts, }); } } export default Web3;