npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

uniswap-angular

v1.0.3

Published

Integrating uniswap within your angular dApp with a couple of lines of code.

Downloads

4

Readme

Uniswap angular

npm version downloads

About

Integrating uniswap within your dApp should be a simple thing but with all the complex stuff that goes into making it work, managing transaction status, calling the correct methods on the swap, maintaining the users balances, syncing the fiat prices, producing the token icons, handling all the UI making it work on every browser, i could keep going. On top of this you don't really want to pop a window for the user to swap using the uniswap widget, you want to keep the user experience consistent with your dApp. The idea of this library is to give you a really easy but fully flexible way you can integrate with uniswap with only a few lines of code. You can customise mostly everything from what tokens you support to what colour you want it to be themed as! This will turn integrating uniswap into a few lines of code task.

Features 🚀

🚀 Integrate it into your existing dApp with a few lines of code 🚀 Supports uniswap v2 and v3 prices together and returns the best price 🚀 Queries all the best routes and finds the best price for you 🚀 Reactive logic so when the price moves or your trade expiries it generates you a new one but alerts the user (queries new trades on every new block) 🚀 Reactive fiat price so users can see the amount the trade is in fiat, this updates as the price changes as well 🚀 Reactive balance syncing so the user can see their correct balance all the time (syncs on every new block) 🚀 Supports all major browsers 🚀 Is fully responsive 🚀 Fully customisable, style it as you want, support whatever tokens you want and much more 🚀 Uses the awesome simple-uniswap-sdk for all the uniswap on chain logic 🚀 Fully typescript supported with full generated typings 🚀 and much more!!

Live demo

You can view a live demo here. You will need MetaMask installed. It only uses a few tokens just to show the demo working.

Installing

npm

$ npm install uniswap-angular

yarn

$ yarn add uniswap-angular

Peer dependencies you must install

You must also install uniswap-dapp-integration-shared package for this to work.

npm

$ npm install uniswap-dapp-integration-shared

yarn

$ yarn add uniswap-dapp-integration-shared

Warnings on builds on angular 10 +

Starting with version 10, Angular now warns you when your build pulls in a CommonJS package. uniswap-dapp-integration-shared uses @ethersprojectinternally which uses bn.js and sha2.js which are CommonJS packages. Also the uniswap-angular uses bignumber.js which again is a CommonJS package. You can safely ignore the warnings in your angular.json. instructions on how angular.json allows you to do this is here.

Usage

It very simple to get uniswap angular up and running below is a simple example in how to get it working, this example assumes the ethereum provider is injected in the window (MetaMask) but can be configured any way you like. This example does not show the logging out handling or a user without MetaMask installed, its purely to showing you how you would get this lib up and running. We shall talk about the config later in the documentation.

your.module.ts

You need to import the UniswapModule into your module file, example is just using a standard module example all you need to do is insert UniswapModule into your imports array.

import { UniswapModule } from 'uniswap-angular';
import { AppComponent } from './app.component';
import { YourComponent } from './your.component';

@NgModule({
  declarations: [YourComponent],
  imports: [UniswapModule],
  providers: [],
  bootstrap: [AppComponent],
})
export class YourModule {}

your.component.ts

