@web3-react/abstract-connector#AbstractConnector TypeScript Examples

The following examples show how to use @web3-react/abstract-connector#AbstractConnector. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: NetworkConnector.ts    From cuiswap with GNU General Public License v3.0 6 votes vote down vote up
export class NetworkConnector extends AbstractConnector {
  private readonly providers: { [chainId: number]: MiniRpcProvider }
  private currentChainId: number

  constructor({ urls, defaultChainId }: NetworkConnectorArguments) {
    invariant(defaultChainId || Object.keys(urls).length === 1, 'defaultChainId is a required argument with >1 url')
    super({ supportedChainIds: Object.keys(urls).map((k): number => Number(k)) })

    this.currentChainId = defaultChainId || Number(Object.keys(urls)[0])
    this.providers = Object.keys(urls).reduce<{ [chainId: number]: MiniRpcProvider }>((accumulator, chainId) => {
      accumulator[Number(chainId)] = new MiniRpcProvider(Number(chainId), urls[Number(chainId)])
      return accumulator
    }, {})
  }

  public async activate(): Promise<ConnectorUpdate> {
    return { provider: this.providers[this.currentChainId], chainId: this.currentChainId, account: null }
  }

  public async getProvider(): Promise<MiniRpcProvider> {
    return this.providers[this.currentChainId]
  }

  public async getChainId(): Promise<number> {
    return this.currentChainId
  }

  public async getAccount(): Promise<null> {
    return null
  }

  public deactivate() {
    return
  }
}
Example #2
Source File: index.tsx    From luaswap-interface with GNU General Public License v3.0 6 votes vote down vote up
// eslint-disable-next-line react/prop-types
function StatusIcon({ connector }: { connector: AbstractConnector }) {
  if (connector === injected) {
    return <Identicon />
  } else if (connector === walletconnect) {
    return (
      <IconWrapper size={16}>
        <img src={WalletConnectIcon} alt={''} />
      </IconWrapper>
    )
  } else if (connector === walletlink) {
    return (
      <IconWrapper size={16}>
        <img src={CoinbaseWalletIcon} alt={''} />
      </IconWrapper>
    )
  } else if (connector === fortmatic) {
    return (
      <IconWrapper size={16}>
        <img src={FortmaticIcon} alt={''} />
      </IconWrapper>
    )
  } else if (connector === portis) {
    return (
      <IconWrapper size={16}>
        <img src={PortisIcon} alt={''} />
      </IconWrapper>
    )
  }
  return null
}
Example #3
Source File: NetworkConnector.ts    From forward.swaps with GNU General Public License v3.0 6 votes vote down vote up
export class NetworkConnector extends AbstractConnector {
  private readonly providers: { [chainId: number]: MiniRpcProvider }
  private currentChainId: number

  constructor({ urls, defaultChainId }: NetworkConnectorArguments) {
    invariant(defaultChainId || Object.keys(urls).length === 1, 'defaultChainId is a required argument with >1 url')
    super({ supportedChainIds: Object.keys(urls).map((k): number => Number(k)) })

    this.currentChainId = defaultChainId || Number(Object.keys(urls)[0])
    this.providers = Object.keys(urls).reduce<{ [chainId: number]: MiniRpcProvider }>((accumulator, chainId) => {
      accumulator[Number(chainId)] = new MiniRpcProvider(Number(chainId), urls[Number(chainId)])
      return accumulator
    }, {})
  }

  public get provider(): MiniRpcProvider {
    return this.providers[this.currentChainId]
  }

  public async activate(): Promise<ConnectorUpdate> {
    return { provider: this.providers[this.currentChainId], chainId: this.currentChainId, account: null }
  }

  public async getProvider(): Promise<MiniRpcProvider> {
    return this.providers[this.currentChainId]
  }

  public async getChainId(): Promise<number> {
    return this.currentChainId
  }

  public async getAccount(): Promise<null> {
    return null
  }

  public deactivate() {
    return
  }
}
Example #4
Source File: index.tsx    From forward.swaps with GNU General Public License v3.0 6 votes vote down vote up
// eslint-disable-next-line react/prop-types
function StatusIcon({ connector }: { connector: AbstractConnector }) {
  if (connector === injected) {
    return <Identicon />
  } else if (connector === walletconnect) {
    return (
      <IconWrapper size={16}>
        <img src={WalletConnectIcon} alt={''} />
      </IconWrapper>
    )
  } else if (connector === walletlink) {
    return (
      <IconWrapper size={16}>
        <img src={CoinbaseWalletIcon} alt={''} />
      </IconWrapper>
    )
  } else if (connector === fortmatic) {
    return (
      <IconWrapper size={16}>
        <img src={FortmaticIcon} alt={''} />
      </IconWrapper>
    )
  } else if (connector === portis) {
    return (
      <IconWrapper size={16}>
        <img src={PortisIcon} alt={''} />
      </IconWrapper>
    )
  }
  return null
}
Example #5
Source File: connector.d.ts    From safe-apps-sdk with MIT License 6 votes vote down vote up
declare class SafeAppConnector extends AbstractConnector {
    private readonly sdk;
    private safe;
    private provider;
    constructor(opts?: Opts);
    activate(): Promise<ConnectorUpdate>;
    getSafeInfo(): Promise<SafeInfo>;
    getProvider(): Promise<SafeAppProvider>;
    getChainId(): Promise<number>;
    getAccount(): Promise<string>;
    deactivate(): void;
    isSafeApp(): Promise<boolean>;
}
Example #6
Source File: index.tsx    From skeleton-web3-interface with GNU General Public License v3.0 6 votes vote down vote up
// eslint-disable-next-line react/prop-types
function StatusIcon({ connector }: { connector: AbstractConnector }) {
  if (connector === injected) {
    return <Identicon />
  } else if (connector === walletconnect) {
    return (
      <IconWrapper size={16}>
        <img src={WalletConnectIcon} alt={''} />
      </IconWrapper>
    )
  } else if (connector === walletlink) {
    return (
      <IconWrapper size={16}>
        <img src={CoinbaseWalletIcon} alt={''} />
      </IconWrapper>
    )
  } else if (connector === fortmatic) {
    return (
      <IconWrapper size={16}>
        <img src={FortmaticIcon} alt={''} />
      </IconWrapper>
    )
  } else if (connector === portis) {
    return (
      <IconWrapper size={16}>
        <img src={PortisIcon} alt={''} />
      </IconWrapper>
    )
  }
  return null
}
Example #7
Source File: index.tsx    From goose-frontend-amm with GNU General Public License v3.0 6 votes vote down vote up
// eslint-disable-next-line react/prop-types
function StatusIcon({ connector }: { connector: AbstractConnector }) {
  if (connector === injected || connector === bsc) {
    return <Identicon />
  } if (connector === walletconnect) {
    return (
      <IconWrapper size={16}>
        <img src={WalletConnectIcon} alt="" />
      </IconWrapper>
    )
  } if (connector === walletlink) {
    return (
      <IconWrapper size={16}>
        <img src={CoinbaseWalletIcon} alt="" />
      </IconWrapper>
    )
  } if (connector === fortmatic) {
    return (
      <IconWrapper size={16}>
        <img src={FortmaticIcon} alt="" />
      </IconWrapper>
    )
  } if (connector === portis) {
    return (
      <IconWrapper size={16}>
        <img src={PortisIcon} alt="" />
      </IconWrapper>
    )
  }
  return null
}
Example #8
Source File: NetworkConnector.ts    From dyp with Do What The F*ck You Want To Public License 6 votes vote down vote up
export class NetworkConnector extends AbstractConnector {
  private readonly providers: { [chainId: number]: MiniRpcProvider }
  private currentChainId: number

