Skip to content

Commit 0a5dcd2

Browse files
authored
Merge pull request #7 from BootNodeDev/chore/improve-lib-usage
chore: update lib architecture to use the instance in all cases.
2 parents df36f55 + 1df7ef4 commit 0a5dcd2

37 files changed

+495
-1790
lines changed

README.md

Lines changed: 85 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,14 @@
77
> Modern TypeScript SDK for integrating Uniswap V4 into your dapp.
88
> **Early version:** API may change rapidly.
99
10-
---
10+
## Features
11+
12+
- 🚀 Full TypeScript support
13+
- 🔄 Multi-chain support out of the box
14+
- 📦 Zero dependencies (except peer deps)
15+
- 🔍 Comprehensive error handling
16+
- 🧪 Fully tested
17+
- 📚 Well documented
1118

1219
## Install
1320

@@ -22,10 +29,10 @@ npm install uniswap-dev-kit
2229
### 1. Configure and create SDK instances
2330

2431
```ts
25-
import { createInstance } from "uniswap-dev-kit";
32+
import { UniDevKitV4 } from "uniswap-dev-kit";
2633

2734
// Create instance for Ethereum mainnet
28-
createInstance({
35+
const ethInstance = new UniDevKitV4({
2936
chainId: 1,
3037
rpcUrl: "https://eth.llamarpc.com",
3138
contracts: {
@@ -40,7 +47,7 @@ createInstance({
4047
});
4148

4249
// Create instance for another chain (e.g., Base)
43-
createInstance({
50+
const baseInstance = new UniDevKitV4({
4451
chainId: 8453,
4552
rpcUrl: "https://mainnet.base.org",
4653
contracts: {
@@ -49,96 +56,104 @@ createInstance({
4956
});
5057
```
5158

52-
The SDK automatically manages multiple instances based on chainId. When using hooks or utilities, just specify the chainId to use the corresponding instance:
59+
### 2. Get a quote
5360

5461
```ts
55-
// Will use Ethereum mainnet instance
56-
const ethPool = await getPool({ tokens: [...] }, 1);
57-
58-
// Will use Base instance
59-
const basePool = await getPool({ tokens: [...] }, 8453);
62+
import { parseEther } from "viem";
6063

61-
// If you only have one instance, chainId is optional
62-
const singleChainPool = await getPool({ tokens: [...] });
64+
const quote = await ethInstance.getQuote({
65+
tokens: [
66+
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
67+
"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", // WETH
68+
],
69+
feeTier: 3000,
70+
amountIn: parseEther("1"),
71+
zeroForOne: true
72+
});
73+
console.log(quote.amountOut);
6374
```
6475

65-
### 2. Get a quote (vanilla JS/TS)
76+
### 3. Get a pool
6677

6778
```ts
68-
import { getQuote } from "uniswap-dev-kit";
69-
import { parseEther } from "viem";
79+
const pool = await ethInstance.getPool({
80+
tokens: [
81+
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
82+
"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
83+
],
84+
feeTier: 3000
85+
});
86+
console.log(pool.liquidity.toString());
87+
```
7088

71-
const quote = await getQuote(
72-
{
73-
tokens: [
74-
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
75-
"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", // WETH
76-
],
77-
feeTier: 3000,
78-
tickSpacing: 60,
79-
amountIn: parseEther("1"),
80-
},
81-
1,
82-
{
83-
enabled: true,
84-
staleTime: 30000,
85-
gcTime: 300000,
86-
retry: 3,
87-
onSuccess: (data) => console.log("Quote received:", data),
88-
},
89-
);
90-
console.log(quote.amountOut);
89+
### 4. Get a position
90+
91+
```ts
92+
const position = await ethInstance.getPosition({
93+
tokenId: "123"
94+
});
95+
console.log({
96+
token0: position.token0.symbol,
97+
token1: position.token1.symbol,
98+
liquidity: position.position.liquidity.toString()
99+
});
91100
```
92101

93-
### 3. Use in React (with hooks)
102+
## Advanced Usage
94103

95-
#### Get a quote
104+
### Error Handling
96105

