@flashnet/sdk 0.3.12-rc.1 → 0.3.12-rc.3

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.
Files changed (39) hide show
  1. package/dist/cjs/src/api/typed-endpoints.d.ts +2 -23
  2. package/dist/cjs/src/api/typed-endpoints.d.ts.map +1 -1
  3. package/dist/cjs/src/api/typed-endpoints.js +3 -33
  4. package/dist/cjs/src/api/typed-endpoints.js.map +1 -1
  5. package/dist/cjs/src/client/FlashnetClient.d.ts +44 -78
  6. package/dist/cjs/src/client/FlashnetClient.d.ts.map +1 -1
  7. package/dist/cjs/src/client/FlashnetClient.js +163 -453
  8. package/dist/cjs/src/client/FlashnetClient.js.map +1 -1
  9. package/dist/cjs/src/types/index.d.ts +17 -223
  10. package/dist/cjs/src/types/index.d.ts.map +1 -1
  11. package/dist/cjs/src/types/index.js +0 -38
  12. package/dist/cjs/src/types/index.js.map +1 -1
  13. package/dist/cjs/src/utils/index.d.ts.map +1 -1
  14. package/dist/cjs/src/utils/index.js +0 -1
  15. package/dist/cjs/src/utils/index.js.map +1 -1
  16. package/dist/cjs/src/utils/intents.d.ts +5 -40
  17. package/dist/cjs/src/utils/intents.d.ts.map +1 -1
  18. package/dist/cjs/src/utils/intents.js +11 -60
  19. package/dist/cjs/src/utils/intents.js.map +1 -1
  20. package/dist/esm/src/api/typed-endpoints.d.ts +2 -23
  21. package/dist/esm/src/api/typed-endpoints.d.ts.map +1 -1
  22. package/dist/esm/src/api/typed-endpoints.js +3 -33
  23. package/dist/esm/src/api/typed-endpoints.js.map +1 -1
  24. package/dist/esm/src/client/FlashnetClient.d.ts +44 -78
  25. package/dist/esm/src/client/FlashnetClient.d.ts.map +1 -1
  26. package/dist/esm/src/client/FlashnetClient.js +164 -454
  27. package/dist/esm/src/client/FlashnetClient.js.map +1 -1
  28. package/dist/esm/src/types/index.d.ts +17 -223
  29. package/dist/esm/src/types/index.d.ts.map +1 -1
  30. package/dist/esm/src/types/index.js +1 -39
  31. package/dist/esm/src/types/index.js.map +1 -1
  32. package/dist/esm/src/utils/index.d.ts.map +1 -1
  33. package/dist/esm/src/utils/index.js +1 -2
  34. package/dist/esm/src/utils/index.js.map +1 -1
  35. package/dist/esm/src/utils/intents.d.ts +5 -40
  36. package/dist/esm/src/utils/intents.d.ts.map +1 -1
  37. package/dist/esm/src/utils/intents.js +12 -58
  38. package/dist/esm/src/utils/intents.js.map +1 -1
  39. package/package.json +1 -1