  constructor({ urls, defaultChainId }: NetworkConnectorArguments) {
    invariant(defaultChainId || Object.keys(urls).length === 1, 'defaultChainId is a required argument with >1 url')
    super({ supportedChainIds: Object.keys(urls).map((k): number => Number(k)) })

    this.currentChainId = defaultChainId || Number(Object.keys(urls)[0])
    this.providers = Object.keys(urls).reduce<{ [chainId: number]: MiniRpcProvider }>((accumulator, chainId) => {
      accumulator[Number(chainId)] = new MiniRpcProvider(Number(chainId), urls[Number(chainId)])
      return accumulator
    }, {})
  }

  public get provider(): MiniRpcProvider {
    return this.providers[this.currentChainId]
  }

  public async activate(): Promise<ConnectorUpdate> {
    return { provider: this.providers[this.currentChainId], chainId: this.currentChainId, account: null }
  }

  public async getProvider(): Promise<MiniRpcProvider> {
    return this.providers[this.currentChainId]
  }

  public async getChainId(): Promise<number> {
    return this.currentChainId
  }

  public async getAccount(): Promise<null> {
    return null
  }

  public deactivate() {
    return
  }
}
Example #9
Source File: index.tsx    From dyp with Do What The F*ck You Want To Public License 6 votes vote down vote up
// eslint-disable-next-line react/prop-types
function StatusIcon({ connector }: { connector: AbstractConnector }) {
  if (connector === injected) {
    return <Identicon />
  } else if (connector === walletconnect) {
    return (
      <IconWrapper size={16}>
        <img src={WalletConnectIcon} alt={''} />
      </IconWrapper>
    )
  } else if (connector === walletlink) {
    return (
      <IconWrapper size={16}>
        <img src={CoinbaseWalletIcon} alt={''} />
      </IconWrapper>
    )
  } else if (connector === fortmatic) {
    return (
      <IconWrapper size={16}>
        <img src={FortmaticIcon} alt={''} />
      </IconWrapper>
    )
  } else if (connector === portis) {
    return (
      <IconWrapper size={16}>
        <img src={PortisIcon} alt={''} />
      </IconWrapper>
    )
  }
  return null
}
Example #10
Source File: index.tsx    From cheeseswap-interface with GNU General Public License v3.0 6 votes vote down vote up
// eslint-disable-next-line react/prop-types
function StatusIcon({ connector }: { connector: AbstractConnector }) {
  if (connector === injected || connector === bsc) {
    return <Identicon />
  } else if (connector === walletconnect) {
    return (
      <IconWrapper size={16}>
        <img src={WalletConnectIcon} alt={''} />
      </IconWrapper>
    )
  } else if (connector === walletlink) {
    return (
      <IconWrapper size={16}>
        <img src={CoinbaseWalletIcon} alt={''} />
      </IconWrapper>
    )
  } else if (connector === fortmatic) {
    return (
      <IconWrapper size={16}>
        <img src={FortmaticIcon} alt={''} />
      </IconWrapper>
    )
  } else if (connector === portis) {
    return (
      <IconWrapper size={16}>
        <img src={PortisIcon} alt={''} />
      </IconWrapper>
    )
  }
  return null
}
Example #11
Source File: NetworkConnector.ts    From sybil-interface with GNU General Public License v3.0 6 votes vote down vote up
export class NetworkConnector extends AbstractConnector {
  private readonly providers: { [chainId: number]: MiniRpcProvider }
  private currentChainId: number

  constructor({ urls, defaultChainId }: NetworkConnectorArguments) {
    invariant(defaultChainId || Object.keys(urls).length === 1, 'defaultChainId is a required argument with >1 url')
    super({ supportedChainIds: Object.keys(urls).map((k): number => Number(k)) })

    this.currentChainId = defaultChainId || Number(Object.keys(urls)[0])
    this.providers = Object.keys(urls).reduce<{ [chainId: number]: MiniRpcProvider }>((accumulator, chainId) => {
      accumulator[Number(chainId)] = new MiniRpcProvider(Number(chainId), urls[Number(chainId)])
      return accumulator
    }, {})
  }

