This repository has been archived by the owner on Jul 22, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Swap.ts
155 lines (137 loc) · 10.3 KB
/
Swap.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import { DexRouter, DexRouter__factory, DexFactory, DexFactory__factory, KIP7, KIP7__factory, DexPair, DexPair__factory } from '../contracts';
import { Wallet, providers, BigNumber, ContractTransaction } from 'ethers'
export class Swap {
public router: DexRouter;
public factory: DexFactory;
constructor(routerAddress: string, factoryAddress: string, privKey: string, rpcURL: string) {
this.factory = DexFactory__factory.connect(factoryAddress, new Wallet(privKey, new providers.JsonRpcProvider(rpcURL)));
this.router = DexRouter__factory.connect(routerAddress, new Wallet(privKey, new providers.JsonRpcProvider(rpcURL)));
}
/**
* A function to swap exact amount of Tokens for a given amount of Tokens.
* @param {string[]} path - a pair of tokens addresses, path[0] should be the address of input Token & path[1] should be the address of output Token.
* @param {string} amountIn - amount of Token to be swapped.
* @param {string} amountDesiredOut - minimum amount of Tokens expecting to receive.
* @param {number} deadline - UTC timestamp as deadline of this transaction, once deadline passed on-chain transaction should be reverted.
* * @return {Promise<ContractTransaction>} - ContractTransaction object.
*/
public async exactTokensForTokens(amountIn: string, amountDesiredOut: string, path: string[], deadline: string): Promise<ContractTransaction> {
if (path.length < 2) throw new Error('exactTokensForTokens => path length must be at least 2');
const inputToken: KIP7 = KIP7__factory.connect(path[0], this.router.provider);
const signerAddress: string = await this.router.signer.getAddress();
const allowance: BigNumber = await inputToken.allowance(signerAddress,this.router.address);
// check if input token's allowance sufficient
if (allowance.lt(BigNumber.from(amountIn))) throw new Error(`exactTokensForTokens => inputToken insufficient allowance`)
return this.router.swapExactTokensForTokens(amountIn, amountDesiredOut, path, signerAddress, deadline);
}
/**
* A function to swap given amount of Tokens for exact amount of KLAYs.
* @param {string[]} path - a pair of tokens addresses, path[0] should be the address of Token & path[1] should be the address of WKLAY.
* @param {string} amountDesiredMaxIn - max amount of Tokens to be swapped.
* @param {string} amountOut - exact amount of KLAYs expecting to receive.
* @param {number} deadline - UTC timestamp as deadline of this transaction, once deadline passed on-chain transaction should be reverted.
* @return {Promise<ContractTransaction>} - ContractTransaction object.
*/
public async tokensForExactTokens(amountOut: string, amountDesiredMaxIn: string, path: string[], deadline: string): Promise<ContractTransaction> {
if (path.length < 2) throw new Error('tokensForExactTokens => path length must be at least 2');
const inputToken: KIP7 = KIP7__factory.connect(path[0], this.router.provider);
const signerAddress: string = await this.router.signer.getAddress();
const allowance: BigNumber = await inputToken.allowance(signerAddress,this.router.address);
// check if input token's allowance sufficient
if (allowance.lt(BigNumber.from(amountDesiredMaxIn))) throw new Error(`tokensForExactTokens => inputToken insufficient allowance`)
return this.router.swapTokensForExactTokens(amountOut, amountDesiredMaxIn, path, signerAddress, deadline);
}
/**
* A function to swap exact amount of KLAY for a given amount of Tokens.
* @param {string[]} path - a pair of tokens address, path[0] should be the address of WKLAY & path[1] should be the address of out Token.
* @param {string} amountKlayIn - amount of WKLAY tokens to be swapped.
* @param {string} amountDesiredOutMin - minimum amount of tokens expecting to receive.
* @param {number} deadline - UTC timestamp as deadline of this transaction, once deadline passed on-chain transaction should be reverted.
* @return {Promise<ContractTransaction>} - ContractTransaction object.
*/
public async exactKlayForTokens(amountKlayIn: string, amountDesiredOutMin: string, path: string[], deadline: string): Promise<ContractTransaction> {
if (path.length < 2) throw new Error('func#exactKlayForTokens: path length must be at least 2');
// const inputToken: KIP7 = new KIP7__factory().attach(path[0]); // WKLAY no approval required as router internally wrapping KLAY into WKLAY to proceed
const signerAddress: string = await this.router.signer.getAddress();
const klayBalance: BigNumber = await this.router.signer.getBalance()
// check if input token's allowance sufficient
if (klayBalance.lt(BigNumber.from(amountKlayIn))) throw new Error(`func#tokensForExactTokens: KLAY insufficient balance`)
return this.router.swapExactKLAYForTokens(amountDesiredOutMin, path, signerAddress, deadline, {value: amountKlayIn});
}
/**
* A function to swap given amount of Tokens for exact amount of KLAYs.
* @param {string[]} path - a pair of tokens addresses, path[0] should be the address of Token & path[1] should be the address of WKLAY.
* @param {string} amountDesiredTokenMaxIn - max amount of Tokens to be swapped.
* @param {string} amountKlayOut - exact amount of KLAYs expecting to receive.
* @param {number} deadline - UTC timestamp as deadline of this transaction, once deadline passed on-chain transaction should be reverted.
* @return {Promise<ContractTransaction>} - ContractTransaction object.
*/
public async tokensForExactKlay(amountKlayOut: string, amountDesiredTokenMaxIn: string, path: string[], deadline: string): Promise<ContractTransaction> {
if (path.length < 2) throw new Error('tokensForExactTokens => path length must be at least 2');
const inputToken: KIP7 = KIP7__factory.connect(path[0], this.router.provider);
const signerAddress: string = await this.router.signer.getAddress();
const allowance: BigNumber = await inputToken.allowance(signerAddress,this.router.address);
// check if input token's allowance sufficient
if (allowance.lt(BigNumber.from(amountDesiredTokenMaxIn))) throw new Error(`tokensForExactTokens => inputToken insufficient allowance`)
return this.router.swapTokensForExactKLAY(amountKlayOut, amountDesiredTokenMaxIn, path, signerAddress, deadline);
}
/**
* A function to swap exact amount of Tokens for a given amount of KLAY.
* @param {string[]} path - a pair of tokens addresses, path[0] should be the address of Token & path[1] should be the address of WKLAY.
* @param {string} amountIn - amount of Token to be swapped.
* @param {string} amountDesiredKlayOut - minimum amount of KLAYs expecting to receive.
* @param {number} deadline - UTC timestamp as deadline of this transaction, once deadline passed on-chain transaction should be reverted.
* @return {Promise<ContractTransaction>} - ContractTransaction object.
*/
public async exactTokensForKlay(amountIn: string, amountDesiredKlayOut: string, path: string[], deadline: string): Promise<ContractTransaction> {
if (path.length < 2) throw new Error('exactTokensForTokens => path length must be at least 2');
const inputToken: KIP7 = KIP7__factory.connect(path[0], this.router.provider);
const signerAddress: string = await this.router.signer.getAddress();
const allowance: BigNumber = await inputToken.allowance(signerAddress,this.router.address);
// check if input token's allowance sufficient
if (allowance.lt(BigNumber.from(amountIn))) throw new Error(`exactTokensForTokens => inputToken insufficient allowance`)
return this.router.swapExactTokensForTokens(amountIn, amountDesiredKlayOut, path, signerAddress, deadline);
}
/**
* A function to swap KLAYs for a given exact amount of Tokens.
* @param {string[]} path - a pair of tokens addresses, path[0] should be the address of WKLAY & path[1] should be the address of output Token.
* @param {string} amountKlayIn - max amount of WKLAY to be swapped.
* @param {string} amountDesiredOut - exact amount of Tokens expecting to receive.
* @param {number} deadline - UTC timestamp as deadline of this transaction, once deadline passed on-chain transaction should be reverted.
* @return {Promise<ContractTransaction>} - ContractTransaction object.
*/
public async klayForExactTokens(amountKlayIn: string, amountDesiredOut: string, path: string[], deadline: string): Promise<ContractTransaction> {
if (path.length < 2) throw new Error('klayForExactTokens => path length must be at least 2');
// const inputToken: KIP7 = new KIP7__factory().attach(path[0]); // WKLAY no approval required as router internally wrapping KLAY into WKLAY to proceed
const signerAddress: string = await this.router.signer.getAddress();
const klayBalance: BigNumber = await this.router.signer.getBalance()
// check if input token's allowance sufficient
if (klayBalance.lt(BigNumber.from(amountKlayIn))) throw new Error(`klayForExactTokens => KLAY insufficient balance`)
return this.router.swapKLAYForExactTokens(amountDesiredOut, path, signerAddress, deadline, {value: amountKlayIn});
}
// Getters
/**
* A getter function to return DexRouter contract's instance
* @return {DexRouter} - DexRouter contract's instance.
*/
public getRouter(): DexRouter { return this.router}
/**
* A getter function to fetch instance of DexPair contract.
* @param {string} tokenA - Address of token0 contract.
* @param {string} tokenB - Address of token1 contract.
* @param {string} privKey - private key of signer account.
* @param {string} rpcURL - RPC URL of blockchain provider.
* @return {Promise<DexPair>} - DexPair contract's instance.
*/
public async getPair(tokenA: string, tokenB: string, privKey: string, rpcURL: string):Promise<DexPair> {
const pairAddress: string = await this.factory.getPair(tokenA, tokenB)
return DexPair__factory.connect(pairAddress, new Wallet(privKey, new providers.JsonRpcProvider(rpcURL)))
}
/**
* A getter function to get WKLAY contract's address
* @return {string} - WKLAY address.
*/
public async getAddressOfWKLAY():Promise<string> {
return this.router.WKLAY()
}
}