97-
```tsx
98-
import { useGetQuote } from "uniswap-dev-kit";
99-
import { parseEther } from "viem";
106+
All SDK functions include comprehensive error handling:
100107

101-
function QuoteComponent() {
102-
const { data, isLoading, error } = useGetQuote({
103-
params: {
104-
tokens: [
105-
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
106-
"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
107-
],
108-
feeTier: 3000,
109-
tickSpacing: 60,
110-
amountIn: parseEther("1"),
111-
zeroForOne: true
112-
},
113-
chainId: 1
108+
```ts
109+
try {
110+
const quote = await ethInstance.getQuote({
111+
tokens: [token0, token1],
112+
feeTier: 3000,
113+
amountIn: parseEther("1"),
114+
zeroForOne: true
114115
});
115-
116-
if (isLoading) return <span>Loading...</span>;
117-
if (error) return <span>Error: {error.message}</span>;
118-
return <span>Quote: {data?.amountOut?.toString()}</span>;
116+
} catch (error) {
117+
// Handle specific error types
118+
if (error.message.includes("insufficient liquidity")) {
119+
// Handle liquidity error
120+
} else if (error.message.includes("invalid pool")) {
121+
// Handle pool error
122+
}
119123
}
120124
```
121125

122-
#### Get a pool
126+
### Using with React
127+
128+
You can use the SDK with React Query for data fetching:
123129

124130
```tsx
125-
import { useGetPool } from "uniswap-dev-kit";
131+
import { useQuery } from '@tanstack/react-query';
132+
import { UniDevKitV4 } from 'uniswap-dev-kit';
126133