  public get provider(): MiniRpcProvider {
    return this.providers[this.currentChainId]
  }

  public async activate(): Promise<ConnectorUpdate> {
    return { provider: this.providers[this.currentChainId], chainId: this.currentChainId, account: null }
  }

  public async getProvider(): Promise<MiniRpcProvider> {
    return this.providers[this.currentChainId]
  }

  public async getChainId(): Promise<number> {
    return this.currentChainId
  }

  public async getAccount(): Promise<null> {
    return null
  }

  public deactivate() {
    return
  }
}
Example #12
Source File: PendingView.tsx    From sybil-interface with GNU General Public License v3.0 5 votes vote down vote up
export default function PendingView({
  connector,
  error = false,
  setPendingError,
  tryActivation,
}: {
  connector?: AbstractConnector
  error?: boolean
  setPendingError: (error: boolean) => void
  tryActivation: (connector: AbstractConnector) => void
}): JSX.Element {
  const isMetamask = window?.ethereum?.isMetaMask

  return (
    <PendingSection>
      <LoadingMessage error={error}>
        <LoadingWrapper>
          {error ? (
            <ErrorGroup>
              <div>Error connecting.</div>
              <ErrorButton
                onClick={() => {
                  setPendingError(false)
                  connector && tryActivation(connector)
                }}
              >
                Try Again
              </ErrorButton>
            </ErrorGroup>
          ) : (
            <>
              <StyledLoader />
              Initializing...
            </>
          )}
        </LoadingWrapper>
      </LoadingMessage>
      {Object.keys(SUPPORTED_WALLETS).map((key) => {
        const option = SUPPORTED_WALLETS[key]
        if (option.connector === connector) {
          if (option.connector === injected) {
            if (isMetamask && option.name !== 'MetaMask') {
              return null
            }
            if (!isMetamask && option.name === 'MetaMask') {
              return null
            }
          }
          return (
            <Option
              id={`connect-${key}`}
              key={key}
              clickable={false}
              color={option.color}
              header={option.name}
              subheader={option.description}
              icon={option.iconURL}
            />
          )
        }
        return null
      })}
    </PendingSection>
  )
}
Example #13
Source File: PendingView.tsx    From cuiswap with GNU General Public License v3.0 5 votes vote down vote up
export default function PendingView({
  connector,
  error = false,
  setPendingError,
  tryActivation
}: {
  connector?: AbstractConnector
  error?: boolean
  setPendingError: (error: boolean) => void
  tryActivation: (connector: AbstractConnector) => void
}) {
  const isMetamask = window?.ethereum?.isMetaMask

  return (
    <PendingSection>
      <LoadingMessage error={error}>
        <LoadingWrapper>
          {error ? (
            <ErrorGroup>
              <div>Error connecting.</div>
              <ErrorButton
                onClick={() => {
                  setPendingError(false)
                  tryActivation(connector)
                }}
              >
                Try Again
              </ErrorButton>
            </ErrorGroup>
          ) : (
            <>
              <StyledLoader />
              Initializing...
            </>
          )}
        </LoadingWrapper>
      </LoadingMessage>
      {Object.keys(SUPPORTED_WALLETS).map(key => {
        const option = SUPPORTED_WALLETS[key]
        if (option.connector === connector) {
          if (option.connector === injected) {
            if (isMetamask && option.name !== 'MetaMask') {
              return null
            }
            if (!isMetamask && option.name === 'MetaMask') {
              return null
            }
          }
          return (
            <Option
              id={`connect-${key}`}
              key={key}
              clickable={false}
              color={option.color}
              header={option.name}
              subheader={option.description}
              icon={require('../../assets/images/' + option.iconName)}
            />
          )
        }
        return null
      })}
    </PendingSection>
  )
}
Example #14
Source File: ledgerConnector.ts    From index-ui with MIT License 5 votes vote down vote up
export class LedgerConnector extends AbstractConnector {
  private readonly provider: Web3ProviderEngine
  private readonly ledger: HookedWalletSubprovider

  constructor(
    private readonly chainId: number,
    rpcUrl: string,
    wsUrl: string,
    baseDerivationPath: string = "44'/60'/0'/0/0"
  ) {
    super({ supportedChainIds: [chainId] })
    this.provider = new Web3ProviderEngine()
    this.provider.addProvider(new FiltersSubprovider())
    this.provider.addProvider(new NonceSubprovider())
    this.provider.addProvider(new CacheSubprovider())
    const transport = () => TransportWebUSB.create()
    this.ledger = createLedgerSubprovider(transport, {
      networkId: chainId,
      paths: [baseDerivationPath],
    })
    this.provider.addProvider(this.ledger)
    // TODO: standardised ws endpoint?
    // WS is required to retrieve balances
    this.provider.addProvider(new WsSubprovider({ rpcUrl: wsUrl }))
    this.provider.addProvider(new RpcSubprovider({ rpcUrl }))
  }

  async activate(): Promise<ConnectorUpdate<string | number>> {
    // Only start the provider on activation. The engine will start
    // polling the blockchain.
    this.provider.start()
    return { provider: this.provider, chainId: this.chainId }
  }

  async getProvider(): Promise<Web3ProviderEngine> {
    return this.provider
  }

  async getChainId(): Promise<string | number> {
    return this.chainId
  }

  async getAccount(): Promise<string> {
    // getAccounts is a callback. See HookedWalletSubprovider from
    // metamask. We wrap the callback in a promise and return it.
    return new Promise((resolve, reject) => {
      this.ledger.getAccounts((err: Error, res: string[]) => {
        if (err != null) {
          reject(err)
        } else {
          if (!res.length) {
            reject('no accounts found')
          }
          resolve(res[0])
        }
      })
    })
  }

