@liberfi.io/react-launchpad 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs ADDED
@@ -0,0 +1,779 @@
1
+ import { createContext, createElement, useContext } from 'react';
2
+ import BigNumber3, { BigNumber } from 'bignumber.js';
3
+
4
+ // src/index.ts
5
+
6
+ // src/curve/BaseCurve.ts
7
+ function unimplemented(args) {
8
+ throw new Error("not implemented");
9
+ }
10
+ var BaseCurve = class {
11
+ static getPoolInitPriceByPool(args) {
12
+ return unimplemented();
13
+ }
14
+ static getPoolInitPriceByInit(args) {
15
+ return unimplemented();
16
+ }
17
+ static getPoolPrice(args) {
18
+ return unimplemented();
19
+ }
20
+ static getPoolEndPrice(args) {
21
+ return unimplemented();
22
+ }
23
+ static getPoolEndPriceReal(args) {
24
+ return unimplemented();
25
+ }
26
+ static getInitParam(args) {
27
+ return unimplemented();
28
+ }
29
+ static buyExactIn(args) {
30
+ return unimplemented();
31
+ }
32
+ static buyExactOut(args) {
33
+ return unimplemented();
34
+ }
35
+ static sellExactIn(args) {
36
+ return unimplemented();
37
+ }
38
+ static sellExactOut(args) {
39
+ return unimplemented();
40
+ }
41
+ };
42
+ var ConstantProductCurve = class extends BaseCurve {
43
+ static getPoolInitPriceByPool({
44
+ poolInfo,
45
+ decimalA,
46
+ decimalB
47
+ }) {
48
+ return new BigNumber(poolInfo.virtualB).div(poolInfo.virtualA).times(10 ** (decimalA - decimalB));
49
+ }
50
+ static getPoolInitPriceByInit({
51
+ a,
52
+ b,
53
+ decimalA,
54
+ decimalB
55
+ }) {
56
+ return new BigNumber(b).div(a).times(10 ** (decimalA - decimalB));
57
+ }
58
+ static getPoolPrice({
59
+ poolInfo,
60
+ decimalA,
61
+ decimalB
62
+ }) {
63
+ return new BigNumber(new BigNumber(poolInfo.virtualB).plus(poolInfo.realB)).div(new BigNumber(poolInfo.virtualA).minus(poolInfo.realA)).times(10 ** (decimalA - decimalB));
64
+ }
65
+ static getPoolEndPrice({
66
+ supply,
67
+ totalSell,
68
+ totalLockedAmount,
69
+ totalFundRaising,
70
+ migrateFee,
71
+ decimalA,
72
+ decimalB
73
+ }) {
74
+ return new BigNumber(new BigNumber(totalFundRaising).minus(migrateFee)).div(new BigNumber(supply).minus(totalSell).minus(totalLockedAmount)).times(10 ** (decimalA - decimalB));
75
+ }
76
+ static getPoolEndPriceReal({
77
+ poolInfo,
78
+ decimalA,
79
+ decimalB
80
+ }) {
81
+ const allSellToken = new BigNumber(poolInfo.totalSellA).minus(poolInfo.realA);
82
+ const buyAllTokenUseB = new BigNumber(poolInfo.totalFundRaisingB).minus(poolInfo.realB);
83
+ return new BigNumber(
84
+ new BigNumber(poolInfo.virtualB).plus(poolInfo.realB).plus(buyAllTokenUseB)
85
+ ).div(new BigNumber(poolInfo.virtualA).minus(new BigNumber(poolInfo.realA).plus(allSellToken))).times(10 ** (decimalA - decimalB));
86
+ }
87
+ static getInitParam({
88
+ supply,
89
+ totalFundRaising,
90
+ totalSell,
91
+ totalLockedAmount,
92
+ migrateFee
93
+ }) {
94
+ if (new BigNumber(supply).lte(totalSell)) throw Error("supply need gt total sell");
95
+ const supplyMinusSellLocked = new BigNumber(supply).minus(totalSell).minus(totalLockedAmount);
96
+ if (supplyMinusSellLocked.lte(new BigNumber(0))) throw Error("supplyMinusSellLocked <= 0");
97
+ const tfMinusMf = new BigNumber(totalFundRaising).minus(migrateFee);
98
+ if (tfMinusMf.lte(0)) throw Error("tfMinusMf <= 0");
99
+ const numerator = tfMinusMf.times(totalSell).times(totalSell).div(supplyMinusSellLocked);
100
+ const denominator = tfMinusMf.times(totalSell).div(supplyMinusSellLocked).minus(totalFundRaising);
101
+ if (denominator.lt(0)) throw Error("supply/totalSell/totalLockedAmount diff too high");
102
+ const x0 = numerator.div(denominator);
103
+ const y0 = new BigNumber(totalFundRaising).times(totalFundRaising).div(denominator);
104
+ if (x0.lt(0) || y0.lt(0)) throw Error("invalid input 0");
105
+ return {
106
+ a: x0,
107
+ b: y0,
108
+ c: totalSell
109
+ };
110
+ }
111
+ static buyExactIn({
112
+ poolInfo,
113
+ amount
114
+ }) {
115
+ return this.getAmountOut({
116
+ amountIn: amount,
117
+ inputReserve: new BigNumber(poolInfo.virtualB).plus(poolInfo.realB),
118
+ outputReserve: new BigNumber(poolInfo.virtualA).minus(poolInfo.realA)
119
+ });
120
+ }
121
+ static buyExactOut({
122
+ poolInfo,
123
+ amount
124
+ }) {
125
+ return this.getAmountIn({
126
+ amountOut: amount,
127
+ inputReserve: new BigNumber(poolInfo.virtualB).plus(poolInfo.realB),
128
+ outputReserve: new BigNumber(poolInfo.virtualA).minus(poolInfo.realA)
129
+ });
130
+ }
131
+ static sellExactIn({
132
+ poolInfo,
133
+ amount
134
+ }) {
135
+ return this.getAmountOut({
136
+ amountIn: amount,
137
+ inputReserve: new BigNumber(poolInfo.virtualA).minus(poolInfo.realA),
138
+ outputReserve: new BigNumber(poolInfo.virtualB).plus(poolInfo.realB)
139
+ });
140
+ }
141
+ static sellExactOut({
142
+ poolInfo,
143
+ amount
144
+ }) {
145
+ return this.getAmountIn({
146
+ amountOut: amount,
147
+ inputReserve: new BigNumber(poolInfo.virtualA).minus(poolInfo.realA),
148
+ outputReserve: new BigNumber(poolInfo.virtualB).plus(poolInfo.realB)
149
+ });
150
+ }
151
+ static getAmountOut({
152
+ amountIn,
153
+ inputReserve,
154
+ outputReserve
155
+ }) {
156
+ const numerator = new BigNumber(amountIn).times(outputReserve);
157
+ const denominator = new BigNumber(inputReserve).plus(amountIn);
158
+ const amountOut = numerator.div(denominator);
159
+ return amountOut;
160
+ }
161
+ static getAmountIn({
162
+ amountOut,
163
+ inputReserve,
164
+ outputReserve
165
+ }) {
166
+ const numerator = new BigNumber(inputReserve).times(amountOut);
167
+ const denominator = new BigNumber(outputReserve).minus(amountOut);
168
+ const amountIn = numerator.div(denominator);
169
+ return amountIn;
170
+ }
171
+ };
172
+
173
+ // src/types.ts
174
+ var LaunchPadPlatform = /* @__PURE__ */ ((LaunchPadPlatform2) => {
175
+ LaunchPadPlatform2["PUMPFUN"] = "pumpfun";
176
+ LaunchPadPlatform2["RAYDIUM"] = "raydium";
177
+ return LaunchPadPlatform2;
178
+ })(LaunchPadPlatform || {});
179
+ var CurveType = /* @__PURE__ */ ((CurveType2) => {
180
+ CurveType2["CONSTANT_PRODUCT"] = "constant_product";
181
+ CurveType2["FIXED_PRICE"] = "fixed_price";
182
+ CurveType2["LINEAR_PRICE"] = "linear_price";
183
+ return CurveType2;
184
+ })(CurveType || {});
185
+ var FixedPriceCurve = class extends BaseCurve {
186
+ static getPoolInitPriceByPool({
187
+ poolInfo,
188
+ decimalA,
189
+ decimalB
190
+ }) {
191
+ return BigNumber3(poolInfo.virtualB).div(poolInfo.virtualA).times(10 ** (decimalA - decimalB));
192
+ }
193
+ static getPoolInitPriceByInit({
194
+ a,
195
+ b,
196
+ decimalA,
197
+ decimalB
198
+ }) {
199
+ return BigNumber3(b).div(a).times(10 ** (decimalA - decimalB));
200
+ }
201
+ static getPoolPrice({
202
+ poolInfo,
203
+ decimalA,
204
+ decimalB
205
+ }) {
206
+ return BigNumber3(poolInfo.virtualB).div(poolInfo.virtualA).times(10 ** (decimalA - decimalB));
207
+ }
208
+ static getPoolEndPrice({
209
+ supply,
210
+ totalSell,
211
+ totalLockedAmount,
212
+ totalFundRaising,
213
+ migrateFee,
214
+ decimalA,
215
+ decimalB
216
+ }) {
217
+ return BigNumber3(totalFundRaising).minus(migrateFee).div(BigNumber3(supply).minus(totalSell).minus(totalLockedAmount)).times(10 ** (decimalA - decimalB));
218
+ }
219
+ static getPoolEndPriceReal({
220
+ poolInfo,
221
+ decimalA,
222
+ decimalB
223
+ }) {
224
+ const allSellToken = BigNumber3(poolInfo.totalSellA).minus(poolInfo.realA);
225
+ const buyAllTokenUseB = BigNumber3(poolInfo.totalFundRaisingB).minus(poolInfo.realB);
226
+ return BigNumber3(poolInfo.virtualB).plus(poolInfo.realB).plus(buyAllTokenUseB).div(BigNumber3(poolInfo.virtualA).minus(poolInfo.realA).plus(allSellToken)).times(10 ** (decimalA - decimalB));
227
+ }
228
+ static getInitParam({
229
+ supply,
230
+ totalFundRaising,
231
+ totalLockedAmount,
232
+ migrateFee
233
+ }) {
234
+ const supplyMinusLocked = BigNumber3(supply).minus(totalLockedAmount);
235
+ if (supplyMinusLocked.lte(0)) throw Error("invalid input 1");
236
+ const denominator = BigNumber3(2).times(totalFundRaising).minus(migrateFee);
237
+ const numerator = BigNumber3(totalFundRaising).times(supplyMinusLocked);
238
+ const totalSellExpect = numerator.div(denominator);
239
+ return { a: totalSellExpect, b: totalFundRaising, c: totalSellExpect };
240
+ }
241
+ static buyExactIn({
242
+ poolInfo,
243
+ amount
244
+ }) {
245
+ return this.getAmountOut({
246
+ amountIn: amount,
247
+ initInput: poolInfo.virtualB,
248
+ initOutput: poolInfo.virtualA
249
+ });
250
+ }
251
+ static buyExactOut({
252
+ poolInfo,
253
+ amount
254
+ }) {
255
+ return this.getAmountIn({
256
+ amountOut: amount,
257
+ initInput: poolInfo.virtualB,
258
+ initOutput: poolInfo.virtualA
259
+ });
260
+ }
261
+ static sellExactIn({
262
+ poolInfo,
263
+ amount
264
+ }) {
265
+ return this.getAmountOut({
266
+ amountIn: amount,
267
+ initInput: poolInfo.virtualA,
268
+ initOutput: poolInfo.virtualB
269
+ });
270
+ }
271
+ static sellExactOut({
272
+ poolInfo,
273
+ amount
274
+ }) {
275
+ return this.getAmountIn({
276
+ amountOut: amount,
277
+ initInput: poolInfo.virtualA,
278
+ initOutput: poolInfo.virtualB
279
+ });
280
+ }
281
+ static getAmountOut({
282
+ amountIn,
283
+ initInput,
284
+ initOutput
285
+ }) {
286
+ const numerator = new BigNumber3(initOutput).times(amountIn);
287
+ const amountOut = numerator.div(initInput);
288
+ return amountOut;
289
+ }
290
+ static getAmountIn({
291
+ amountOut,
292
+ initInput,
293
+ initOutput
294
+ }) {
295
+ const numerator = new BigNumber3(initInput).times(amountOut);
296
+ const amountIn = numerator.div(initOutput);
297
+ return amountIn;
298
+ }
299
+ };
300
+ var LinearPriceCurve = class extends BaseCurve {
301
+ static getPoolInitPriceByPool(args) {
302
+ return 0;
303
+ }
304
+ static getPoolInitPriceByInit(args) {
305
+ return 0;
306
+ }
307
+ static getPoolPrice({
308
+ poolInfo,
309
+ decimalA,
310
+ decimalB
311
+ }) {
312
+ return new BigNumber3(poolInfo.virtualA).times(poolInfo.realA).div(new BigNumber3(1).shiftedBy(-64)).times(10 ** (decimalA - decimalB));
313
+ }
314
+ static getPoolEndPrice({
315
+ supply,
316
+ totalSell,
317
+ totalLockedAmount,
318
+ totalFundRaising,
319
+ migrateFee,
320
+ decimalA,
321
+ decimalB
322
+ }) {
323
+ return new BigNumber3(totalFundRaising).minus(migrateFee).div(new BigNumber3(supply).minus(totalSell).minus(totalLockedAmount)).times(10 ** (decimalA - decimalB));
324
+ }
325
+ static getPoolEndPriceReal({
326
+ poolInfo,
327
+ decimalA,
328
+ decimalB
329
+ }) {
330
+ const allSellToken = new BigNumber3(poolInfo.totalSellA).minus(poolInfo.realA);
331
+ const buyAllTokenUseB = new BigNumber3(poolInfo.totalFundRaisingB).minus(poolInfo.realB);
332
+ return new BigNumber3(poolInfo.virtualB).plus(poolInfo.realB).plus(buyAllTokenUseB).div(new BigNumber3(poolInfo.virtualA).minus(poolInfo.realA).minus(allSellToken)).times(10 ** (decimalA - decimalB));
333
+ }
334
+ static getInitParam({
335
+ supply,
336
+ totalFundRaising,
337
+ totalLockedAmount,
338
+ migrateFee
339
+ }) {
340
+ const supplyMinusLocked = new BigNumber3(supply).minus(totalLockedAmount);
341
+ if (supplyMinusLocked.lte(0)) throw Error("supplyMinusLocked need gt 0");
342
+ const denominator = new BigNumber3(totalFundRaising).times(3).minus(migrateFee);
343
+ const numerator = new BigNumber3(totalFundRaising).times(2).minus(supplyMinusLocked);
344
+ const totalSellExpect = numerator.div(denominator);
345
+ const totalSellSquared = totalSellExpect.times(totalSellExpect);
346
+ const a = new BigNumber3(totalFundRaising).times(2).times(new BigNumber3(1).shiftedBy(-64)).div(totalSellSquared);
347
+ if (!a.gt(0)) throw Error("a need gt 0");
348
+ const MaxU64 = new BigNumber3(1).shiftedBy(-64).minus(1);
349
+ if (!MaxU64.gt(a)) throw Error("a need lt u64 max");
350
+ return { a, b: 0, c: totalSellExpect };
351
+ }
352
+ static buyExactIn({
353
+ poolInfo,
354
+ amount
355
+ }) {
356
+ const newQuote = new BigNumber3(poolInfo.realB).plus(amount);
357
+ const termInsideSqrt = new BigNumber3(2).times(newQuote).times(new BigNumber3(1).shiftedBy(-64)).div(poolInfo.virtualA);
358
+ const sqrtTerm = new BigNumber3(new BigNumber3(termInsideSqrt).sqrt().toFixed(0));
359
+ const amountOut = sqrtTerm.minus(poolInfo.realA);
360
+ return amountOut;
361
+ }
362
+ static buyExactOut({
363
+ poolInfo,
364
+ amount
365
+ }) {
366
+ const newBase = new BigNumber3(poolInfo.realA).plus(amount);
367
+ const newBaseSquared = newBase.times(newBase);
368
+ const newQuote = new BigNumber3(poolInfo.virtualA).times(newBaseSquared).div(new BigNumber3(2).times(new BigNumber3(1).shiftedBy(-64)));
369
+ return newQuote.minus(poolInfo.realB);
370
+ }
371
+ static sellExactIn({
372
+ poolInfo,
373
+ amount
374
+ }) {
375
+ const newBase = new BigNumber3(poolInfo.realA).minus(amount);
376
+ const newBaseSquared = newBase.times(newBase);
377
+ const newQuote = new BigNumber3(poolInfo.virtualA).times(newBaseSquared).div(new BigNumber3(2).times(new BigNumber3(1).shiftedBy(-64)));
378
+ return new BigNumber3(poolInfo.realB).minus(newQuote);
379
+ }
380
+ static sellExactOut({
381
+ poolInfo,
382
+ amount
383
+ }) {
384
+ const newB = new BigNumber3(poolInfo.realB).minus(amount);
385
+ const termInsideSqrt = new BigNumber3(2).times(newB).times(new BigNumber3(1).shiftedBy(-64)).div(poolInfo.virtualA);
386
+ const sqrtTerm = new BigNumber3(new BigNumber3(termInsideSqrt).sqrt().toFixed(0));
387
+ const amountIn = new BigNumber3(poolInfo.realA).minus(sqrtTerm);
388
+ return amountIn;
389
+ }
390
+ };
391
+
392
+ // src/curve/Curve.ts
393
+ var Curve = class _Curve {
394
+ static getCurvePreviewPoints({
395
+ curveType,
396
+ pointCount,
397
+ poolInfo
398
+ }) {
399
+ return this.getPoolCurvePointByInit({
400
+ curveType,
401
+ pointCount,
402
+ supply: poolInfo.supply,
403
+ totalFundRaising: poolInfo.totalFundRaisingB,
404
+ totalSell: poolInfo.totalSellA,
405
+ totalLockedAmount: poolInfo.vestingSchedule.totalLockedAmount,
406
+ migrateFee: poolInfo.migrateFee,
407
+ decimalA: poolInfo.mintDecimalsA,
408
+ decimalB: poolInfo.mintDecimalsB
409
+ });
410
+ }
411
+ static getPoolCurvePointByInit({
412
+ curveType,
413
+ pointCount,
414
+ supply,
415
+ totalFundRaising,
416
+ totalSell,
417
+ totalLockedAmount,
418
+ migrateFee,
419
+ decimalA,
420
+ decimalB
421
+ }) {
422
+ if (pointCount < 3) throw Error("point count < 3");
423
+ const curve = this.getCurve(curveType);
424
+ const { a, b } = curve.getInitParam({
425
+ supply,
426
+ totalFundRaising,
427
+ totalSell,
428
+ totalLockedAmount,
429
+ migrateFee
430
+ });
431
+ const initPrice = curve.getPoolInitPriceByInit({ a, b, decimalA, decimalB });
432
+ const stepBuy = new BigNumber3(totalFundRaising).div(pointCount - 1);
433
+ const zero = new BigNumber3(0);
434
+ const returnPoints = [{ price: initPrice, totalSellSupply: 0 }];
435
+ let realA = zero;
436
+ let realB = zero;
437
+ for (let i = 1; i < pointCount; i++) {
438
+ const amountB = i !== pointCount - 1 ? stepBuy : new BigNumber3(totalFundRaising).minus(realB);
439
+ const itemBuy = this.buyExactIn({
440
+ poolInfo: {
441
+ virtualA: a,
442
+ virtualB: b,
443
+ realA,
444
+ realB,
445
+ totalFundRaisingB: totalFundRaising,
446
+ totalSellA: totalSell
447
+ },
448
+ amountB,
449
+ protocolFeeRate: zero,
450
+ platformFeeRate: zero,
451
+ curveType,
452
+ shareFeeRate: zero
453
+ });
454
+ realA = realA.plus(itemBuy.amountA);
455
+ realB = realB.plus(itemBuy.amountB);
456
+ const nowPoolPrice = this.getPrice({
457
+ poolInfo: { virtualA: a, virtualB: b, realA, realB },
458
+ decimalA,
459
+ decimalB,
460
+ curveType
461
+ });
462
+ returnPoints.push({
463
+ price: nowPoolPrice,
464
+ totalSellSupply: new BigNumber3(realA).div(10 ** decimalA).toNumber()
465
+ });
466
+ }
467
+ return returnPoints;
468
+ }
469
+ static getPoolInitPriceByPool({
470
+ poolInfo,
471
+ decimalA,
472
+ decimalB,
473
+ curveType
474
+ }) {
475
+ const curve = this.getCurve(curveType);
476
+ return curve.getPoolInitPriceByPool({ poolInfo, decimalA, decimalB });
477
+ }
478
+ static getPoolInitPriceByInit({
479
+ a,
480
+ b,
481
+ decimalA,
482
+ decimalB,
483
+ curveType
484
+ }) {
485
+ const curve = this.getCurve(curveType);
486
+ return curve.getPoolInitPriceByInit({ a, b, decimalA, decimalB });
487
+ }
488
+ static getPrice({
489
+ poolInfo,
490
+ curveType,
491
+ decimalA,
492
+ decimalB
493
+ }) {
494
+ const curve = this.getCurve(curveType);
495
+ return curve.getPoolPrice({ poolInfo, decimalA, decimalB });
496
+ }
497
+ static getEndPrice({
498
+ poolInfo,
499
+ curveType,
500
+ decimalA,
501
+ decimalB
502
+ }) {
503
+ const curve = this.getCurve(curveType);
504
+ return curve.getPoolPrice({ poolInfo, decimalA, decimalB });
505
+ }
506
+ static getPoolEndPriceReal({
507
+ poolInfo,
508
+ curveType,
509
+ decimalA,
510
+ decimalB
511
+ }) {
512
+ const curve = this.getCurve(curveType);
513
+ return curve.getPoolEndPriceReal({ poolInfo, decimalA, decimalB });
514
+ }
515
+ static checkParam({
516
+ supply,
517
+ totalFundRaising,
518
+ totalSell,
519
+ totalLockedAmount,
520
+ decimalsA,
521
+ decimalsB,
522
+ config,
523
+ migrateType
524
+ }) {
525
+ const supplyBn = new BigNumber3(supply);
526
+ if (decimalsA !== config.decimals) throw Error(`decimals should be ${config.decimals}`);
527
+ if (supplyBn.times(config.maxLockRate).lt(totalLockedAmount))
528
+ throw Error("totalLockedAmount exceeds max lock amount");
529
+ if (new BigNumber3(config.minSupplyA).shiftedBy(decimalsA).gte(supply))
530
+ throw Error("supply less than min supply");
531
+ if (supplyBn.times(config.minSellRateA).gte(totalSell))
532
+ throw Error("totalSell less than min sell");
533
+ if (new BigNumber3(config.minFundRaisingB).shiftedBy(decimalsB).gte(totalFundRaising))
534
+ throw Error("totalFundRaising less than min fund raising");
535
+ const migrateAmountBn = supplyBn.minus(totalSell).minus(totalLockedAmount);
536
+ if (migrateAmountBn.lt(supplyBn.times(config.minMigrateRateA)))
537
+ throw Error("migrateAmount less than min migrate amount");
538
+ const liquidity = migrateAmountBn.times(totalFundRaising).sqrt();
539
+ if (migrateType === "amm") {
540
+ if (liquidity.shiftedBy(-decimalsA).lte(1)) throw Error("insufficient liquidity");
541
+ } else if (migrateType === "cpmm") {
542
+ if (liquidity.lte(100)) throw Error("insufficient liquidity");
543
+ } else {
544
+ throw Error("invalid migrateType");
545
+ }
546
+ }
547
+ static buyExactIn({
548
+ poolInfo,
549
+ amountB,
550
+ protocolFeeRate,
551
+ platformFeeRate,
552
+ curveType,
553
+ shareFeeRate
554
+ }) {
555
+ const feeRate = new BigNumber3(protocolFeeRate).plus(shareFeeRate).plus(platformFeeRate);
556
+ const _totalFee = this.calculateFee({ amount: amountB, feeRate });
557
+ const amountLessFeeB = new BigNumber3(amountB).minus(_totalFee);
558
+ const curve = this.getCurve(curveType);
559
+ const _amountA = curve.buyExactIn({ poolInfo, amount: amountLessFeeB });
560
+ const remainingAmountA = new BigNumber3(poolInfo.totalSellA).minus(poolInfo.realA);
561
+ let amountA;
562
+ let realAmountB;
563
+ let totalFee;
564
+ if (remainingAmountA.lte(_amountA)) {
565
+ amountA = remainingAmountA;
566
+ const amountLessFeeB2 = curve.buyExactOut({
567
+ poolInfo,
568
+ amount: amountA
569
+ });
570
+ realAmountB = this.calculatePreFee({ postFeeAmount: amountLessFeeB2, feeRate });
571
+ totalFee = new BigNumber3(realAmountB).minus(amountLessFeeB2);
572
+ } else {
573
+ amountA = _amountA;
574
+ realAmountB = amountB;
575
+ totalFee = _totalFee;
576
+ }
577
+ const splitFee = this.splitFee({ totalFee, protocolFeeRate, platformFeeRate, shareFeeRate });
578
+ return { amountA, amountB: realAmountB, splitFee };
579
+ }
580
+ static buyExactOut({
581
+ poolInfo,
582
+ amountA,
583
+ protocolFeeRate,
584
+ platformFeeRate,
585
+ curveType,
586
+ shareFeeRate
587
+ }) {
588
+ const remainingAmountA = new BigNumber3(poolInfo.totalSellA).minus(poolInfo.realA);
589
+ let realAmountA = amountA;
590
+ if (remainingAmountA.lte(amountA)) {
591
+ realAmountA = remainingAmountA;
592
+ }
593
+ const curve = this.getCurve(curveType);
594
+ const amountInLessFeeB = curve.buyExactOut({ poolInfo, amount: amountA });
595
+ const totalFeeRate = new BigNumber3(protocolFeeRate).plus(shareFeeRate).plus(platformFeeRate);
596
+ const amountB = this.calculatePreFee({
597
+ postFeeAmount: amountInLessFeeB,
598
+ feeRate: totalFeeRate
599
+ });
600
+ const totalFee = new BigNumber3(amountB).minus(amountInLessFeeB);
601
+ const splitFee = this.splitFee({ totalFee, protocolFeeRate, platformFeeRate, shareFeeRate });
602
+ return { amountA: realAmountA, amountB, splitFee };
603
+ }
604
+ static sellExactIn({
605
+ poolInfo,
606
+ amountA,
607
+ protocolFeeRate,
608
+ platformFeeRate,
609
+ curveType,
610
+ shareFeeRate
611
+ }) {
612
+ const curve = this.getCurve(curveType);
613
+ const amountB = curve.sellExactIn({ poolInfo, amount: amountA });
614
+ const totalFee = this.calculateFee({
615
+ amount: amountB,
616
+ feeRate: new BigNumber3(protocolFeeRate).plus(shareFeeRate).plus(platformFeeRate)
617
+ });
618
+ const splitFee = this.splitFee({ totalFee, protocolFeeRate, platformFeeRate, shareFeeRate });
619
+ return { amountA, amountB: new BigNumber3(amountB).minus(totalFee), splitFee };
620
+ }
621
+ static sellExactOut({
622
+ poolInfo,
623
+ amountB,
624
+ protocolFeeRate,
625
+ platformFeeRate,
626
+ curveType,
627
+ shareFeeRate
628
+ }) {
629
+ const totalFeeRate = new BigNumber3(protocolFeeRate).plus(shareFeeRate).plus(platformFeeRate);
630
+ const amountOutWithFeeB = this.calculatePreFee({
631
+ postFeeAmount: amountB,
632
+ feeRate: totalFeeRate
633
+ });
634
+ if (new BigNumber3(poolInfo.realB).lt(amountOutWithFeeB)) throw Error("Insufficient liquidity");
635
+ const totalFee = new BigNumber3(amountOutWithFeeB).minus(amountB);
636
+ const curve = _Curve.getCurve(curveType);
637
+ const amountA = curve.sellExactOut({ poolInfo, amount: amountOutWithFeeB });
638
+ if (new BigNumber3(amountA).gt(poolInfo.realA)) throw Error("Insufficient liquidity");
639
+ const splitFee = this.splitFee({ totalFee, protocolFeeRate, platformFeeRate, shareFeeRate });
640
+ return { amountA, amountB, splitFee };
641
+ }
642
+ static splitFee({
643
+ totalFee,
644
+ protocolFeeRate,
645
+ platformFeeRate,
646
+ shareFeeRate
647
+ }) {
648
+ const totalFeeBn = new BigNumber3(totalFee);
649
+ const totalFeeRate = new BigNumber3(protocolFeeRate).plus(platformFeeRate).plus(shareFeeRate);
650
+ const platformFee = totalFeeRate.isZero() ? new BigNumber3(0) : totalFeeBn.times(platformFeeRate).div(totalFeeRate);
651
+ const shareFee = totalFeeRate.isZero() ? new BigNumber3(0) : totalFeeBn.times(shareFeeRate).div(totalFeeRate);
652
+ const protocolFee = totalFeeBn.minus(platformFee).minus(shareFee);
653
+ return { platformFee, shareFee, protocolFee };
654
+ }
655
+ static calculateFee({
656
+ amount,
657
+ feeRate
658
+ }) {
659
+ return new BigNumber3(amount).times(feeRate);
660
+ }
661
+ static calculatePreFee({
662
+ postFeeAmount,
663
+ feeRate
664
+ }) {
665
+ if (new BigNumber3(feeRate).isZero()) return postFeeAmount;
666
+ return new BigNumber3(postFeeAmount).div(new BigNumber3(feeRate).plus(1));
667
+ }
668
+ static getCurve(curveType) {
669
+ switch (curveType) {
670
+ case "constant_product" /* CONSTANT_PRODUCT */:
671
+ return ConstantProductCurve;
672
+ case "fixed_price" /* FIXED_PRICE */:
673
+ return FixedPriceCurve;
674
+ case "linear_price" /* LINEAR_PRICE */:
675
+ return LinearPriceCurve;
676
+ }
677
+ }
678
+ };
679
+
680
+ // src/create-token-runtime.ts
681
+ function validateCreateTokenIntent(intent) {
682
+ if (!intent.name.trim()) throw new Error("name required");
683
+ if (!intent.symbol.trim()) throw new Error("symbol required");
684
+ if (intent.symbol.length > 12) throw new Error("symbol too long");
685
+ }
686
+ function createLaunchpadCreateRuntime(options) {
687
+ let current = { status: "idle" };
688
+ const set = (next) => {
689
+ current = next;
690
+ options.onChange?.(next);
691
+ return next;
692
+ };
693
+ return {
694
+ snapshot() {
695
+ return current;
696
+ },
697
+ async submit(intent) {
698
+ set({ status: "validating", intent });
699
+ try {
700
+ validateCreateTokenIntent(intent);
701
+ } catch (error) {
702
+ const err = error instanceof Error ? error : new Error(String(error));
703
+ return set({ status: "failed", intent, error: err });
704
+ }
705
+ let imageUri = intent.imageUri ?? "";
706
+ if (options.upload) {
707
+ set({ status: "uploading", intent });
708
+ try {
709
+ imageUri = await options.upload.upload(intent);
710
+ } catch (error) {
711
+ const err = error instanceof Error ? error : new Error(String(error));
712
+ return set({ status: "failed", intent, error: err });
713
+ }
714
+ }
715
+ if (!options.signer) {
716
+ return set({
717
+ status: "rejected",
718
+ intent,
719
+ error: new Error("missing signer")
720
+ });
721
+ }
722
+ set({ status: "signing", intent: { ...intent, imageUri } });
723
+ let signed;
724
+ try {
725
+ signed = await options.signer.sign(imageUri || intent.symbol);
726
+ } catch (error) {
727
+ const err = error instanceof Error ? error : new Error(String(error));
728
+ return set({ status: "rejected", intent, error: err });
729
+ }
730
+ set({ status: "submitting", intent });
731
+ try {
732
+ const result = await options.execution.submit(signed, intent);
733
+ return set({ status: "succeeded", intent, txHash: result.txHash });
734
+ } catch (error) {
735
+ const err = error instanceof Error ? error : new Error(String(error));
736
+ return set({ status: "failed", intent, error: err });
737
+ }
738
+ }
739
+ };
740
+ }
741
+
742
+ // src/in-memory-launchpad-adapter.ts
743
+ function createInMemoryLaunchpadPorts(options = {}) {
744
+ return {
745
+ upload: {
746
+ async upload() {
747
+ if (options.uploadError) throw options.uploadError;
748
+ return "ipfs://memory";
749
+ }
750
+ },
751
+ signer: {
752
+ async sign(payload) {
753
+ if (options.signError) throw options.signError;
754
+ return `signed:${payload}`;
755
+ }
756
+ },
757
+ execution: {
758
+ async submit() {
759
+ if (options.timeout) throw new Error("submit timeout");
760
+ if (options.submitError) throw options.submitError;
761
+ return { txHash: "tx-memory" };
762
+ }
763
+ }
764
+ };
765
+ }
766
+
767
+ // src/index.ts
768
+ var PACKAGE_NAME = "@liberfi.io/react-launchpad";
769
+ var ReadyContext = createContext(true);
770
+ function LaunchpadProvider({ children }) {
771
+ return createElement(ReadyContext.Provider, { value: true }, children);
772
+ }
773
+ function useLaunchpadReady() {
774
+ return useContext(ReadyContext);
775
+ }
776
+
777
+ export { BaseCurve, ConstantProductCurve, Curve, CurveType, FixedPriceCurve, LaunchPadPlatform, LaunchpadProvider, LinearPriceCurve, PACKAGE_NAME, createInMemoryLaunchpadPorts, createLaunchpadCreateRuntime, useLaunchpadReady, validateCreateTokenIntent };
778
+ //# sourceMappingURL=index.mjs.map
779
+ //# sourceMappingURL=index.mjs.map