127-
function PoolComponent() {
128-
const { data, isLoading, error } = useGetPool({
129-
params: {
134+
// Create instance once
135+
const sdk = new UniDevKitV4({
136+
chainId: 1,
137+
rpcUrl: "https://eth.llamarpc.com",
138+
contracts: {
139+
// ... contract addresses
140+
}
141+
});
142+
143+
// Simple hook for quotes
144+
function useQuote() {
145+
return useQuery({
146+
queryKey: ['quote'],
147+
queryFn: () => sdk.getQuote({
130148
tokens: [
131149
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
132150
"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
133151
],
134-
fee: 3000,
135-
},
136-
chainId: 1
152+
feeTier: 3000,
153+
amountIn: parseEther("1"),
154+
zeroForOne: true
155+
})
137156
});
138-
139-
if (isLoading) return <span>Loading...</span>;
140-
if (error) return <span>Error: {error.message}</span>;
141-
return <span>Pool: {JSON.stringify(data)}</span>;
142157
}
143158
```
144159

@@ -173,10 +188,8 @@ See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
173188

174189
## FAQ
175190

176-
- **Which React versions are supported?**
177-
React 18+ (see peerDependencies)
178191
- **Does it work in Node and browser?**
179-
Yes, but hooks are React-only.
192+
Yes, works in both environments.
180193
- **Can I use my own ABIs?**
181194
Yes, but Uniswap V4 ABIs are included.
182195

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "uniswap-dev-kit",
3-
"version": "1.0.4",
3+
"version": "1.0.7",
44
"description": "A modern TypeScript library for integrating Uniswap into your dapp.",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",

src/core/uniDevKitV4.ts

Lines changed: 65 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
import { getChainById } from "@/constants/chains";
22
import type { UniDevKitV4Config, UniDevKitV4Instance } from "@/types/core";
3+
import type { PoolParams } from "@/types/utils/getPool";
4+
import type { GetPoolKeyFromPoolIdParams } from "@/types/utils/getPoolKeyFromPoolId";
5+
import type {
6+
GetPositionParams,
7+
GetPositionResponse,
8+
} from "@/types/utils/getPosition";
9+
import type { QuoteParams, QuoteResponse } from "@/types/utils/getQuote";
10+
import type { GetTokensParams } from "@/types/utils/getTokens";
11+
import { getPool } from "@/utils/getPool";
12+
import { getPoolKeyFromPoolId } from "@/utils/getPoolKeyFromPoolId";
13+
import { getPosition } from "@/utils/getPosition";
14+
import { getQuote } from "@/utils/getQuote";
15+
import { getTokens } from "@/utils/getTokens";
16+
import type { Token } from "@uniswap/sdk-core";
17+
import type { Pool, PoolKey } from "@uniswap/v4-sdk";
318
import {
419
http,
520
type Address,
@@ -21,40 +36,19 @@ export class UniDevKitV4 {
2136
* @throws Will throw an error if the configuration is invalid.
2237
*/
2338
constructor(config: UniDevKitV4Config) {
24-
this.instance = this.createInstance(config);
25-
}
39+
const chain = getChainById(config.chainId);
40+
const client = createPublicClient({
41+
chain,
42+
transport: http(config.rpcUrl || chain.rpcUrls.default.http[0]),
43+
});
2644

27-
/**
28-
* Creates a new internal instance for the SDK.
29-
* This method is used internally to reset the instance when the configuration changes.
30-
* @param config - The complete configuration for the SDK.
31-
* @returns A new instance of UniDevKitV4.
32-
*/
33-
private createInstance(config: UniDevKitV4Config): UniDevKitV4Instance {
34-
const client = this.createClient(config);
35-
return {
45+
this.instance = {
3646
client: client as PublicClient,
37-
chainId: config.chainId,
47+
chain,
3848
contracts: config.contracts,
3949
};
4050
}
4151

42-
/**
43-
* Creates a new PublicClient for the specified chain ID and RPC URL.
44-
* @param config - The complete configuration for the SDK.
45-
* @returns A new PublicClient instance.
46-
*/
47-
private createClient(config: UniDevKitV4Config) {
48-
const { chainId, rpcUrl } = config;
49-
50-
const chain = getChainById(chainId);
51-
52-
return createPublicClient({
53-
chain,
54-
transport: http(rpcUrl || chain.rpcUrls.default.http[0]),
55-
});
56-
}
57-
5852
/**
5953
* Returns the current PublicClient instance.
6054
* @returns The current PublicClient.
@@ -68,7 +62,7 @@ export class UniDevKitV4 {
6862
* @returns The chain ID currently configured.
6963
*/
7064
getChainId(): number {
71-
return this.instance.chainId;
65+
return this.instance.chain.id;
7266
}
7367

7468
/**
@@ -94,12 +88,48 @@ export class UniDevKitV4 {
9488
}
9589

9690
/**
97-
* Updates the SDK configuration with a complete new set of parameters.
98-
* This method will reset the client and instance to reflect the new configuration.
99-
* @param config - The complete configuration for the SDK.
100-
* @throws Will throw an error if the configuration is invalid.
91+
* Retrieves a Uniswap V4 pool instance for a given token pair.
92+
* @param params Pool parameters including tokens, fee tier, tick spacing, and hooks configuration
93+
* @returns Promise resolving to pool data
94+
* @throws Error if pool data cannot be fetched
10195
*/
102-
updateConfig(config: UniDevKitV4Config): void {
103-
this.instance = this.createInstance(config);
96+
async getPool(params: PoolParams): Promise<Pool> {
97+
return getPool(params, this.instance);
98+
}
99+
100+
/**
101+
* Retrieves token information for a given array of token addresses.
102+
* @param params Parameters including token addresses
103+
* @returns Promise resolving to Token instances for each token address.
104+
* @throws Error if token data cannot be fetched
105+
*/
106+
async getTokens(params: GetTokensParams): Promise<Token[]> {
107+
return getTokens(params, this.instance);
108+
}
109+
110+
/**
111+
* Retrieves a Uniswap V4 position information for a given token ID.
112+
* @param params Position parameters including token ID
113+
* @returns Promise resolving to position data including pool, token0, token1, poolId, and tokenId
114+
* @throws Error if SDK instance is not found or if position data is invalid
115+
*/
116+
async getPosition(params: GetPositionParams): Promise<GetPositionResponse> {
117+
return getPosition(params, this.instance);
118+
}
119+
120+
/**
121+
* Retrieves a Uniswap V4 quote for a given token pair and amount in.
122+
* @param params Quote parameters including token pair and amount in
123+
* @returns Promise resolving to quote data including amount out, estimated gas used, and timestamp
124+
* @throws Error if SDK instance is not found or if quote data is invalid
125+
*/
126+
async getQuote(params: QuoteParams): Promise<QuoteResponse> {
127+
return getQuote(params, this.instance);
128+
}
129+
130+
async getPoolKeyFromPoolId(
131+
params: GetPoolKeyFromPoolIdParams,
132+
): Promise<PoolKey> {
133+
return getPoolKeyFromPoolId(params, this.instance);
104134
}
105135
}

0 commit comments

Comments
 (0)