  deactivate(): void {
    this.provider.stop()
  }
}
Example #15
Source File: Login.tsx    From nft-market with MIT License 5 votes vote down vote up
Login = () => {
  const { activatingConnector, setActivatingConnector } = useAppState()
  const { connector, activate } = useWeb3React()
  return (
    <Flex sx={{ justifyContent: 'center' }}>
      {Object.keys(connectorsByName).map((name: string) => {
        const currentConnector = connectorsByName[name as keyof typeof connectorsByName]
        const activating = currentConnector === activatingConnector
        const connected = currentConnector === connector

        return (
          <Button
            mt={2}
            mr={2}
            variant="connect"
            sx={{
              borderColor: activating ? 'orange' : connected ? 'green' : 'unset',
              position: 'relative',
              maxWidth: 250,
            }}
            key={name}
            onClick={() => {
              setActivatingConnector(currentConnector)
              activate(connectorsByName[name as keyof typeof connectorsByName] as AbstractConnector)
            }}
          >
            {iconsMap[name as keyof typeof connectorsByName] && (
              <Image
                sx={{ width: 35, height: 35 }}
                mr={3}
                src={iconsMap[name as keyof typeof connectorsByName]}
              />
            )}

            {name}
            {activating && <Spinner size={20} color="white" sx={{ ml: 3 }} />}
          </Button>
        )
      })}
    </Flex>
  )
}
Example #16
Source File: Login.tsx    From nft-market with MIT License 5 votes vote down vote up
Login = () => {
  const { activatingConnector, setActivatingConnector } = useAppState()
  const { connector, activate } = useWeb3React()
  return (
    <Flex sx={{ justifyContent: 'center' }}>
      {Object.keys(connectorsByName).map((name: string) => {
        const currentConnector = connectorsByName[name as keyof typeof connectorsByName]
        const activating = currentConnector === activatingConnector
        const connected = currentConnector === connector

        return (
          <Button
            mt={2}
            mr={2}
            variant="connect"
            sx={{
              borderColor: activating ? 'orange' : connected ? 'green' : 'unset',
              position: 'relative',
              maxWidth: 250,
            }}
            key={name}
            onClick={() => {
              setActivatingConnector(currentConnector)
              activate(connectorsByName[name as keyof typeof connectorsByName] as AbstractConnector)
            }}
          >
            {iconsMap[name as keyof typeof connectorsByName] && (
              <Image
                sx={{ width: 35, height: 35 }}
                mr={3}
                src={iconsMap[name as keyof typeof connectorsByName]}
              />
            )}

            {name}
            {activating && <Spinner size={20} color="white" sx={{ ml: 3 }} />}
          </Button>
        )
      })}
    </Flex>
  )
}
Example #17
Source File: connector.ts    From safe-apps-sdk with MIT License 5 votes vote down vote up
class SafeAppConnector extends AbstractConnector {
  private readonly sdk: SafeAppsSDK;
  private safe: SafeInfo | undefined;
  private provider: SafeAppProvider | undefined;

  constructor(opts?: Opts) {
    super();
    this.sdk = new SafeAppsSDK(opts);
  }

  async activate(): Promise<ConnectorUpdate> {
    const runningAsSafeApp = await this.isSafeApp();
    if (!runningAsSafeApp) {
      throw new Error('The app is loaded outside safe context');
    }

    return { provider: await this.getProvider(), chainId: await this.getChainId(), account: await this.getAccount() };
  }

  public async getSafeInfo(): Promise<SafeInfo> {
    if (!this.safe) {
      this.safe = await this.sdk.safe.getInfo();
    }
    return this.safe;
  }

  public async getProvider(): Promise<SafeAppProvider> {
    if (!this.provider) {
      const safe = await this.getSafeInfo();
      this.provider = new SafeAppProvider(safe, this.sdk);
    }
    return this.provider;
  }

  public async getChainId(): Promise<number> {
    const provider = await this.getProvider();
    return provider.chainId;
  }

  public async getAccount(): Promise<string> {
    const safe = await this.getSafeInfo();
    return safe.safeAddress;
  }

  public deactivate(): void {
    return;
  }

  public async isSafeApp(): Promise<boolean> {
    // check if we're in an iframe
    if (window?.parent === window) {
      return false;
    }

    const safe = await Promise.race([
      this.getSafeInfo(),
      new Promise<undefined>((resolve) => setTimeout(resolve, 300)),
    ]);

    return !!safe;
  }
}
Example #18
Source File: Arkane.ts    From interface-v2 with GNU General Public License v3.0 5 votes vote down vote up
export class ArkaneConnector extends AbstractConnector {
  private readonly clientID: string;
  private readonly chainId: number;

  public arkane: any;

  constructor({ clientID, chainId }: ArkaneConnectorArguments) {
    invariant(
      Object.keys(CHAIN_ID_NETWORK_ARGUMENT).includes(chainId.toString()),
      `Unsupported chainId ${chainId}`,
    );
    super({ supportedChainIds: [chainId] });

    this.clientID = clientID;
    this.chainId = chainId;
  }

  public async activate(): Promise<ConnectorUpdate> {
    const options = {
      clientId: this.clientID,
      secretType: SecretType.MATIC,
      signMethod: 'POPUP',
      skipAuthentication: false,
    };
    const arkaneProvider = await Arkane.createArkaneProviderEngine(options);
    if (!this.arkane) {
      this.arkane = new ArkaneConnect(this.clientID);
    }

    const web3 = new Web3(arkaneProvider as any);
    const accounts = await web3.eth.getAccounts();

    return {
      provider: arkaneProvider,
      chainId: this.chainId,
      account: accounts[0],
    };
  }

  public async getProvider(): Promise<any> {
    const options = {
      clientId: this.clientID,
      secretType: SecretType.MATIC,
      signMethod: 'POPUP',
      skipAuthentication: false,
    };
    return Arkane.createArkaneProviderEngine(options);
  }

  public async getChainId(): Promise<number | string> {
    return this.chainId;
  }

