@gamcaplabs/uniswapeasy
Version:
Uniswap V4 Liquidity Provider
279 lines (220 loc) • 8.92 kB
Markdown
# UniswapEasy
UniswapEasy is a React widget designed to simplify liquidity management on the Uniswap V4 protocol. This version has been updated to include more customization options and supports the Ethereum Sepolia chain for testing purposes.
# Table of Contents
- [UniswapEasy](#uniswapeasy)
- [Installation](#installation)
- [Building from Source](#building-from-source)
- [Usage](#usage)
- [Theme Customization](#theme-customization)
- [PoolInfo and PoolKey](#poolinfo-and-poolkey)
- [PoolInfo Definition](#poolinfo-definition)
- [HookInfo and InputField](#hookinfo-and-inputfield)
- [HookInfo Definition](#hookinfo-definition)
- [CurrencyIconMap](#currencyiconmap)
- [CurrencyIconMap Definition](#currencyiconmap-definition)
- [Handling Complex Cases with Custom Inputs](#handling-complex-cases-with-custom-inputs)
- [Using overrideInputFields and hookData](#using-overrideinputfields-and-hookdata)
- [Integrating Custom Interfaces](#integrating-custom-interfaces)
- [Contracts and Supported Chains](#contracts-and-supported-chains)
- [Additional Resources](#additional-resources)
- [License](#license)
## Installation
```bash
npm install @gamcaplabs/uniswapeasy
# or
yarn add @gamcaplabs/uniswapeasy
```
## Building from Source
Before building, ensure you have all peer dependencies installed:
- react
- react-dom
- react-redux
- redux
- redux-persist
- styled-components
- ethers
To build the package from source:
1. Clone the repository:
```bash
git clone https://github.com/GamCap/uniswapeasy.git
```
2. Navigate to the project directory:
```bash
cd uniswapeasy
```
3. Install dependencies:
```bash
yarn install
```
4. Run the prebuild script which includes ABI type generation:
```bash
yarn prebuild
```
5. Build the package:
```bash
yarn build
```
6. Generate a gzip archive of the package for local development:
```bash
yarn pack
```
## Usage
Import `UniswapEasy` from the package and use it in your React application with the following props for extensive customization:
```jsx
import {UniswapEasy, defaultTheme} from '@gamcaplabs/uniswapeasy';
<UniswapEasy
theme={defaultTheme}
defaultChainId={1}
provider={provider}
poolInfos={poolKeys}
hookInfos={hookInfos}
onPoolSelect={onPoolSelect}
currencyIconMap={currencyIconMap}
hookData={hookData}
/>
```
### Theme Customization
Customize the theme using the following interface, which allows for detailed adjustments to colors, fonts, and layout specifics:
```typescript
import {type Theme, type Colors, defaultTheme, orangeDark } // other preset themes are orangeLight, tealDark,and tealLight.
// Example custom colors:
const myColors : Colors = {
...orangeDark,
text: {
...orangeDark.text,
primary: "#d9d9d9"
}
}
const myTheme : Theme = {
...defaultTheme,
...myColors
// You can also add other custom attributes like font family
}
```
### PoolInfo and PoolKey
The `PoolInfo` object is essential for configuring liquidity pools. Each `PoolInfo` specifies the blockchain network with `chainId` and contains a `poolKey` detailing specific pool parameters.
#### PoolInfo Definition
```typescript
type PoolKey = {
currency0: Currency; // First currency in the liquidity pool
currency1: Currency; // Second currency in the liquidity pool
fee: BigNumberish; // Fee associated with the pool
tickSpacing: BigNumberish; // The minimum price movement between ticks
hooks: string; // Address of any additional hooks used with the pool
};
export type PoolInfo = {
chainId: number; // Blockchain network ID
poolKey: PoolKey; // Specific pool parameters
};
// Example of PoolInfo
const poolInfos: PoolInfo[] = [{
chainId: 1, // Ethereum mainnet
poolKey: {
currency0: new Token(1, '0x...', 18, 'ETH'),
currency1: new Token(1, '0x...', 6, 'USDC'),
fee: 3000,
tickSpacing: 60,
hooks: '0x0000000000000000000000000000000000000000'
}
}];
```
### HookInfo and InputField
`HookInfo` defines hooks available within the liquidity pool, providing metadata and the required inputs.
#### HookInfo Definition
```typescript
export type HookInfo = {
address: string; // Smart contract address of the hook
name: string; // Display name of the hook
abbr: string; // Abbreviation of the hook name
desc: string; // Description of the hook's functionality
inputFields: InputField[]; // Array of input fields for the hook
overrideInputFields?: boolean; // Flag to override default input fields
};
interface InputRestrictions {
min?: string; // Minimum value for the input
max?: string; // Maximum value for the input
pattern?: string; // Regular expression for validating the input
required?: boolean; // Whether the input is required
};
interface BaseProps {
name: string;
description?: string;
}
interface BaseInputField extends BaseProps {
type: string; // Data type of the input field
defaultValue?: string; // Default value for the input field
restrictions?: InputRestrictions; // Restrictions for the input field
};
interface Tuple extends BaseProps {
fields: InputField[]; // Fields in case the input is a tuple
};
type InputField = BaseInputField | Tuple;
// Example of HookInfo
const hookInfos: HookInfo[] = [{
address: '0x...',
name: 'Example Hook',
abbr: 'ExHook',
desc: 'This hook does XYZ',
inputFields: [{
name: 'Sender',
type: 'address',
restrictions: { required: true }
}, {
name: 'Value',
type: 'uint256',
restrictions: { min: '1', max: '1000', required: true }
}]
}];
```
### CurrencyIconMap
Maps currency symbols to image URLs or base64 encoded images for enhancing user interface.
#### CurrencyIconMap Definition
```typescript
const currencyIconMap: Record<string, string> = {
'ETH': 'data:image/png;base64,...', // Base64 encoded image of Ethereum
'USDC': 'https://example.com/usdc.png' // URL to an image of USDC
};
```
### Handling Complex Cases with Custom Inputs
For scenarios where the widget's dynamic input field generation does not meet specific requirements, or if you need to handle complex data types that the widget cannot automatically encode, you can utilize the `overrideInputFields` and `hookData` properties.
#### Using `overrideInputFields` and `hookData`
When a hook requires complex data handling, set `overrideInputFields` to `true` to disable the widget's automatic input field generation. This allows you to implement a custom interface to collect and encode data according to the hook's needs.
```typescript
// Example showing how to set overrideInputFields
const hookInfos: HookInfo[] = [{
address: '0x...',
name: 'Complex Data Hook',
abbr: 'CDH',
desc: 'A hook requiring complex data input',
inputFields: [], // Normally filled, now empty due to override
overrideInputFields: true
}];
```
#### Integrating Custom Interfaces
Use the `onPoolSelect` callback to detect when a user selects a pool. This callback provides the selected `poolKey`, enabling you to display the appropriate custom interface for data input.
```typescript
// Example of using onPoolSelect to handle complex cases
<UniswapEasy
theme={defaultTheme}
defaultChainId={1}
provider={provider}
poolInfos={poolInfos}
hookInfos={hookInfos}
onPoolSelect={(poolKey) => {
console.log('Selected pool:', poolKey);
// Logic to display custom interface for hook data input goes here}
}
currencyIconMap={currencyIconMap}
hookData={hookData} // Encoded data provided by the user's custom interface
/>
```
## Contracts and Supported Chains
Currently, the UniswapEasy widget is only supported on the Ethereum Sepolia test network. The addresses for pool management and liquidity modification contracts are:
- **PoolManager Contract**: `0xf7a031A182aFB3061881156df520FE7912A51617`
- **PoolModifyLiquidity Contract**: `0x140C64C63c52cE05138E21564b72b0B2Dff9B67f`
## Additional Resources
Below are links to the smart contracts on the Ethereum Sepolia testnet and other resources used by this widget:
- [Etherscan link for Pool Manager](https://sepolia.etherscan.io/address/0xf7a031A182aFB3061881156df520FE7912A51617)
- [Etherscan link for Pool Modify Liquidity](https://sepolia.etherscan.io/address/0x140C64C63c52cE05138E21564b72b0B2Dff9B67f)
## License
This project is licensed under the MIT License - see the `LICENSE` file for details.