import { Component, OnInit } from '@angular/core';
import {
  UniswapDappSharedLogicContext,
  ChainId,
  ETH,
} from 'uniswap-dapp-integration-shared';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class YourComponent implements OnInit {
  public uniswapDappSharedLogicContext:
    | UniswapDappSharedLogicContext
    | undefined;

  /**
   * On load
   */
  async ngOnInit(): Promise<void> {
    const accounts = await (window as any).ethereum.request({
      method: 'eth_requestAccounts',
    });

    this.uniswapDappSharedLogicContext = {
      supportedNetworkTokens: [
        {
          chainId: ChainId.MAINNET,
          defaultInputToken: ETH.MAINNET().contractAddress,
          defaultOutputToken: '0xDe30da39c46104798bB5aA3fe8B9e0e1F348163F',
          supportedTokens: [
            { contractAddress: ETH.MAINNET().contractAddress },
            { contractAddress: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984' },
            { contractAddress: '0xdac17f958d2ee523a2206206994597c13d831ec7' },
            { contractAddress: '0x1985365e9f78359a9B6AD760e32412f4a445E862' },
            { contractAddress: '0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9' },
            { contractAddress: '0xDe30da39c46104798bB5aA3fe8B9e0e1F348163F' },
          ],
        },
        {
          chainId: ChainId.RINKEBY,
          defaultInputToken: ETH.RINKEBY().contractAddress,
          defaultOutputToken: '0xef0e839cf88e47be676e72d5a9cb6ced99fad1cf',
          supportedTokens: [
            { contractAddress: ETH.RINKEBY().contractAddress },
            { contractAddress: '0xef0e839cf88e47be676e72d5a9cb6ced99fad1cf' },
          ],
        },
      ],
      ethereumAddress: accounts[0],
      ethereumProvider: (window as any).ethereum,
      theming: {
        backgroundColor: 'red',
        button: { textColor: 'white', backgroundColor: 'blue' },
        panel: { textColor: 'black', backgroundColor: 'yellow' },
        textColor: 'orange',
      },
    };
  }
}

your.component.html

<lib-uniswap-angular-swapper
  *ngIf="uniswapDappSharedLogicContext"
  [uniswapDappSharedLogicContext]="uniswapDappSharedLogicContext"
></lib-uniswap-angular-swapper>

Account changes and chain changes

If your ethereum provider follows https://eips.ethereum.org/EIPS/eip-1193 spec then this should just work. As long as your provider emits accountsChanged on a account change and chainChanged on a chain change then this will all happen automatically for you. If for some reason you can not support this then we have exposed 2 inputs for you to emit values to when they change.

accountChanged

@Input() accountChanged: Observable<string> | undefined;

When the account changes just emit the new account value to this input, example below:

your.component.ts

import { Component, OnInit } from '@angular/core';
import {
  UniswapDappSharedLogicContext,
  ChainId,
} from 'uniswap-dapp-integration-shared';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class YourComponent implements OnInit {
  public uniswapDappSharedLogicContext:
    | UniswapDappSharedLogicContext
    | undefined;

  public accountChangedSubject: Subject<string> = new Subject<string>();

  /**
   * On load
   */
  async ngOnInit(): Promise<void> {
    const accounts = await (window as any).ethereum.request({
      method: 'eth_requestAccounts',
    });

    this.uniswapDappSharedLogicContext = {
      supportedNetworkTokens: [
        {
          chainId: ChainId.MAINNET,
          defaultInputToken: ETH.MAINNET().contractAddress,
          defaultOutputToken: '0xDe30da39c46104798bB5aA3fe8B9e0e1F348163F',
          supportedTokens: [
            { contractAddress: ETH.MAINNET().contractAddress },
            { contractAddress: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984' },
            { contractAddress: '0xdac17f958d2ee523a2206206994597c13d831ec7' },
            { contractAddress: '0x1985365e9f78359a9B6AD760e32412f4a445E862' },
            { contractAddress: '0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9' },
            { contractAddress: '0xDe30da39c46104798bB5aA3fe8B9e0e1F348163F' },
          ],
        },
        {
          chainId: ChainId.RINKEBY,
          defaultInputToken: ETH.RINKEBY().contractAddress,
          defaultOutputToken: '0xef0e839cf88e47be676e72d5a9cb6ced99fad1cf',
          supportedTokens: [
            { contractAddress: ETH.RINKEBY().contractAddress },
            {
              contractAddress: '0xef0e839cf88e47be676e72d5a9cb6ced99fad1cf',
            },
          ],
        },
      ],
      ethereumAddress: accounts[0],
      ethereumProvider: (window as any).ethereum,
      theming: {
        backgroundColor: 'red',
        button: { textColor: 'white', backgroundColor: 'blue' },
        panel: { textColor: 'black', backgroundColor: 'yellow' },
        textColor: 'orange',
      },
    };
  }

  public accountChanged(account: string): void {
    this.accountChangedSubject.next(account);
  }
}

your.component.html

<lib-uniswap-angular-swapper
  *ngIf="uniswapDappSharedLogicContext"
  [uniswapDappSharedLogicContext]="uniswapDappSharedLogicContext"
  [accountChanged]="accountChangedSubject.asObservable()"
></lib-uniswap-angular-swapper>

chainChanged

@Input() chainChanged: Observable<any> | undefined;

When the chain changes just emit the new ethereum provider, if there is no need for your ethereum provider to change or the instance you passed to the lib is the property that has changed then you do not need to pass us the new ethereum provider. example below:

your.component.ts

import { Component, OnInit } from '@angular/core';
import {
  UniswapDappSharedLogicContext,
  ChainId,
} from 'uniswap-dapp-integration-shared';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class YourComponent implements OnInit {
  public uniswapDappSharedLogicContext:
    | UniswapDappSharedLogicContext
    | undefined;

  public chainChangedSubject: Subject<any> = new Subject<any>();

  /**
   * On load
   */
  async ngOnInit(): Promise<void> {
    const accounts = await (window as any).ethereum.request({
      method: 'eth_requestAccounts',
    });

    this.uniswapDappSharedLogicContext = {
      supportedNetworkTokens: [
        {
          chainId: ChainId.MAINNET,
          defaultInputToken: ETH.MAINNET().contractAddress,
          defaultOutputToken: '0xDe30da39c46104798bB5aA3fe8B9e0e1F348163F',
          supportedTokens: [
            { contractAddress: ETH.MAINNET().contractAddress },
            { contractAddress: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984' },
            { contractAddress: '0xdac17f958d2ee523a2206206994597c13d831ec7' },
            { contractAddress: '0x1985365e9f78359a9B6AD760e32412f4a445E862' },
            { contractAddress: '0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9' },
            { contractAddress: '0xDe30da39c46104798bB5aA3fe8B9e0e1F348163F' },
          ],
        },
        {
          chainId: ChainId.RINKEBY,
          defaultInputToken: ETH.RINKEBY().contractAddress,
          defaultOutputToken: '0xef0e839cf88e47be676e72d5a9cb6ced99fad1cf',
          supportedTokens: [
            { contractAddress: ETH.RINKEBY().contractAddress },
            {
              contractAddress: '0xef0e839cf88e47be676e72d5a9cb6ced99fad1cf',
            },
          ],
        },
      ],
      ethereumAddress: accounts[0],
      ethereumProvider: (window as any).ethereum,
    };
  }

  public chainChanged(newEthereumProvider: any): void {
    this.chainChangedSubject.next(newEthereumProvider);
  }
}

your.component.html

<lib-uniswap-angular-swapper
  *ngIf="uniswapDappSharedLogicContext"
  [uniswapDappSharedLogicContext]="uniswapDappSharedLogicContext"
  [chainChanged]="chainChangedSubject.asObservable()"
></lib-uniswap-angular-swapper>

Thats it it now will be integrated in your dApp, now lets talk about the config you can pass it.

Config

UniswapDappSharedLogicContext

export interface UniswapDappSharedLogicContext {
  supportedNetworkTokens: {
    chainId: ChainId;
    defaultInputValue?: string | undefined;
    defaultInputToken?: string | undefined;
    defaultOutputToken?: string | undefined;
    supportedTokens: {
      tokenImageContext?: {
        image: string;
        isSvg?: boolean | undefined;
      };
      contractAddress: string;
    }[];
  }[];
  ethereumAddress: string;
  ethereumProvider: any;
  settings?: UniswapPairSettings | undefined;
  theming?: {
    backgroundColor?: string | undefined;
    textColor?: string | undefined;
    button?: {
      textColor?: string | undefined;
      backgroundColor?: string | undefined;
    };
    panel?: {
      textColor?: string | undefined;
      backgroundColor?: string | undefined;
    };
  };
}

export declare class UniswapPairSettings {
  slippage: number;
  deadlineMinutes: number;
  disableMultihops: boolean;
  uniswapVersions: UniswapVersion[];
  constructor(settings?: {
    slippage?: number | undefined;
    deadlineMinutes?: number | undefined;
    disableMultihops?: boolean | undefined;
    uniswapVersions?: UniswapVersion[] | undefined;
  });
}

export declare enum UniswapVersion {
  v2 = 'v2',
  v3 = 'v3',
}

supportedNetworkTokens - required

The is the config which maps your chains you want to support with the tokens you want to be swappable lets break down the config.

supportedNetworkTokens: {
    // the chain this mapping is for so if this was MAINNET you would import the `ChainId`
    // enum from `uniswap-dapp-integration-shared` and do `ChainId.MAINNET`
    chainId: ChainId;
    // the deep linked input amount
    // if not passed input will have nothing deep linked in
    // it should always be the formatted string aka 0.0001 ETH
    // you pass ether value ('0.0001'). Same with tokens you pass in
    // the formatted value
    defaultInputValue?: string | undefined;
    // the default input token you want to show
    // if nothing is passed in it will use WETH
    defaultInputToken?: string | undefined;
    // the default output token you want to show
    // if nothing passed it then it will pick nothing
    // as default
    defaultOutputToken?: string | undefined;
    // an array of all the tokens you want to support
    // should include any that you supplied above
    supportedTokens: {
        // if not supplied it try to get the image from trust
        // wallet github assets `https://github.com/trustwallet/assets`
        // image accepts a svg string or url for the image, if you pass in a
        // svg html string make sure you set `isSvg` to true. If you pass in a image url even
        // if that is a `.svg` pass in `isSvg` as false
        tokenImageContext?: {
          image: string;
          isSvg?: boolean | undefined;
        },
        // the contract address for the token
        contractAddress: string;
    }[];
  }[];

ethereumAddress - requied

The ethereum address for the user.

ethereumProvider - required

This is the ethereum provider you are using to send these transaction. It must confirm to the https://eips.ethereum.org/EIPS/eip-1193. If your using MetaMask for example you can just pass in the ethereum provider from the window aka window.ethereum. If your using a integrated wallet you should pass in your own custom provider which hooks onto the JSONRPC calls and on eth_sendTransaction it does what your dApp expects.

settings

This is the settings you want to use on uniswap. UniswapPairSettings is a class.

export declare class UniswapPairSettings {
  // if not supplied it will use `0.005` which is 0.5%
  // please pass it in as a full number decimal so 0.7%
  // would be 0.007
  slippage: number;
  // if not supplied it will use 20 a deadline minutes
  deadlineMinutes: number;
  // if not supplied it will try to use multihops
  // if this is true it will require swaps to direct
  // pairs
  disableMultihops: boolean;
  // for example if you only wanted to turn on quotes for v3 and not v3
  // you can only support the v3 enum same works if you only want v2 quotes
  // if you do not supply anything it query both v2 and v3
  uniswapVersions: UniswapVersion[];
  constructor(settings?: {
    slippage?: number | undefined;
    deadlineMinutes?: number | undefined;
    disableMultihops?: boolean | undefined;
    uniswapVersions?: UniswapVersion[] | undefined;
  });
}

theming

This allows you to theme the component which matches your dApp.

  theming?: {
    // The main background colour this will
    // apply to the main component and the modals
    backgroundColor?: string | undefined;
    // The text colour for the main body
    textColor?: string | undefined;
    // The button theme
    button?: {
      // The text colour for the buttons
      textColor?: string | undefined;
      // the background colour for the buttons
      backgroundColor?: string | undefined;
    };
    // The main area panels
    panel?: {
      // The text colour for the panels
      textColor?: string | undefined;
      // The background colour for the panels
      backgroundColor?: string | undefined;
    };
  };