  public async getAccount(): Promise<null | string> {
    return this.arkane.flows
      .getAccount(SecretType.MATIC)
      .then((accounts: any): string => accounts.wallets[0].address);
  }

  public deactivate(): void {
    console.log('deactivate');
  }

  public async close(): Promise<void> {
    await this.arkane.logout();
    this.emitDeactivate();
  }
}
Example #19
Source File: NetworkConnector.ts    From pancake-swap-testnet with MIT License 5 votes vote down vote up
export class NetworkConnector extends AbstractConnector {
  private readonly providers: { [chainId: number]: MiniRpcProvider }

  private currentChainId: number

  constructor({ urls, defaultChainId }: NetworkConnectorArguments) {
    invariant(defaultChainId || Object.keys(urls).length === 1, 'defaultChainId is a required argument with >1 url')
    super({ supportedChainIds: Object.keys(urls).map((k): number => Number(k)) })

    this.currentChainId = defaultChainId || Number(Object.keys(urls)[0])
    this.providers = Object.keys(urls).reduce<{ [chainId: number]: MiniRpcProvider }>((accumulator, chainId) => {
      accumulator[Number(chainId)] = new MiniRpcProvider(Number(chainId), urls[Number(chainId)])
      return accumulator
    }, {})
  }

  public get provider(): MiniRpcProvider {
    return this.providers[this.currentChainId]
  }

  public async activate(): Promise<ConnectorUpdate> {
    return { provider: this.providers[this.currentChainId], chainId: this.currentChainId, account: null }
  }

  public async getProvider(): Promise<MiniRpcProvider> {
    return this.providers[this.currentChainId]
  }

  public async getChainId(): Promise<number> {
    return this.currentChainId
  }

  public async getAccount(): Promise<null> {
    return null
  }

  public deactivate() {
    return null
  }
}
Example #20
Source File: NetworkConnector.ts    From pancake-swap-exchange-testnet with GNU General Public License v3.0 5 votes vote down vote up
export class NetworkConnector extends AbstractConnector {
  private readonly providers: { [chainId: number]: MiniRpcProvider }

  private currentChainId: number

  constructor({ urls, defaultChainId }: NetworkConnectorArguments) {
    invariant(defaultChainId || Object.keys(urls).length === 1, 'defaultChainId is a required argument with >1 url')
    super({ supportedChainIds: Object.keys(urls).map((k): number => Number(k)) })

    this.currentChainId = defaultChainId || Number(Object.keys(urls)[0])
    this.providers = Object.keys(urls).reduce<{ [chainId: number]: MiniRpcProvider }>((accumulator, chainId) => {
      accumulator[Number(chainId)] = new MiniRpcProvider(Number(chainId), urls[Number(chainId)])
      return accumulator
    }, {})
  }

  public get provider(): MiniRpcProvider {
    return this.providers[this.currentChainId]
  }

  public async activate(): Promise<ConnectorUpdate> {
    return { provider: this.providers[this.currentChainId], chainId: this.currentChainId, account: null }
  }

  public async getProvider(): Promise<MiniRpcProvider> {
    return this.providers[this.currentChainId]
  }

  public async getChainId(): Promise<number> {
    return this.currentChainId
  }

  public async getAccount(): Promise<null> {
    return null
  }

  public deactivate() {
    return null
  }
}
Example #21
Source File: NetworkConnector.ts    From mozartfinance-swap-interface with GNU General Public License v3.0 5 votes vote down vote up
export class NetworkConnector extends AbstractConnector {
  private readonly providers: { [chainId: number]: MiniRpcProvider }

  private currentChainId: number

  constructor({ urls, defaultChainId }: NetworkConnectorArguments) {
    invariant(defaultChainId || Object.keys(urls).length === 1, 'defaultChainId is a required argument with >1 url')
    super({ supportedChainIds: Object.keys(urls).map((k): number => Number(k)) })

    this.currentChainId = defaultChainId || Number(Object.keys(urls)[0])
    this.providers = Object.keys(urls).reduce<{ [chainId: number]: MiniRpcProvider }>((accumulator, chainId) => {
      accumulator[Number(chainId)] = new MiniRpcProvider(Number(chainId), urls[Number(chainId)])
      return accumulator
    }, {})
  }

  public get provider(): MiniRpcProvider {
    return this.providers[this.currentChainId]
  }

  public async activate(): Promise<ConnectorUpdate> {
    return { provider: this.providers[this.currentChainId], chainId: this.currentChainId, account: null }
  }

  public async getProvider(): Promise<MiniRpcProvider> {
    return this.providers[this.currentChainId]
  }

  public async getChainId(): Promise<number> {
    return this.currentChainId
  }

  public async getAccount(): Promise<null> {
    return null
  }

  public deactivate() {
    return null
  }
}
Example #22
Source File: Fortmatic.ts    From interface-v2 with GNU General Public License v3.0 5 votes vote down vote up
export class FortmaticConnector extends AbstractConnector {
  private readonly apiKey: string;
  private readonly chainId: number;

  public fortmatic: any;

  constructor({ apiKey, chainId }: FortmaticConnectorArguments) {
    invariant(
      Object.keys(CHAIN_ID_NETWORK_ARGUMENT).includes(chainId.toString()),
      `Unsupported chainId ${chainId}`,
    );
    super({ supportedChainIds: [chainId] });

    this.apiKey = apiKey;
    this.chainId = chainId;
  }

  async activate(): Promise<{
    provider: any;
    chainId: any;
    account: any;
  }> {
    if (!this.fortmatic) {
      const { default: Fortmatic } = await import('fortmatic');

      if (this.chainId in CHAIN_ID_NETWORK_ARGUMENT) {
        this.fortmatic = new Fortmatic(this.apiKey);
      } else {
        throw new Error(`Unsupported network ID: ${this.chainId}`);
      }
    }

    const provider = this.fortmatic.getProvider();

    const pollForOverlayReady = new Promise((resolve) => {
      const interval = setInterval(() => {
        if (provider.overlay.overlayReady) {
          clearInterval(interval);
          this.emit(OVERLAY_READY);
          resolve(OVERLAY_READY);
        }
      }, 200);
    });

    const [account] = await Promise.all([
      provider.enable().then((accounts: string[]) => accounts[0]),
      pollForOverlayReady,
    ]);

    return {
      provider: this.fortmatic.getProvider(),
      chainId: (this as any).chainId,
      account,
    };
  }