@@ -250,14 +250,27 @@ class FlashnetClient {
250
250
  /**
251
251
  * Check if wallet has sufficient balance for an operation
252
252
  */
253
- async checkBalance(requirements) {
254
- const balance = await this.getBalance();
253
+ async checkBalance(params) {
254
+ const balance = params.walletBalance ?? (await this.getBalance());
255
+ // Check balance
256
+ const requirements = {
257
+ tokens: new Map(),
258
+ };
259
+ for (const balance of params.balancesToCheck) {
260
+ if (balance.assetAddress === index$1.BTC_ASSET_PUBKEY) {
261
+ requirements.btc = BigInt(balance.amount);
262
+ }
263
+ else {
264
+ requirements.tokens?.set(balance.assetAddress, BigInt(balance.amount));
265
+ }
266
+ }
255
267
  // Check BTC balance
256
268
  if (requirements.btc && balance.balance < requirements.btc) {
257
- return {
258
- sufficient: false,
259
- message: `Insufficient BTC balance. Required: ${requirements.btc} sats, Available: ${balance.balance} sats`,
260
- };
269
+ throw new Error([
270
+ params.errorPrefix ?? "",
271
+ `Insufficient BTC balance. `,
272
+ `Required: ${requirements.btc} sats, Available: ${balance.balance} sats`,
273
+ ].join(""));
261
274
  }
262
275
  // Check token balances
263
276
  if (requirements.tokens) {
@@ -268,14 +281,14 @@ class FlashnetClient {
268
281
  balance.tokenBalances.get(hrKey);
269
282
  const available = effectiveTokenBalance?.balance ?? 0n;
270
283
  if (available < requiredAmount) {
271
- return {
272
- sufficient: false,
273
- message: `Insufficient token balance for ${tokenPubkey}. Required: ${requiredAmount}, Available: ${available}`,
274
- };
284
+ throw new Error([
285
+ params.errorPrefix ?? "",
286
+ `Insufficient token balance for ${tokenPubkey}. `,
287
+ `Required: ${requiredAmount}, Available: ${available}`,
288
+ ].join(""));
275
289
  }
276
290
  }
277
291
  }
278
- return { sufficient: true };
279
292
  }
280
293
  // ===== Pool Operations =====
281
294
  /**
@@ -314,26 +327,19 @@ class FlashnetClient {
314
327
  await this.ensureInitialized();
315
328
  // Check if we need to add initial liquidity
316
329
  if (params.initialLiquidity) {
317
- const requirements = {
318
- tokens: new Map(),
319
- };
320
- if (params.assetAAddress === index$1.BTC_ASSET_PUBKEY) {
321
- requirements.btc = params.initialLiquidity.assetAAmount;
322
- }
323
- else {
324
- requirements.tokens?.set(params.assetAAddress, params.initialLiquidity.assetAAmount);
325
- }
326
- if (params.assetBAddress === index$1.BTC_ASSET_PUBKEY) {
327
- requirements.btc =
328
- (requirements.btc || 0n) + params.initialLiquidity.assetBAmount;
329
- }
330
- else {
331
- requirements.tokens?.set(params.assetBAddress, params.initialLiquidity.assetBAmount);
332
- }
333
- const balanceCheck = await this.checkBalance(requirements);
334
- if (!balanceCheck.sufficient) {
335
- throw new Error(`Insufficient balance for initial liquidity: ${balanceCheck.message}`);
336
- }
330
+ await this.checkBalance({
331
+ balancesToCheck: [
332
+ {
333
+ assetAddress: params.assetAAddress,
334
+ amount: params.initialLiquidity.assetAAmount,
335
+ },
336
+ {
337
+ assetAddress: params.assetBAddress,
338
+ amount: params.initialLiquidity.assetBAmount,
339
+ },
340
+ ],
341
+ errorPrefix: "Insufficient balance for initial liquidity: ",
342
+ });
337
343
  }
338
344
  // Generate intent
339
345
  const nonce = index$2.generateNonce();
@@ -362,101 +368,44 @@ class FlashnetClient {
362
368
  const response = await this.typedApi.createConstantProductPool(request);
363
369
  // Add initial liquidity if specified
364
370
  if (params.initialLiquidity && response.poolId) {
365
- await this.addInitialLiquidity(response.poolId, params.assetAAddress, params.assetBAddress, params.initialLiquidity.assetAAmount.toString(), params.initialLiquidity.assetBAmount.toString(), params.initialLiquidity.assetAMinAmountIn.toString(), params.initialLiquidity.assetBMinAmountIn.toString());
371
+ await this.addInitialLiquidity(response.poolId, params.assetAAddress, params.assetBAddress, params.initialLiquidity.assetAAmount.toString(), params.initialLiquidity.assetBAmount.toString());
366
372
  }
367
373
  return response;
368
374
  }
369
- /**
370
- * Calculates virtual reserves for a bonding curve AMM.
371
- *
372
- * This helper function calculates the initial virtual reserves (`v_A^0`, `v_B^0`)
373
- * based on the bonding curve parameters. These virtual reserves ensure smooth
374
- * pricing and price continuity during graduation to the double-sided phase.
375
- *
376
- * @param params - The parameters for the calculation.
377
- * @param params.initialTokenSupply - The initial supply of Asset A (tokens to be sold).
378
- * @param params.graduationThresholdPct - The percentage of tokens that need to be sold for graduation (20-95%).
379
- * @param params.targetRaise - The target amount of Asset B to raise at graduation.
380
- * @returns An object containing `virtualReserveA`, `virtualReserveB`, and `threshold`.
381
- */
382
- static calculateVirtualReserves(params) {
383
- const supply = Number(params.initialTokenSupply);
384
- const targetB = Number(params.targetRaise);
385
- const lpFrac = 1.0;
386
- // Validate inputs
387
- if (supply <= 0) {
388
- throw new Error("Initial token supply must be positive");
389
- }
390
- if (targetB <= 0) {
391
- throw new Error("Target raise must be positive");
392
- }
393
- const MIN_GRADUATION_THRESHOLD_PCT = 20;
394
- const MAX_GRADUATION_THRESHOLD_PCT = 95;
395
- // Validate graduation threshold is a positive whole number
396
- if (!Number.isInteger(params.graduationThresholdPct) ||
397
- params.graduationThresholdPct <= 0) {
398
- throw new Error("Graduation threshold percentage must be a positive whole number");
399
- }
400
- if (params.graduationThresholdPct < MIN_GRADUATION_THRESHOLD_PCT ||
401
- params.graduationThresholdPct > MAX_GRADUATION_THRESHOLD_PCT) {
402
- throw new Error(`Graduation threshold percentage must be between ${MIN_GRADUATION_THRESHOLD_PCT} and ${MAX_GRADUATION_THRESHOLD_PCT}`);
403
- }
404
- // Calculate graduation parameters
405
- const f = params.graduationThresholdPct / 100;
406
- const g = lpFrac;
407
- // Check feasibility: f - g*(1-f) > 0
408
- const denom = f - g * (1 - f);
409
- if (denom <= 0) {
410
- throw new Error(`Invalid configuration: graduation threshold ${f * 100}% with LP fraction ${g} is infeasible. Need f > g/(1+g)`);
411
- }
412
- // Calculate virtual reserves and round down to integers
413
- const virtualA = Math.floor((supply * f * f) / denom);
414
- const virtualB = Math.floor((targetB * g * (1 - f)) / denom);
415
- return {
416
- virtualReserveA: virtualA,
417
- virtualReserveB: virtualB,
418
- threshold: params.graduationThresholdPct,
419
- };
420
- }
421
375
  /**
422
376
  * Create a single-sided pool with automatic initial deposit
423
377
  *
424
- * This method creates a single-sided pool and automatically handles the initial deposit.
378
+ * This method creates a single-sided pool and by default automatically handles the initial deposit.
425
379
  * The initial reserve amount will be transferred to the pool and confirmed.
426
380
  */
427
381
  async createSingleSidedPool(params) {
428
382
  await this.ensureInitialized();
383
+ // check that assetAPctSoldAtGraduation is between 0 and 100 - no decimals
384
+ if (params.assetAPctSoldAtGraduation < 0 ||
385
+ params.assetAPctSoldAtGraduation > 100) {
386
+ throw new Error(`assetAPctSoldAtGraduation must be between 0 and 100`);
387
+ }
429
388
  if (!params.hostNamespace && params.totalHostFeeRateBps < 10) {
430
389
  throw new Error(`Host fee must be greater than 10 bps when no host namespace is provided`);
431
390
  }
432
- // Clip decimals off reserves before any operations
433
- const clippedAssetAInitialReserve = Math.floor(Number(params.assetAInitialReserve)).toString();
434
- const clippedVirtualReserveA = Math.floor(Number(params.virtualReserveA)).toString();
435
- const clippedVirtualReserveB = Math.floor(Number(params.virtualReserveB)).toString();
436
- // Check balance for initial reserve
437
- const requirements = {
438
- tokens: new Map(),
439
- };
440
- if (params.assetAAddress === index$1.BTC_ASSET_PUBKEY) {
441
- requirements.btc = BigInt(clippedAssetAInitialReserve);
442
- }
443
- else {
444
- requirements.tokens?.set(params.assetAAddress, BigInt(clippedAssetAInitialReserve));
445
- }
446
- const balanceCheck = await this.checkBalance(requirements);
447
- if (!balanceCheck.sufficient) {
448
- throw new Error(`Insufficient balance for pool creation: ${balanceCheck.message}`);
449
- }
391
+ await this.checkBalance({
392
+ balancesToCheck: [
393
+ {
394
+ assetAddress: params.assetAInitialReserve,
395
+ amount: params.assetAInitialReserve,
396
+ },
397
+ ],
398
+ errorPrefix: "Insufficient balance for pool creation: ",
399
+ });
450
400
  // Generate intent
451
401
  const nonce = index$2.generateNonce();
452
402
  const intentMessage = intents.generatePoolInitializationIntentMessage({
453
403
  poolOwnerPublicKey: this.publicKey,
454
404
  assetAAddress: this.toHexTokenIdentifier(params.assetAAddress),
455
405
  assetBAddress: this.toHexTokenIdentifier(params.assetBAddress),
456
- assetAInitialReserve: clippedAssetAInitialReserve,
457
- virtualReserveA: clippedVirtualReserveA,
458
- virtualReserveB: clippedVirtualReserveB,
459
- threshold: params.threshold,
406
+ assetAInitialReserve: params.assetAInitialReserve,
407
+ graduationThresholdPct: params.assetAPctSoldAtGraduation.toString(),
408
+ targetBRaisedAtGraduation: params.targetBRaisedAtGraduation,
460
409
  lpFeeRateBps: params.lpFeeRateBps.toString(),
461
410
  totalHostFeeRateBps: params.totalHostFeeRateBps.toString(),
462
411
  nonce,
@@ -468,10 +417,9 @@ class FlashnetClient {
468
417
  poolOwnerPublicKey: this.publicKey,
469
418
  assetAAddress: this.toHexTokenIdentifier(params.assetAAddress),
470
419
  assetBAddress: this.toHexTokenIdentifier(params.assetBAddress),
471
- assetAInitialReserve: clippedAssetAInitialReserve,
472
- virtualReserveA: clippedVirtualReserveA,
473
- virtualReserveB: clippedVirtualReserveB,
474
- threshold: params.threshold,
420
+ assetAInitialReserve: params.assetAInitialReserve,
421
+ graduationThresholdPct: params.assetAPctSoldAtGraduation,
422
+ targetBRaisedAtGraduation: params.targetBRaisedAtGraduation,
475
423
  lpFeeRateBps: params.lpFeeRateBps.toString(),
476
424
  totalHostFeeRateBps: params.totalHostFeeRateBps.toString(),
477
425
  hostNamespace: params.hostNamespace,
@@ -479,56 +427,29 @@ class FlashnetClient {
479
427
  signature: Buffer.from(signature).toString("hex"),
480
428
  };
481
429
  const createResponse = await this.typedApi.createSingleSidedPool(request);
482
- // If pool creation was successful, handle the initial deposit
483
- if (createResponse.poolId) {
484
- try {
485
- // Transfer initial reserve to the pool using new address encoding
486
- const lpSparkAddress = sparkAddress.encodeSparkAddressNew({
487
- identityPublicKey: createResponse.poolId,
488
- network: this.sparkNetwork,
489
- });
490
- let assetATransferId;
491
- if (params.assetAAddress === index$1.BTC_ASSET_PUBKEY) {
492
- const transfer = await this._wallet.transfer({
493
- amountSats: Number(clippedAssetAInitialReserve),
494
- receiverSparkAddress: lpSparkAddress,
495
- });
496
- assetATransferId = transfer.id;
497
- }
498
- else {
499
- assetATransferId = await this._wallet.transferTokens({
500
- tokenIdentifier: this.toHumanReadableTokenIdentifier(params.assetAAddress),
501
- tokenAmount: BigInt(clippedAssetAInitialReserve),
502
- receiverSparkAddress: lpSparkAddress,
503
- });
504
- }
505
- // Confirm the initial deposit
506
- const confirmNonce = index$2.generateNonce();
507
- const confirmIntentMessage = intents.generatePoolConfirmInitialDepositIntentMessage({
508
- poolOwnerPublicKey: this.publicKey,
509
- lpIdentityPublicKey: createResponse.poolId,
510
- assetASparkTransferId: assetATransferId,
511
- nonce: confirmNonce,
512
- });
513
- const confirmMessageHash = new Uint8Array(await crypto.subtle.digest("SHA-256", confirmIntentMessage));
514
- const confirmSignature = await this._wallet.config.signer.signMessageWithIdentityKey(confirmMessageHash, true);
515
- const confirmRequest = {
516
- poolId: createResponse.poolId,
517
- assetASparkTransferId: assetATransferId,
518
- nonce: confirmNonce,
519
- signature: Buffer.from(confirmSignature).toString("hex"),
520
- poolOwnerPublicKey: this.publicKey,
521
- };
522
- const confirmResponse = await this.typedApi.confirmInitialDeposit(confirmRequest);
523
- if (!confirmResponse.confirmed) {
524
- throw new Error(`Failed to confirm initial deposit: ${confirmResponse.message}`);
525
- }
526
- }
527
- catch (error) {
528
- // If initial deposit fails, we should inform the user
529
- throw new Error(`Pool created with ID ${createResponse.poolId}, but initial deposit failed: ${error instanceof Error ? error.message : String(error)}`);
430
+ if (params.disableInitialDeposit) {
431
+ return createResponse;
432
+ }
433
+ try {
434
+ // Transfer initial reserve to the pool using new address encoding
435
+ const lpSparkAddress = sparkAddress.encodeSparkAddressNew({
436
+ identityPublicKey: createResponse.poolId,
437
+ network: this.sparkNetwork,
438
+ });
439
+ const assetATransferId = await this.transferAsset({
440
+ receiverSparkAddress: lpSparkAddress,
441
+ assetAddress: params.assetAAddress,
442
+ amount: params.assetAInitialReserve,
443
+ });
444
+ const confirmResponse = await this.confirmInitialDeposit(createResponse.poolId, assetATransferId);
445
+ if (!confirmResponse.confirmed) {
446
+ throw new Error(`Failed to confirm initial deposit: ${confirmResponse.message}`);
530
447
  }
531
448
  }
449
+ catch (error) {
450
+ // If initial deposit fails, we should inform the user
451
+ throw new Error(`Pool created with ID ${createResponse.poolId}, but initial deposit failed: ${error instanceof Error ? error.message : String(error)}`);
452
+ }
532
453
  return createResponse;
533
454
  }
534
455
  /**
@@ -570,46 +491,30 @@ class FlashnetClient {
570
491
  */
571
492
  async executeSwap(params) {
572
493
  await this.ensureInitialized();
573
- // Check balance
574
- const requirements = {
575
- tokens: new Map(),
576
- };
577
- if (params.assetInAddress === index$1.BTC_ASSET_PUBKEY) {
578
- requirements.btc = BigInt(params.amountIn);
579
- }
580
- else {
581
- requirements.tokens?.set(params.assetInAddress, BigInt(params.amountIn));
582
- }
583
- const balanceCheck = await this.checkBalance(requirements);
584
- if (!balanceCheck.sufficient) {
585
- throw new Error(`Insufficient balance for swap: ${balanceCheck.message}`);
586
- }
587
494
  // Transfer assets to pool using new address encoding
588
495
  const lpSparkAddress = sparkAddress.encodeSparkAddressNew({
589
496
  identityPublicKey: params.poolId,
590
497
  network: this.sparkNetwork,
591
498
  });
592
- let transferId;
593
- if (params.assetInAddress === index$1.BTC_ASSET_PUBKEY) {
594
- const transfer = await this._wallet.transfer({
595
- amountSats: Number(params.amountIn),
596
- receiverSparkAddress: lpSparkAddress,
597
- });
598
- transferId = transfer.id;
599
- }
600
- else {
601
- transferId = await this._wallet.transferTokens({
602
- tokenIdentifier: this.toHumanReadableTokenIdentifier(params.assetInAddress),
603
- tokenAmount: BigInt(params.amountIn),
604
- receiverSparkAddress: lpSparkAddress,
605
- });
606
- }
499
+ const transferId = await this.transferAsset({
500
+ receiverSparkAddress: lpSparkAddress,
501
+ assetAddress: params.assetInAddress,
502
+ amount: params.amountIn,
503
+ }, "Insufficient balance for swap: ");
504
+ const response = await this.executeSwapIntent({
505
+ ...params,
506
+ transferId,
507
+ });
508
+ return response;
509
+ }
510
+ async executeSwapIntent(params) {
511
+ await this.ensureInitialized();
607
512
  // Generate swap intent
608
513
  const nonce = index$2.generateNonce();
609
514
  const intentMessage = intents.generatePoolSwapIntentMessage({
610
515
  userPublicKey: this.publicKey,
611
516
  lpIdentityPublicKey: params.poolId,
612
- assetInSparkTransferId: transferId,
517
+ assetInSparkTransferId: params.transferId,
613
518
  assetInTokenPublicKey: this.toHexTokenIdentifier(params.assetInAddress),
614
519
  assetOutTokenPublicKey: this.toHexTokenIdentifier(params.assetOutAddress),
615
520
  amountIn: params.amountIn.toString(),
@@ -629,7 +534,7 @@ class FlashnetClient {
629
534
  amountIn: params.amountIn.toString(),
630
535
  maxSlippageBps: params.maxSlippageBps?.toString(),
631
536
  minAmountOut: params.minAmountOut,
632
- assetInSparkTransferId: transferId,
537
+ assetInSparkTransferId: params.transferId,
633
538
  totalIntegratorFeeRateBps: params.integratorFeeRateBps?.toString() || "0",
634
539
  integratorPublicKey: params.integratorPublicKey || "",
635
540
  nonce,
@@ -658,20 +563,6 @@ class FlashnetClient {
658
563
  */
659
564
  async executeRouteSwap(params) {
660
565
  await this.ensureInitialized();
661
- // Check balance for initial asset
662
- const requirements = {
663
- tokens: new Map(),
664
- };
665
- if (params.initialAssetAddress === index$1.BTC_ASSET_PUBKEY) {
666
- requirements.btc = BigInt(params.inputAmount);
667
- }
668
- else {
669
- requirements.tokens?.set(params.initialAssetAddress, BigInt(params.inputAmount));
670
- }
671
- const balanceCheck = await this.checkBalance(requirements);
672
- if (!balanceCheck.sufficient) {
673
- throw new Error(`Insufficient balance for route swap: ${balanceCheck.message}`);
674
- }
675
566
  // Validate hops array
676
567
  if (!params.hops.length) {
677
568
  throw new Error("Route swap requires at least one hop");
@@ -685,21 +576,11 @@ class FlashnetClient {
685
576
  identityPublicKey: firstPoolId,
686
577
  network: this.sparkNetwork,
687
578
  });
688
- let initialTransferId;
689
- if (params.initialAssetAddress === index$1.BTC_ASSET_PUBKEY) {
690
- const transfer = await this._wallet.transfer({
691
- amountSats: Number(params.inputAmount),
692
- receiverSparkAddress: lpSparkAddress,
693
- });
694
- initialTransferId = transfer.id;
695
- }
696
- else {
697
- initialTransferId = await this._wallet.transferTokens({
698
- tokenIdentifier: this.toHumanReadableTokenIdentifier(params.initialAssetAddress),
699
- tokenAmount: BigInt(params.inputAmount),
700
- receiverSparkAddress: lpSparkAddress,
701
- });
702
- }
579
+ const initialTransferId = await this.transferAsset({
580
+ receiverSparkAddress: lpSparkAddress,
581
+ assetAddress: params.initialAssetAddress,
582
+ amount: params.inputAmount,
583
+ }, "Insufficient balance for route swap: ");
703
584
  // Prepare hops for validation
704
585
  const hops = params.hops.map((hop) => ({
705
586
  lpIdentityPublicKey: hop.poolId,
@@ -778,63 +659,23 @@ class FlashnetClient {
778
659
  await this.ensureInitialized();
779
660
  // Get pool details to know which assets we're dealing with
780
661
  const pool = await this.getPool(params.poolId);
781
- // Check balance
782
- const requirements = {
783
- tokens: new Map(),
784
- };
785
- if (pool.assetAAddress === index$1.BTC_ASSET_PUBKEY) {
786
- requirements.btc = BigInt(params.assetAAmount);
787
- }
788
- else {
789
- requirements.tokens?.set(pool.assetAAddress, BigInt(params.assetAAmount));
790
- }
791
- if (pool.assetBAddress === index$1.BTC_ASSET_PUBKEY) {
792
- requirements.btc = (requirements.btc || 0n) + BigInt(params.assetBAmount);
793
- }
794
- else {
795
- requirements.tokens?.set(pool.assetBAddress, BigInt(params.assetBAmount));
796
- }
797
- const balanceCheck = await this.checkBalance(requirements);
798
- if (!balanceCheck.sufficient) {
799
- throw new Error(`Insufficient balance for adding liquidity: ${balanceCheck.message}`);
800
- }
801
662
  // Transfer assets to pool using new address encoding
802
663
  const lpSparkAddress = sparkAddress.encodeSparkAddressNew({
803
664
  identityPublicKey: params.poolId,
804
665
  network: this.sparkNetwork,
805
666
  });
806
- // Transfer asset A
807
- let assetATransferId;
808
- if (pool.assetAAddress === index$1.BTC_ASSET_PUBKEY) {
809
- const transfer = await this._wallet.transfer({
810
- amountSats: Number(params.assetAAmount),
811
- receiverSparkAddress: lpSparkAddress,
812
- });
813
- assetATransferId = transfer.id;
814
- }
815
- else {
816
- assetATransferId = await this._wallet.transferTokens({
817
- tokenIdentifier: this.toHumanReadableTokenIdentifier(pool.assetAAddress),
818
- tokenAmount: BigInt(params.assetAAmount),
667
+ const [assetATransferId, assetBTransferId] = await this.transferAssets([
668
+ {
819
669
  receiverSparkAddress: lpSparkAddress,
820
- });
821
- }
822
- // Transfer asset B
823
- let assetBTransferId;
824
- if (pool.assetBAddress === index$1.BTC_ASSET_PUBKEY) {
825
- const transfer = await this._wallet.transfer({
826
- amountSats: Number(params.assetBAmount),
670
+ assetAddress: pool.assetAAddress,
671
+ amount: params.assetAAmount,
672
+ },
673
+ {
827
674
  receiverSparkAddress: lpSparkAddress,
828
- });
829
- assetBTransferId = transfer.id;
830
- }
831
- else {
832
- assetBTransferId = await this._wallet.transferTokens({
833
- tokenIdentifier: this.toHumanReadableTokenIdentifier(pool.assetBAddress),
834
- tokenAmount: BigInt(params.assetBAmount),
835
- receiverSparkAddress: lpSparkAddress,
836
- });
837
- }
675
+ assetAddress: pool.assetBAddress,
676
+ amount: params.assetBAmount,
677
+ },
678
+ ], "Insufficient balance for adding liquidity: ");
838
679
  // Generate add liquidity intent
839
680
  const nonce = index$2.generateNonce();
840
681
  const intentMessage = intents.generateAddLiquidityIntentMessage({
@@ -844,8 +685,6 @@ class FlashnetClient {
844
685
  assetBSparkTransferId: assetBTransferId,
845
686
  assetAAmount: params.assetAAmount.toString(),
846
687
  assetBAmount: params.assetBAmount.toString(),
847
- assetAMinAmountIn: params.assetAMinAmountIn.toString(),
848
- assetBMinAmountIn: params.assetBMinAmountIn.toString(),
849
688
  nonce,
850
689
  });
851
690
  // Sign intent
@@ -858,8 +697,6 @@ class FlashnetClient {
858
697
  assetBSparkTransferId: assetBTransferId,
859
698
  assetAAmountToAdd: params.assetAAmount.toString(),
860
699
  assetBAmountToAdd: params.assetBAmount.toString(),
861
- assetAMinAmountIn: params.assetAMinAmountIn.toString(),
862
- assetBMinAmountIn: params.assetBMinAmountIn.toString(),
863
700
  nonce,
864
701
  signature: Buffer.from(signature).toString("hex"),
865
702
  };
@@ -969,6 +806,7 @@ class FlashnetClient {
969
806
  const intentMessage = intents.generateWithdrawHostFeesIntentMessage({
970
807
  hostPublicKey: this.publicKey,
971
808
  lpIdentityPublicKey: params.lpIdentityPublicKey,
809
+ assetAAmount: params.assetAAmount,
972
810
  assetBAmount: params.assetBAmount,
973
811
  nonce,
974
812
  });
@@ -977,6 +815,7 @@ class FlashnetClient {
977
815
  const signature = await this._wallet.config.signer.signMessageWithIdentityKey(messageHash, true);
978
816
  const request = {
979
817
  lpIdentityPublicKey: params.lpIdentityPublicKey,
818
+ assetAAmount: params.assetAAmount,
980
819
  assetBAmount: params.assetBAmount,
981
820
  nonce,
982
821
  signature: Buffer.from(signature).toString("hex"),
@@ -1008,6 +847,7 @@ class FlashnetClient {
1008
847
  const intentMessage = intents.generateWithdrawIntegratorFeesIntentMessage({
1009
848
  integratorPublicKey: this.publicKey,
1010
849
  lpIdentityPublicKey: params.lpIdentityPublicKey,
850
+ assetAAmount: params.assetAAmount,
1011
851
  assetBAmount: params.assetBAmount,
1012
852
  nonce,
1013
853
  });
@@ -1017,6 +857,7 @@ class FlashnetClient {
1017
857
  const request = {
1018
858
  integratorPublicKey: this.publicKey,
1019
859
  lpIdentityPublicKey: params.lpIdentityPublicKey,
860
+ assetAAmount: params.assetAAmount,
1020
861
  assetBAmount: params.assetBAmount,
1021
862
  nonce,
1022
863
  signature: Buffer.from(signature).toString("hex"),
@@ -1036,151 +877,6 @@ class FlashnetClient {
1036
877
  await this.ensureInitialized();
1037
878
  return this.typedApi.getIntegratorFees();
1038
879
  }
1039
- // ===== Escrow Operations =====
1040
- /**
1041
- * Creates a new escrow contract.
1042
- * This is the first step in a two-step process: create, then fund.
1043
- * @param params Parameters to create the escrow.
1044
- * @returns The escrow creation response, including the ID and deposit address.
1045
- */
1046
- async createEscrow(params) {
1047
- await this.ensureInitialized();
1048
- const nonce = index$2.generateNonce();
1049
- // The intent message requires a different structure for recipients and conditions
1050
- const intentRecipients = params.recipients.map((r) => ({
1051
- recipientId: r.id,
1052
- amount: r.amount,
1053
- hasClaimed: false, // Default value for creation
1054
- }));
1055
- const intentMessage = intents.generateCreateEscrowIntentMessage({
1056
- creatorPublicKey: this.publicKey,
1057
- assetId: params.assetId,
1058
- assetAmount: params.assetAmount,
1059
- recipients: intentRecipients,
1060
- claimConditions: params.claimConditions, // Assuming API `Condition` is compatible
1061
- abandonHost: params.abandonHost,
1062
- abandonConditions: params.abandonConditions || undefined,
1063
- nonce,
1064
- });
1065
- const messageHash = new Uint8Array(await crypto.subtle.digest("SHA-256", intentMessage));
1066
- const signature = await this._wallet.config.signer.signMessageWithIdentityKey(messageHash, true);
1067
- const request = {
1068
- creatorPublicKey: this.publicKey,
1069
- assetId: params.assetId,
1070
- assetAmount: params.assetAmount,
1071
- recipients: params.recipients,
1072
- claimConditions: params.claimConditions,
1073
- abandonHost: params.abandonHost,
1074
- abandonConditions: params.abandonConditions,
1075
- nonce,
1076
- signature: Buffer.from(signature).toString("hex"),
1077
- };
1078
- const createResponse = await this.typedApi.createEscrow(request);
1079
- const autoFund = params.autoFund !== false;
1080
- if (!autoFund) {
1081
- return createResponse;
1082
- }
1083
- // Auto-fund the escrow
1084
- return this.fundEscrow({
1085
- escrowId: createResponse.escrowId,
1086
- depositAddress: createResponse.depositAddress,
1087
- assetId: params.assetId,
1088
- assetAmount: params.assetAmount,
1089
- });
1090
- }
1091
- /**
1092
- * Funds an escrow contract to activate it.
1093
- * This handles the asset transfer and confirmation in one step.
1094
- * @param params Parameters to fund the escrow, including asset details and deposit address.
1095
- * @returns The funding confirmation response.
1096
- */
1097
- async fundEscrow(params) {
1098
- await this.ensureInitialized();
1099
- // 1. Balance check
1100
- const requirements = {
1101
- tokens: new Map(),
1102
- };
1103
- if (params.assetId === index$1.BTC_ASSET_PUBKEY) {
1104
- requirements.btc = BigInt(params.assetAmount);
1105
- }
1106
- else {
1107
- requirements.tokens?.set(params.assetId, BigInt(params.assetAmount));
1108
- }
1109
- const balanceCheck = await this.checkBalance(requirements);
1110
- if (!balanceCheck.sufficient) {
1111
- throw new Error(`Insufficient balance to fund escrow: ${balanceCheck.message}`);
1112
- }
1113
- // 2. Perform transfer
1114
- const escrowSparkAddress = sparkAddress.encodeSparkAddressNew({
1115
- identityPublicKey: params.depositAddress,
1116
- network: this.sparkNetwork,
1117
- });
1118
- let sparkTransferId;
1119
- if (params.assetId === index$1.BTC_ASSET_PUBKEY) {
1120
- const transfer = await this._wallet.transfer({
1121
- amountSats: Number(params.assetAmount),
1122
- receiverSparkAddress: escrowSparkAddress,
1123
- });
1124
- sparkTransferId = transfer.id;
1125
- }
1126
- else {
1127
- sparkTransferId = await this._wallet.transferTokens({
1128
- tokenIdentifier: this.toHumanReadableTokenIdentifier(params.assetId),
1129
- tokenAmount: BigInt(params.assetAmount),
1130
- receiverSparkAddress: escrowSparkAddress,
1131
- });
1132
- }
1133
- // 3. Generate intent, sign, and call API
1134
- const nonce = index$2.generateNonce();
1135
- const intentMessage = intents.generateFundEscrowIntentMessage({
1136
- escrowId: params.escrowId,
1137
- creatorPublicKey: this.publicKey,
1138
- sparkTransferId,
1139
- nonce,
1140
- });
1141
- const messageHash = new Uint8Array(await crypto.subtle.digest("SHA-256", intentMessage));
1142
- const signature = await this._wallet.config.signer.signMessageWithIdentityKey(messageHash, true);
1143
- const request = {
1144
- escrowId: params.escrowId,
1145
- sparkTransferId,
1146
- nonce,
1147
- signature: Buffer.from(signature).toString("hex"),
1148
- };
1149
- return this.typedApi.fundEscrow(request);
1150
- }
1151
- /**
1152
- * Claims funds from an active escrow contract.
1153
- * The caller must be a valid recipient and all claim conditions must be met.
1154
- * @param params Parameters for the claim.
1155
- * @returns The claim processing response.
1156
- */
1157
- async claimEscrow(params) {
1158
- await this.ensureInitialized();
1159
- const nonce = index$2.generateNonce();
1160
- const intentMessage = intents.generateClaimEscrowIntentMessage({
1161
- escrowId: params.escrowId,
1162
- recipientPublicKey: this.publicKey,
1163
- nonce,
1164
- });
1165
- const messageHash = new Uint8Array(await crypto.subtle.digest("SHA-256", intentMessage));
1166
- const signature = await this._wallet.config.signer.signMessageWithIdentityKey(messageHash, true);
1167
- const request = {
1168
- escrowId: params.escrowId,
1169
- nonce,
1170
- signature: Buffer.from(signature).toString("hex"),
1171
- };
1172
- return this.typedApi.claimEscrow(request);
1173
- }
1174
- /**
1175
- * Retrieves the current state of an escrow contract.
1176
- * This is a read-only operation and does not require authentication.
1177
- * @param escrowId The unique identifier of the escrow.
1178
- * @returns The full state of the escrow.
1179
- */
1180
- async getEscrow(escrowId) {
1181
- await this.ensureInitialized();
1182
- return this.typedApi.getEscrow(escrowId);
1183
- }
1184
880
  // ===== Swap History =====
1185
881
  /**
1186
882
  * Get swaps for a specific pool
@@ -1248,46 +944,64 @@ class FlashnetClient {
1248
944
  return this.typedApi.ping();
1249
945
  }
1250
946
  // ===== Helper Methods =====
947
+ /**
948
+ * Performs asset transfer using generalized asset address for both BTC and tokens.
949
+ */
950
+ async transferAsset(recipient, checkBalanceErrorPrefix) {
951
+ const transferIds = await this.transferAssets([recipient], checkBalanceErrorPrefix);
952
+ return transferIds[0];
953
+ }
954
+ /**
955
+ * Performs asset transfers using generalized asset addresses for both BTC and tokens.
956
+ * Supports optional generic to hardcode recipients length so output list can be typed with same length.
957
+ */
958
+ async transferAssets(recipients, checkBalanceErrorPrefix) {
959
+ if (checkBalanceErrorPrefix) {
960
+ await this.checkBalance({
961
+ balancesToCheck: recipients,
962
+ errorPrefix: checkBalanceErrorPrefix,
963
+ });
964
+ }
965
+ const transferIds = [];
966
+ for (const recipient of recipients) {
967
+ if (recipient.assetAddress === index$1.BTC_ASSET_PUBKEY) {
968
+ const transfer = await this._wallet.transfer({
969
+ amountSats: Number(recipient.amount),
970
+ receiverSparkAddress: recipient.receiverSparkAddress,
971
+ });
972
+ transferIds.push(transfer.id);
973
+ }
974
+ else {
975
+ const transferId = await this._wallet.transferTokens({
976
+ tokenIdentifier: this.toHumanReadableTokenIdentifier(recipient.assetAddress),
977
+ tokenAmount: BigInt(recipient.amount),
978
+ receiverSparkAddress: recipient.receiverSparkAddress,
979
+ });
980
+ transferIds.push(transferId);
981
+ }
982
+ }
983
+ return transferIds;
984
+ }
1251
985
  /**
1252
986
  * Helper method to add initial liquidity after pool creation
1253
987
  */
1254
- async addInitialLiquidity(poolId, assetAAddress, assetBAddress, assetAAmount, assetBAmount, assetAMinAmountIn, assetBMinAmountIn) {
988
+ async addInitialLiquidity(poolId, assetAAddress, assetBAddress, assetAAmount, assetBAmount) {
1255
989
  const lpSparkAddress = sparkAddress.encodeSparkAddressNew({
1256
990
  identityPublicKey: poolId,
1257
991
  network: this.sparkNetwork,
1258
992
  });
1259
- // Transfer asset A
1260
- let assetATransferId;
1261
- if (assetAAddress === index$1.BTC_ASSET_PUBKEY) {
1262
- const transfer = await this._wallet.transfer({
1263
- amountSats: Number(assetAAmount),
993
+ const [assetATransferId, assetBTransferId] = await this.transferAssets([
994
+ {
1264
995
  receiverSparkAddress: lpSparkAddress,
1265
- });
1266
- assetATransferId = transfer.id;
1267
- }
1268
- else {
1269
- assetATransferId = await this._wallet.transferTokens({
1270
- tokenIdentifier: this.toHumanReadableTokenIdentifier(assetAAddress),
1271
- tokenAmount: BigInt(assetAAmount),
1272
- receiverSparkAddress: lpSparkAddress,
1273
- });
1274
- }
1275
- // Transfer asset B
1276
- let assetBTransferId;
1277
- if (assetBAddress === index$1.BTC_ASSET_PUBKEY) {
1278
- const transfer = await this._wallet.transfer({
1279
- amountSats: Number(assetBAmount),
996
+ assetAddress: assetAAddress,
997
+ amount: assetAAmount,
998
+ },
999
+ {
1280
1000
  receiverSparkAddress: lpSparkAddress,
1281
- });
1282
- assetBTransferId = transfer.id;
1283
- }
1284
- else {
1285
- assetBTransferId = await this._wallet.transferTokens({
1286
- tokenIdentifier: this.toHumanReadableTokenIdentifier(assetBAddress),
1287
- tokenAmount: BigInt(assetBAmount),
1288
- receiverSparkAddress: lpSparkAddress,
1289
- });
1290
- }
1001
+ assetAddress: assetBAddress,
1002
+ amount: assetBAmount,
1003
+ },
1004
+ ]);
1291
1005
  // Add liquidity
1292
1006
  const nonce = index$2.generateNonce();
1293
1007
  const intentMessage = intents.generateAddLiquidityIntentMessage({
@@ -1297,8 +1011,6 @@ class FlashnetClient {
1297
1011
  assetBSparkTransferId: assetBTransferId,
1298
1012
  assetAAmount: assetAAmount.toString(),
1299
1013
  assetBAmount: assetBAmount.toString(),
1300
- assetAMinAmountIn: assetAMinAmountIn.toString(),
1301
- assetBMinAmountIn: assetBMinAmountIn.toString(),
1302
1014
  nonce,
1303
1015
  });
1304
1016
  const messageHash = new Uint8Array(await crypto.subtle.digest("SHA-256", intentMessage));
@@ -1310,8 +1022,6 @@ class FlashnetClient {
1310
1022
  assetBSparkTransferId: assetBTransferId,
1311
1023
  assetAAmountToAdd: assetAAmount.toString(),
1312
1024
  assetBAmountToAdd: assetBAmount.toString(),
1313
- assetAMinAmountIn: assetAMinAmountIn.toString(),
1314
- assetBMinAmountIn: assetBMinAmountIn.toString(),
1315
1025
  nonce,
1316
1026
  signature: Buffer.from(signature).toString("hex"),
1317
1027
  };