@@ -18,286 +18,26 @@ import {
18
18
} from '../../constants' ;
19
19
import { Services } from '../../core/services' ;
20
20
import { BestRoute } from '../../types/router' ;
21
- import { Balance } from '../../types/swap' ;
21
+ import { Balance , SwapResponse } from '../../types/swap' ;
22
22
import { DEX , pTON } from '@ston-fi/sdk' ;
23
- import {
24
- Asset ,
25
- Factory ,
26
- JettonRoot ,
27
- MAINNET_FACTORY_ADDR ,
28
- Pool ,
29
- PoolType ,
30
- ReadinessStatus ,
31
- Vault ,
32
- VaultJetton ,
33
- VaultNative ,
34
- } from '@dedust/sdk' ;
23
+
35
24
import { sleep } from '@lifeomic/attempt' ;
36
25
37
26
export class Swap extends Services {
38
27
/**
39
28
* swap
40
29
*/
41
- public async createSwap ( userWalletAddress : string , bestRoute : BestRoute ) {
42
- try {
43
- switch ( bestRoute . selected_pool . dex ) {
44
- case 'stonfi' :
45
- return await this . createStonSwap ( userWalletAddress , bestRoute ) ;
46
- case 'dedust' :
47
- return await this . createDedustSwap ( userWalletAddress , bestRoute ) ;
48
-
49
- default :
50
- break ;
51
- }
52
- } catch ( error ) {
53
- console . log ( error ) ;
54
- }
55
- }
56
-
57
- /**
58
- * createStonSwap
59
- *
60
- */
61
- private async createStonSwap ( userWalletAddress : string , bestRoute : BestRoute ) {
62
- let jettonData : Balance | undefined ;
63
- let swapTxParams : SenderArguments | null = null ;
64
- const isMintless = supportedMintlessTokens . includes ( bestRoute . selected_pool . token0_address ) ;
65
- if ( isMintless ) {
66
- jettonData = await this . client . tonapi . getJettonData (
67
- userWalletAddress ,
68
- bestRoute . selected_pool . token0_address ,
69
- ) ;
70
- }
71
-
72
- let customPayload : Cell | undefined ;
73
- let stateInit : { code : Cell ; data : Cell } | undefined ;
74
-
75
- if ( isMintless && jettonData ?. extensions ?. includes ( 'custom_payload' ) ) {
76
- const offerJettonCustomPayload = await this . client . tonapi . getCustomPayload (
77
- userWalletAddress ,
78
- bestRoute . selected_pool . token0_address ,
79
- ) ;
80
-
81
- if ( ! offerJettonCustomPayload ) {
82
- throw new Error ( 'Unable to retrieve custom payload. Please try again.' ) ;
83
- }
84
- customPayload = Cell . fromBoc (
85
- Buffer . from ( offerJettonCustomPayload . custom_payload , 'hex' ) ,
86
- ) [ 0 ] ;
87
- const stateInitCell = Cell . fromBoc (
88
- Buffer . from ( offerJettonCustomPayload . state_init , 'hex' ) ,
89
- ) [ 0 ] . beginParse ( ) ;
90
-
91
- stateInit = {
92
- code : stateInitCell . loadRef ( ) ,
93
- data : stateInitCell . loadRef ( ) ,
94
- } ;
95
- }
96
-
97
- const router =
98
- bestRoute . selected_pool . router_address === STON_ROUTER_V1
99
- ? this . client . tonClient . open (
100
- DEX . v1 . Router . create ( bestRoute . selected_pool . router_address ) ,
101
- )
102
- : this . client . tonClient . open (
103
- DEX . v2_1 . Router . create ( bestRoute . selected_pool . router_address ) ,
104
- ) ;
105
-
106
- const pTon =
107
- bestRoute . selected_pool . router_address === STON_ROUTER_V1
108
- ? new pTON . v1 ( )
109
- : new pTON . v2_1 ( PTON_V2 ) ;
110
- const gasConstants =
111
- bestRoute . selected_pool . router_address === STON_ROUTER_V1
112
- ? DEX . v1 . Router . gasConstants
113
- : DEX . v2_1 . Router . gasConstants ;
114
-
115
- if ( bestRoute . pool_data . route [ 0 ] === TON_ADDRESS ) {
116
- swapTxParams = await router . getSwapTonToJettonTxParams ( {
117
- userWalletAddress : userWalletAddress ,
118
- proxyTon : pTon ,
119
- offerAmount : bestRoute . pool_data . pay ,
120
- askJettonAddress : bestRoute . pool_data . route [ 1 ] ,
121
- minAskAmount : BigInt ( bestRoute . pool_data . minimumReceive ) ,
122
- referralAddress : address ( feeWallet ) ,
123
- } ) ;
124
- } else if ( bestRoute . pool_data . route [ 1 ] === TON_ADDRESS ) {
125
- swapTxParams = await router . getSwapJettonToTonTxParams ( {
126
- userWalletAddress : userWalletAddress ,
127
- offerJettonAddress : bestRoute . pool_data . route [ 0 ] ,
128
- offerAmount : bestRoute . pool_data . pay ,
129
- proxyTon : pTon ,
130
- jettonCustomPayload : customPayload ? customPayload : undefined ,
131
- minAskAmount : BigInt ( bestRoute . pool_data . minimumReceive ) ,
132
- referralAddress : feeWallet ,
133
- gasAmount : isMintless
134
- ? gasConstants . swapJettonToJetton . gasAmount + toNano ( 0.1 )
135
- : undefined ,
136
- } ) ;
137
- } else {
138
- swapTxParams = await router . getSwapJettonToJettonTxParams ( {
139
- userWalletAddress : userWalletAddress ,
140
- offerJettonAddress : bestRoute . selected_pool . token0_address ,
141
- offerAmount : BigInt ( bestRoute . pool_data . pay ) ,
142
- askJettonAddress : bestRoute . selected_pool . token1_address ,
143
- jettonCustomPayload : customPayload ? customPayload : undefined ,
144
-
145
- minAskAmount : BigInt ( bestRoute . pool_data . minimumReceive ) ,
146
- referralAddress : address ( feeWallet ) ,
147
- gasAmount : stateInit
148
- ? gasConstants . swapJettonToJetton . gasAmount + toNano ( 0.1 )
149
- : undefined ,
150
- } ) ;
151
- }
152
- return swapTxParams satisfies SenderArguments ;
153
- }
154
-
155
- private async createDedustSwap ( userWalletAddress : string , bestRoute : BestRoute ) {
156
- let [ jetton0 , jetton1 , jetton2 ] = bestRoute . pool_data . route ;
157
-
158
- let Asset0 : Asset ;
159
- let Asset1 : Asset ;
160
- let Asset2 : Asset ;
161
- let Vault0 : OpenedContract < VaultNative > | OpenedContract < VaultJetton > ;
162
- let Vault2 : OpenedContract < VaultNative > | OpenedContract < VaultJetton > ;
163
- let PoolB : OpenedContract < Pool > ;
164
- let RequestAddress : Address ;
165
- let StoreAddress : Address ;
166
-
167
- let TxAmount = toNano ( '0.3' ) ;
168
-
169
- let jettonData : Balance | undefined ;
170
- const isMintless = supportedMintlessTokens . includes ( bestRoute . selected_pool . token0_address ) ;
171
- if ( isMintless ) {
172
- jettonData = await this . client . tonapi . getJettonData (
173
- userWalletAddress ,
174
- bestRoute . selected_pool . token0_address ,
175
- ) ;
176
- }
177
-
178
- let customPayload : Cell | undefined ;
179
- let stateInit : { code : Cell ; data : Cell } | undefined ;
180
- if ( isMintless && jettonData ?. extensions ?. includes ( 'custom_payload' ) ) {
181
- const offerJettonCustomPayload = await this . client . tonapi . getCustomPayload (
182
- userWalletAddress ,
183
- bestRoute . selected_pool . token0_address ,
184
- ) ;
185
-
186
- if ( ! offerJettonCustomPayload ) {
187
- throw new Error ( 'Unable to retrieve custom payload. Please try again.' ) ;
188
- }
189
- customPayload = Cell . fromBoc (
190
- Buffer . from ( offerJettonCustomPayload . custom_payload , 'hex' ) ,
191
- ) [ 0 ] ;
192
- const stateInitCell = Cell . fromBoc (
193
- Buffer . from ( offerJettonCustomPayload . state_init , 'hex' ) ,
194
- ) [ 0 ] . beginParse ( ) ;
195
-
196
- stateInit = {
197
- code : stateInitCell . loadRef ( ) ,
198
- data : stateInitCell . loadRef ( ) ,
199
- } ;
200
- }
201
- const factory = this . client . tonClient . open ( Factory . createFromAddress ( MAINNET_FACTORY_ADDR ) ) ;
202
- await sleep ( 500 ) ;
203
- if ( jetton0 == 'EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c' ) {
204
- if ( jetton2 && jetton2 !== '' ) {
205
- throw new Error ( 'This request can not process!' ) ;
206
- }
207
-
208
- Asset0 = Asset . native ( ) ;
209
- Vault0 = this . client . tonClient . open ( await factory . getNativeVault ( ) ) ;
210
- } else {
211
- Asset0 = Asset . jetton ( Address . parse ( jetton0 ) ) ;
212
- Vault0 = this . client . tonClient . open (
213
- await factory . getJettonVault ( Address . parse ( jetton0 ) ) ,
214
- ) ;
215
- }
216
- await sleep ( 500 ) ;
217
- if ( jetton1 == 'EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c' ) {
218
- Asset1 = Asset . native ( ) ;
219
- } else {
220
- Asset1 = Asset . jetton ( Address . parse ( jetton1 ) ) ;
221
- }
222
- await sleep ( 500 ) ;
223
- const PoolA = this . client . tonClient . open (
224
- await factory . getPool ( PoolType . VOLATILE , [ Asset0 , Asset1 ] ) ,
225
- ) ;
226
- if ( jetton2 && jetton2 !== '' ) {
227
- if ( jetton2 == 'EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c' ) {
228
- Asset2 = Asset . native ( ) ;
229
- } else {
230
- Asset2 = Asset . jetton ( Address . parse ( jetton2 ) ) ;
231
- }
232
- await sleep ( 500 ) ;
233
-
234
- PoolB = this . client . tonClient . open (
235
- await factory . getPool ( PoolType . VOLATILE , [ Asset1 , Asset2 ] ) ,
236
- ) ;
237
- }
238
-
239
- let PAY_LOAD : Cell ;
240
- let pay : Cell ;
241
- if ( jetton0 == 'EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c' ) {
242
- // @ts -expect-error because dedust doesn't let user to build custom payloads
243
- PAY_LOAD = Vault . packSwapParams ( { } ) ;
244
-
245
- StoreAddress = PoolA . address ;
246
- RequestAddress = Vault0 . address ;
247
-
248
- TxAmount = BigInt ( bestRoute . pool_data . pay ) + toNano ( '0.1' ) ;
249
-
250
- pay = beginCell ( )
251
- . storeUint ( DEDUST_SWAP , 32 )
252
- . storeUint ( 0 , 64 )
253
- . storeCoins ( BigInt ( bestRoute . pool_data . pay ) )
254
- . storeAddress ( StoreAddress )
255
- . storeUint ( 0 , 1 )
256
- . storeCoins ( 0 )
257
- . storeMaybeRef ( null )
258
- . storeRef ( PAY_LOAD )
259
- . endCell ( ) ;
260
- } else {
261
- const JRoot = this . client . tonClient . open (
262
- JettonRoot . createFromAddress ( Address . parse ( jetton0 ) ) ,
263
- ) ;
264
- const JWallet = this . client . tonClient . open (
265
- await JRoot . getWallet ( Address . parseRaw ( userWalletAddress ) ) ,
266
- ) ;
267
-
268
- StoreAddress = Vault0 . address ;
269
- RequestAddress = JWallet . address ;
270
-
271
- if ( jetton2 == '' ) {
272
- PAY_LOAD = VaultJetton . createSwapPayload ( {
273
- poolAddress : Address . parse ( PoolA . address . toString ( ) ) ,
274
- } ) ;
275
- } else {
276
- PAY_LOAD = VaultJetton . createSwapPayload ( {
277
- poolAddress : Address . parse ( PoolA . address . toString ( ) ) ,
278
- limit : BigInt ( bestRoute . pool_data . innerMinimumReceive ) ,
279
- next : {
280
- poolAddress : PoolB ! . address ,
281
- } ,
282
- } ) ;
283
- }
284
-
285
- pay = beginCell ( )
286
- . storeUint ( DEDUST_TRANSFER , 32 )
287
- . storeUint ( 0 , 64 )
288
- . storeCoins ( BigInt ( bestRoute . pool_data . pay ) )
289
- . storeAddress ( StoreAddress )
290
- . storeAddress ( Address . parseRaw ( userWalletAddress ) )
291
- . storeMaybeRef ( customPayload ? customPayload : null )
292
- . storeCoins ( toNano ( '0.25' ) )
293
- . storeMaybeRef ( PAY_LOAD )
294
- . endCell ( ) ;
295
- }
296
- return {
297
- to : RequestAddress ,
298
- value : isMintless ? TxAmount + toNano ( 0.07 ) : TxAmount ,
299
- body : pay ,
300
- init : stateInit ,
301
- } satisfies SenderArguments ;
30
+ public async createSwap ( userWalletAddress : string , bestRoute : BestRoute , app_id ?: string ) {
31
+ return await this . client . request . send < SwapResponse > ( {
32
+ method : 'POST' ,
33
+ headers : {
34
+ ...( app_id ? { app_id : app_id } : { } ) ,
35
+ } ,
36
+ url : 'v2/routes/boc' ,
37
+ data : {
38
+ userWallet : userWalletAddress ,
39
+ bestRoute : bestRoute ,
40
+ } ,
41
+ } ) ;
302
42
}
303
43
}
0 commit comments