  public async getProvider(): Promise<any> {
    return this.fortmatic.getProvider();
  }

  public async getChainId(): Promise<number | string> {
    return this.chainId;
  }

  public async getAccount(): Promise<null | string> {
    return this.fortmatic
      .getProvider()
      .send('eth_accounts')
      .then((accounts: string[]): string => accounts[0]);
  }

  public deactivate(): void {
    console.log('deactivate');
  }

  public async close(): Promise<void> {
    await this.fortmatic.user.logout();
    this.emitDeactivate();
  }
}
Example #23
Source File: NetworkConnector.ts    From interface-v2 with GNU General Public License v3.0 5 votes vote down vote up
export class NetworkConnector extends AbstractConnector {
  private readonly providers: { [chainId: number]: MiniRpcProvider };
  private currentChainId: number;

  constructor({ urls, defaultChainId }: NetworkConnectorArguments) {
    invariant(
      defaultChainId || Object.keys(urls).length === 1,
      'defaultChainId is a required argument with >1 url',
    );
    super({
      supportedChainIds: Object.keys(urls).map((k): number => Number(k)),
    });

    this.currentChainId = defaultChainId || Number(Object.keys(urls)[0]);
    this.providers = Object.keys(urls).reduce<{
      [chainId: number]: MiniRpcProvider;
    }>((accumulator, chainId) => {
      accumulator[Number(chainId)] = new MiniRpcProvider(
        Number(chainId),
        urls[Number(chainId)],
      );
      return accumulator;
    }, {});
  }

  public get provider(): MiniRpcProvider {
    return this.providers[this.currentChainId];
  }

  public async activate(): Promise<ConnectorUpdate> {
    return {
      provider: this.providers[this.currentChainId],
      chainId: this.currentChainId,
      account: null,
    };
  }

  public async getProvider(): Promise<MiniRpcProvider> {
    return this.providers[this.currentChainId];
  }

  public async getChainId(): Promise<number> {
    return this.currentChainId;
  }

  public async getAccount(): Promise<null> {
    return null;
  }

  public deactivate(): void {
    return;
  }
}
Example #24
Source File: PendingView.tsx    From goose-frontend-amm with GNU General Public License v3.0 5 votes vote down vote up
export default function PendingView({
  connector,
  error = false,
  setPendingError,
  tryActivation,
}: {
  connector?: AbstractConnector
  error?: boolean
  setPendingError: (error: boolean) => void
  tryActivation: (connector: AbstractConnector) => void
}) {
  const isMetamask = window?.ethereum?.isMetaMask

  return (
    <PendingSection>
      <LoadingMessage error={error}>
        <LoadingWrapper>
          {error ? (
            <ErrorGroup>
              <div>Error connecting.</div>
              <ErrorButton
                onClick={() => {
                  setPendingError(false)
                  if (connector) {
                    tryActivation(connector)
                  }
                }}
              >
                Try Again
              </ErrorButton>
            </ErrorGroup>
          ) : (
            <>
              <StyledLoader />
              Initializing...
            </>
          )}
        </LoadingWrapper>
      </LoadingMessage>
      {Object.keys(SUPPORTED_WALLETS).map((key) => {
        const option = SUPPORTED_WALLETS[key]
        if (option.connector === connector) {
          if (option.connector === injected) {
            if (isMetamask && option.name !== 'MetaMask') {
              return null
            }
            if (!isMetamask && option.name === 'MetaMask') {
              return null
            }
          }
          return (
            <Option
              id={`connect-${key}`}
              key={key}
              clickable={false}
              color={option.color}
              header={option.name}
              subheader={option.description}
              icon={require(`../../assets/images/${option.iconName}`)}
            />
          )
        }
        return null
      })}
    </PendingSection>
  )
}
Example #25
Source File: SafeApp.ts    From interface-v2 with GNU General Public License v3.0 5 votes vote down vote up
export class SafeAppConnector extends AbstractConnector {
  private readonly sdk = new SafeAppsSDK();
  private safe: SafeInfo | undefined;
  private provider: SafeAppProvider | undefined;

  async activate(): Promise<{
    provider: SafeAppProvider;
    chainId: number;
    account: string;
  }> {
    this.safe = await this.sdk.safe.getInfo();
    return {
      provider: await this.getProvider(),
      chainId: await this.getChainId(),
      account: await this.getAccount(),
    };
  }

  public async getSafeInfo(): Promise<SafeInfo> {
    if (!this.safe) {
      this.safe = await this.sdk.safe.getInfo();
    }
    return this.safe;
  }

  public async getProvider(): Promise<SafeAppProvider> {
    if (!this.provider) {
      const safe = await this.getSafeInfo();
      this.provider = new SafeAppProvider(safe, this.sdk);
    }
    return this.provider;
  }

  public async getChainId(): Promise<number> {
    const provider = await this.getProvider();
    return provider.chainId;
  }

  public async getAccount(): Promise<string> {
    const safe = await this.getSafeInfo();
    return safe.safeAddress;
  }

  public deactivate(): void {
    return;
  }
}
Example #26
Source File: PendingView.tsx    From dyp with Do What The F*ck You Want To Public License 5 votes vote down vote up
export default function PendingView({
  connector,
  error = false,
  setPendingError,
  tryActivation
}: {
  connector?: AbstractConnector
  error?: boolean
  setPendingError: (error: boolean) => void
  tryActivation: (connector: AbstractConnector) => void
}) {
  const isMetamask = window?.ethereum?.isMetaMask

  return (
    <PendingSection>
      <LoadingMessage error={error}>
        <LoadingWrapper>
          {error ? (
            <ErrorGroup>
              <div>Error connecting.</div>
              <ErrorButton
                onClick={() => {
                  setPendingError(false)
                  connector && tryActivation(connector)
                }}
              >
                Try Again
              </ErrorButton>
            </ErrorGroup>
          ) : (
            <>
              <StyledLoader />
              Initializing...
            </>
          )}
        </LoadingWrapper>
      </LoadingMessage>
      {Object.keys(SUPPORTED_WALLETS).map(key => {
        const option = SUPPORTED_WALLETS[key]
        if (option.connector === connector) {
          if (option.connector === injected) {
            if (isMetamask && option.name !== 'MetaMask') {
              return null
            }
            if (!isMetamask && option.name === 'MetaMask') {
              return null
            }
          }
          return (
            <Option
              id={`connect-${key}`}
              key={key}
              clickable={false}
              color={option.color}
              header={option.name}
              subheader={option.description}
              icon={require('../../assets/images/' + option.iconName)}
            />
          )
        }
        return null
      })}
    </PendingSection>
  )
}
Example #27
Source File: NetworkConnector.ts    From cheeseswap-interface with GNU General Public License v3.0 5 votes vote down vote up
export class NetworkConnector extends AbstractConnector {
  private readonly providers: { [chainId: number]: MiniRpcProvider }

  private currentChainId: number

  constructor({ urls, defaultChainId }: NetworkConnectorArguments) {
    invariant(defaultChainId || Object.keys(urls).length === 1, 'defaultChainId is a required argument with >1 url')
    super({ supportedChainIds: Object.keys(urls).map((k): number => Number(k)) })

    this.currentChainId = defaultChainId || Number(Object.keys(urls)[0])
    this.providers = Object.keys(urls).reduce<{ [chainId: number]: MiniRpcProvider }>((accumulator, chainId) => {
      accumulator[Number(chainId)] = new MiniRpcProvider(Number(chainId), urls[Number(chainId)])
      return accumulator
    }, {})
  }

  public get provider(): MiniRpcProvider {
    return this.providers[this.currentChainId]
  }

  public async activate(): Promise<ConnectorUpdate> {
    return { provider: this.providers[this.currentChainId], chainId: this.currentChainId, account: null }
  }

  public async getProvider(): Promise<MiniRpcProvider> {
    return this.providers[this.currentChainId]
  }

  public async getChainId(): Promise<number> {
    return this.currentChainId
  }

  public async getAccount(): Promise<null> {
    return null
  }

  public deactivate() {
    return null
  }
}
Example #28
Source File: PendingView.tsx    From cheeseswap-interface with GNU General Public License v3.0 5 votes vote down vote up
export default function PendingView({
  connector,
  error = false,
  setPendingError,
  tryActivation
}: {
  connector?: AbstractConnector
  error?: boolean
  setPendingError: (error: boolean) => void
  tryActivation: (connector: AbstractConnector) => void
}) {
  const isMetamask = window?.ethereum?.isMetaMask

  return (
    <PendingSection>
      <LoadingMessage error={error}>
        <LoadingWrapper>
          {error ? (
            <ErrorGroup>
              <div>Error connecting.</div>
              <ErrorButton
                onClick={() => {
                  setPendingError(false)
                  connector && tryActivation(connector)
                }}
              >
                Try Again
              </ErrorButton>
            </ErrorGroup>
          ) : (
            <>
              <StyledLoader />
              Initializing...
            </>
          )}
        </LoadingWrapper>
      </LoadingMessage>
      {Object.keys(SUPPORTED_WALLETS).map(key => {
        const option = SUPPORTED_WALLETS[key]
        if (option.connector === connector) {
          if (option.connector === injected) {
            if (isMetamask && option.name !== 'MetaMask') {
              return null
            }
            if (!isMetamask && option.name === 'MetaMask') {
              return null
            }
          }
          return (
            <Option
              id={`connect-${key}`}
              key={key}
              clickable={false}
              color={option.color}
              header={option.name}
              subheader={option.description}
              icon={require('../../assets/images/' + option.iconName)}
            />
          )
        }
        return null
      })}
    </PendingSection>
  )
}
Example #29
Source File: index.tsx    From goose-frontend-amm with GNU General Public License v3.0 4 votes vote down vote up
export default function WalletModal({
  pendingTransactions,
  confirmedTransactions,
  ENSName,
}: {
  pendingTransactions: string[] // hashes of pending
  confirmedTransactions: string[] // hashes of confirmed
  ENSName?: string
}) {
  // important that these are destructed from the account-specific web3-react context
  const { active, account, connector, activate, error } = useWeb3React()

  const [walletView, setWalletView] = useState(WALLET_VIEWS.ACCOUNT)

  const [pendingWallet, setPendingWallet] = useState<AbstractConnector | undefined>()

  const [pendingError, setPendingError] = useState<boolean>()

  const walletModalOpen = useWalletModalOpen()
  const toggleWalletModal = useWalletModalToggle()

  const previousAccount = usePrevious(account)

  // close on connection, when logged out before
  useEffect(() => {
    if (account && !previousAccount && walletModalOpen) {
      toggleWalletModal()
    }
  }, [account, previousAccount, toggleWalletModal, walletModalOpen])

  // always reset to account view
  useEffect(() => {
    if (walletModalOpen) {
      setPendingError(false)
      setWalletView(WALLET_VIEWS.ACCOUNT)
    }
  }, [walletModalOpen])

  // close modal when a connection is successful
  const activePrevious = usePrevious(active)
  const connectorPrevious = usePrevious(connector)
  useEffect(() => {
    if (walletModalOpen && ((active && !activePrevious) || (connector && connector !== connectorPrevious && !error))) {
      setWalletView(WALLET_VIEWS.ACCOUNT)
    }
  }, [setWalletView, active, error, connector, walletModalOpen, activePrevious, connectorPrevious])

  // eslint-disable-next-line @typescript-eslint/no-shadow
  const tryActivation = async (connector: AbstractConnector | undefined) => {
    setPendingWallet(connector) // set wallet for pending view
    setWalletView(WALLET_VIEWS.PENDING)

    // if the connector is walletconnect and the user has already tried to connect, manually reset the connector
    if (connector instanceof WalletConnectConnector && connector.walletConnectProvider?.wc?.uri) {
      connector.walletConnectProvider = undefined
    }

    if (connector) {
      activate(connector, undefined, true).catch((err) => {
        if (err instanceof UnsupportedChainIdError) {
          activate(connector) // a little janky...can't use setError because the connector isn't set
        } else {
          setPendingError(true)
        }
      })
    }
  }

  // close wallet modal if fortmatic modal is active
  useEffect(() => {
    fortmatic.on(OVERLAY_READY, () => {
      toggleWalletModal()
    })
  }, [toggleWalletModal])

  // get wallets user can switch too, depending on device/browser
  function getOptions() {
    const isMetamask = window.ethereum && window.ethereum.isMetaMask
    return Object.keys(SUPPORTED_WALLETS).map((key) => {
      const option = SUPPORTED_WALLETS[key]
      // check for mobile options
      if (isMobile) {
        // disable portis on mobile for now
        if (option.connector === portis) {
          return null
        }

        if (!window.web3 && !window.ethereum && option.mobile) {
          return (
            <Option
              onClick={() => {
                if (option.connector !== connector && !option.href) {
                  tryActivation(option.connector)
                }
              }}
              id={`connect-${key}`}
              key={key}
              active={option.connector && option.connector === connector}
              color={option.color}
              link={option.href}
              header={option.name}
              subheader={null}
              icon={require(`../../assets/images/${option.iconName}`)}
            />
          )
        }
        return null
      }

      // overwrite injected when needed
      if (option.connector === injected) {
        // don't show injected if there's no injected provider
        if (!(window.web3 || window.ethereum)) {
          if (option.name === 'MetaMask') {
            return (
              <Option
                id={`connect-${key}`}
                key={key}
                color="#E8831D"
                header="Install Metamask"
                subheader={null}
                link="https://metamask.io/"
                icon={MetamaskIcon}
              />
            )
          }
          return null // dont want to return install twice
        }
        // don't return metamask if injected provider isn't metamask
        if (option.name === 'MetaMask' && !isMetamask) {
          return null
        }
        // likewise for generic
        if (option.name === 'Injected' && isMetamask) {
          return null
        }
      }

      // return rest of options
      return (
        !isMobile &&
        !option.mobileOnly && (
          <Option
            id={`connect-${key}`}
            onClick={() => {
              // eslint-disable-next-line no-unused-expressions
              option.connector === connector
                ? setWalletView(WALLET_VIEWS.ACCOUNT)
                : !option.href && tryActivation(option.connector)
            }}
            key={key}
            active={option.connector === connector}
            color={option.color}
            link={option.href}
            header={option.name}
            subheader={null} // use option.descriptio to bring back multi-line
            icon={require(`../../assets/images/${option.iconName}`)}
          />
        )
      )
    })
  }

  function getModalContent() {
    if (error) {
      return (
        <UpperSection>
          <CloseIcon onClick={toggleWalletModal}>
            <CloseColor />
          </CloseIcon>
          <HeaderRow>{error instanceof UnsupportedChainIdError ? 'Wrong Network' : 'Error connecting'}</HeaderRow>
          <ContentWrapper>
            {error instanceof UnsupportedChainIdError ? (
              <h5>
                Please connect to the appropriate Binance Smart Chain network.
                <a href="https://docs.binance.org/smart-chain/wallet/metamask.html">How?</a>
              </h5>
            ) : (
              'Error connecting. Try refreshing the page.'
            )}
          </ContentWrapper>
        </UpperSection>
      )
    }
    if (account && walletView === WALLET_VIEWS.ACCOUNT) {
      return (
        <AccountDetails
          toggleWalletModal={toggleWalletModal}
          pendingTransactions={pendingTransactions}
          confirmedTransactions={confirmedTransactions}
          ENSName={ENSName}
          openOptions={() => setWalletView(WALLET_VIEWS.OPTIONS)}
        />
      )
    }
    return (
      <UpperSection>
        <CloseIcon onClick={toggleWalletModal}>
          <CloseColor />
        </CloseIcon>
        {walletView !== WALLET_VIEWS.ACCOUNT ? (
          <HeaderRow color="blue">
            <HoverText
              onClick={() => {
                setPendingError(false)
                setWalletView(WALLET_VIEWS.ACCOUNT)
              }}
            >
              Back
            </HoverText>
          </HeaderRow>
        ) : (
          <HeaderRow>
            <HoverText>Connect to a wallet</HoverText>
          </HeaderRow>
        )}
        <ContentWrapper>
          {walletView === WALLET_VIEWS.PENDING ? (
            <PendingView
              connector={pendingWallet}
              error={pendingError}
              setPendingError={setPendingError}
              tryActivation={tryActivation}
            />
          ) : (
            <OptionGrid>{getOptions()}</OptionGrid>
          )}
          {walletView !== WALLET_VIEWS.PENDING && (
            <Blurb>
              <span>New to BSC? &nbsp;</span>{' '}
              <ExternalLink href="https://docs.binance.org/smart-chain/wallet/metamask.html">
                Learn more about wallets
              </ExternalLink>
            </Blurb>
          )}
        </ContentWrapper>
      </UpperSection>
    )
  }

  return (
    <Modal isOpen={walletModalOpen} onDismiss={toggleWalletModal} minHeight={false} maxHeight={90}>
      <Wrapper>{getModalContent()}</Wrapper>
    </Modal>
  )
}