@riftresearch/sdk 0.17.0 → 0.19.0

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/README.md CHANGED
@@ -42,14 +42,14 @@ const ethereumPepe = createCurrency({
42
42
 
43
43
  // Get a quote
44
44
  const { quote, executeSwap } = await sdk.getQuote({
45
- from: Currencies.Ethereum.USDC,
46
- to: Currencies.Bitcoin.BTC,
45
+ fromAsset: Currencies.Ethereum.USDC,
46
+ toAsset: Currencies.Bitcoin.BTC,
47
47
  amount: '100000000', // 100 USDC (6 decimals)
48
48
  mode: 'exact_input',
49
49
  slippageBps: 100, // 1%
50
50
  })
51
51
 
52
- console.log(`Swapping ${quote.from.expected} USDC for ${quote.to.expected} sats`)
52
+ console.log(`Swapping ${quote.fromAsset.expected} USDC for ${quote.toAsset.expected} sats`)
53
53
  console.log(`Fees: $${quote.fees.totalUsd.toFixed(2)}`)
54
54
 
55
55
  // Execute the swap
@@ -96,8 +96,8 @@ const walletClient = createWalletClient({ account, chain: base, transport: http(
96
96
  const sdk = new RiftSdk({ integratorName: 'my-app' })
97
97
 
98
98
  const result = await sdk.createLimitOrder({
99
- from: Currencies.Base.USDC,
100
- to: Currencies.Bitcoin.BTC,
99
+ fromAsset: Currencies.Base.USDC,
100
+ toAsset: Currencies.Bitcoin.BTC,
101
101
  pricing: {
102
102
  sellAmount: '1000000', // 1 USDC (6 decimals)
103
103
  buyAmount: '2500', // 2500 sats
package/dist/index.d.ts CHANGED
@@ -108,9 +108,13 @@ interface QuoteResponseBase {
108
108
  interface ExactInputQuoteResponse extends QuoteResponseBase {
109
109
  mode: "exact_input";
110
110
  /** The exact input amount specified by the user */
111
- from: SpecifiedAmount;
111
+ fromAsset: SpecifiedAmount;
112
+ /** @deprecated Temporary legacy alias for fromAsset */
113
+ from?: SpecifiedAmount;
112
114
  /** The calculated output amount with slippage bound */
113
- to: CalculatedOutputAmount;
115
+ toAsset: CalculatedOutputAmount;
116
+ /** @deprecated Temporary legacy alias for toAsset */
117
+ to?: CalculatedOutputAmount;
114
118
  }
115
119
  /**
116
120
  * Quote response for exact_output mode.
@@ -119,9 +123,13 @@ interface ExactInputQuoteResponse extends QuoteResponseBase {
119
123
  interface ExactOutputQuoteResponse extends QuoteResponseBase {
120
124
  mode: "exact_output";
121
125
  /** The calculated input amount with slippage bound */
122
- from: CalculatedInputAmount;
126
+ fromAsset: CalculatedInputAmount;
127
+ /** @deprecated Temporary legacy alias for fromAsset */
128
+ from?: CalculatedInputAmount;
123
129
  /** The exact output amount specified by the user */
124
- to: SpecifiedAmount;
130
+ toAsset: SpecifiedAmount;
131
+ /** @deprecated Temporary legacy alias for toAsset */
132
+ to?: SpecifiedAmount;
125
133
  }
126
134
  /**
127
135
  * Discriminated union of quote responses.
@@ -374,9 +382,9 @@ type RiftOrdersPage = AnalyticsOrdersResponse;
374
382
  type OrderTypeFilter = "market" | "limit";
375
383
  interface QuoteParameters {
376
384
  /** The currency to swap from */
377
- from: Currency;
385
+ fromAsset: Currency;
378
386
  /** The currency to swap to */
379
- to: Currency;
387
+ toAsset: Currency;
380
388
  /** Amount in smallest unit (sats for BTC, wei for ETH, etc.) */
381
389
  amount: string;
382
390
  /** Whether amount refers to input or output */
@@ -411,9 +419,13 @@ interface QuoteResultBase {
411
419
  interface ExactInputQuoteResult extends QuoteResultBase {
412
420
  mode: "exact_input";
413
421
  /** The exact input amount specified by the user */
414
- from: SpecifiedAmount;
422
+ fromAsset: SpecifiedAmount;
423
+ /** @deprecated Temporary legacy alias for fromAsset */
424
+ from?: SpecifiedAmount;
415
425
  /** The calculated output amount with slippage bound */
416
- to: CalculatedOutputAmount;
426
+ toAsset: CalculatedOutputAmount;
427
+ /** @deprecated Temporary legacy alias for toAsset */
428
+ to?: CalculatedOutputAmount;
417
429
  }
418
430
  /**
419
431
  * Quote result for exact_output mode.
@@ -422,9 +434,13 @@ interface ExactInputQuoteResult extends QuoteResultBase {
422
434
  interface ExactOutputQuoteResult extends QuoteResultBase {
423
435
  mode: "exact_output";
424
436
  /** The calculated input amount with slippage bound */
425
- from: CalculatedInputAmount;
437
+ fromAsset: CalculatedInputAmount;
438
+ /** @deprecated Temporary legacy alias for fromAsset */
439
+ from?: CalculatedInputAmount;
426
440
  /** The exact output amount specified by the user */
427
- to: SpecifiedAmount;
441
+ toAsset: SpecifiedAmount;
442
+ /** @deprecated Temporary legacy alias for toAsset */
443
+ to?: SpecifiedAmount;
428
444
  }
429
445
  /**
430
446
  * Discriminated union of quote results.
@@ -435,6 +451,14 @@ interface GetQuoteResult {
435
451
  quote: QuoteResult;
436
452
  executeSwap: <chain extends Chain2 | undefined = Chain2 | undefined>(context: ExecuteSwapOptions<chain>) => Promise<SwapResult>;
437
453
  }
454
+ type LiquidityLimit = {
455
+ from: Currency;
456
+ to: Currency;
457
+ maxInput: string;
458
+ };
459
+ type LiquidityResponse = {
460
+ limits: LiquidityLimit[];
461
+ };
438
462
  interface SwapResult {
439
463
  orderId: string;
440
464
  status: AnalyticsOrderStatus;
@@ -485,8 +509,8 @@ type SendBitcoinFn = (params: {
485
509
  }) => Promise<void>;
486
510
  type ExecuteSwapStepType = "approval" | "transaction" | "signature";
487
511
  type CreateLimitOrderOptions<chain extends Chain2 | undefined = Chain2 | undefined> = ExecuteSwapContext<chain> & {
488
- from: Currency;
489
- to: Currency;
512
+ fromAsset: Currency;
513
+ toAsset: Currency;
490
514
  pricing: LimitPricing;
491
515
  destinationAddress: string;
492
516
  refundAddress?: string;
@@ -546,19 +570,21 @@ declare class RiftSdk {
546
570
  constructor(options: RiftSdkOptions);
547
571
  private logDebug;
548
572
  private unwrapEdenResult;
573
+ private normalizeQuoteParameters;
574
+ private normalizeLimitOrderOptions;
549
575
  /**
550
576
  * Get a quote for a swap and return a function to execute it.
551
577
  *
552
578
  * @example
553
579
  * const { quote, executeSwap } = await sdk.getQuote({
554
- * from: Currencies.Base.CBBTC,
555
- * to: Currencies.Bitcoin.BTC,
580
+ * fromAsset: Currencies.Base.CBBTC,
581
+ * toAsset: Currencies.Bitcoin.BTC,
556
582
  * amount: '100000000', // 1 cbBTC
557
583
  * mode: 'exact_input',
558
584
  * slippageBps: 100, // 1%
559
585
  * })
560
586
  *
561
- * console.log(`You'll receive: ${quote.to.expected} sats`)
587
+ * console.log(`You'll receive: ${quote.toAsset.expected} sats`)
562
588
  * const swap = await executeSwap({
563
589
  * destinationAddress: 'bc1q...',
564
590
  * publicClient,
@@ -618,6 +644,10 @@ declare class RiftSdk {
618
644
  */
619
645
  getOrders(options?: GetOrdersOptions): Promise<RiftOrdersPage>;
620
646
  /**
647
+ * Get the current exact-input liquidity limits exposed by the swap router.
648
+ */
649
+ getLiquidity(): Promise<LiquidityResponse>;
650
+ /**
621
651
  * Cancel a supported limit order through the swap router.
622
652
  *
623
653
  * The SDK first requests the backend-specific typed-data payload from the
@@ -627,4 +657,4 @@ declare class RiftSdk {
627
657
  cancelOrder<chain extends Chain3 | undefined = Chain3 | undefined>(options: CancelOrderOptions<chain>): Promise<CancelOrderResult>;
628
658
  }
629
659
  declare function createRiftSdk(options: RiftSdkOptions): RiftSdk;
630
- export { getSupportedModes, detectRoute, createRiftSdk, createCurrency, TokenIdentifier, AnalyticsOrderStatus as SwapStatus, SwapRouterApiError, SwapRoute, SwapResult, SwapResponse, SupportedModes, SendBitcoinFn, RiftSwap, RiftSdkOptions, RiftSdk, RiftOrdersPage, QuoteResult, QuoteParameters, OrderTypeFilter, NativeToken, LimitPricing, GetQuoteResult, GetOrdersOptions, ExecutionStep, ExecutionAction, ExecuteSwapStepType, ExecuteSwapOptions, ExecuteSwapOnExecuteStepCallback, EvmChain, EvmCallStep, EvmCallKind, Erc20Token, Currency, Currencies, CreateLimitOrderOptions, Chain, CancelOrderResult, CancelOrderOptions, BtcTransferStep, BtcTransferKind, BitcoinChain };
660
+ export { getSupportedModes, detectRoute, createRiftSdk, createCurrency, TokenIdentifier, AnalyticsOrderStatus as SwapStatus, SwapRouterApiError, SwapRoute, SwapResult, SwapResponse, SupportedModes, SendBitcoinFn, RiftSwap, RiftSdkOptions, RiftSdk, RiftOrdersPage, QuoteResult, QuoteParameters, OrderTypeFilter, NativeToken, LiquidityResponse, LiquidityLimit, LimitPricing, GetQuoteResult, GetOrdersOptions, ExecutionStep, ExecutionAction, ExecuteSwapStepType, ExecuteSwapOptions, ExecuteSwapOnExecuteStepCallback, EvmChain, EvmCallStep, EvmCallKind, Erc20Token, Currency, Currencies, CreateLimitOrderOptions, Chain, CancelOrderResult, CancelOrderOptions, BtcTransferStep, BtcTransferKind, BitcoinChain };
package/dist/index.js CHANGED
@@ -263,6 +263,19 @@ function postJson(baseUrl, path, body) {
263
263
  }
264
264
  function createClient(baseUrl) {
265
265
  const normalizedBaseUrl = baseUrl.replace(/\/$/, "");
266
+ const toCreateMarketOrderRequest = (body) => ({
267
+ orderType: "market",
268
+ quoteId: body.id,
269
+ ...body.senderAddress !== undefined ? { senderAddress: body.senderAddress } : {},
270
+ destinationAddress: body.destinationAddress,
271
+ refundAddress: body.refundAddress,
272
+ ...body.integratorName !== undefined ? { integratorName: body.integratorName } : {},
273
+ ...body.approvalMode !== undefined ? { approvalMode: body.approvalMode } : {}
274
+ });
275
+ const toCreateLimitOrderRequest = (body) => ({
276
+ orderType: "limit",
277
+ ...body
278
+ });
266
279
  const swap = (params) => {
267
280
  const orderId = encodeURIComponent(params.orderId);
268
281
  return {
@@ -281,17 +294,21 @@ function createClient(baseUrl) {
281
294
  }
282
295
  };
283
296
  };
284
- swap.post = (body) => postJson(normalizedBaseUrl, "/order/market", body);
297
+ swap.post = (body) => postJson(normalizedBaseUrl, "/order", toCreateMarketOrderRequest(body));
285
298
  const market = {
286
- post: (body) => postJson(normalizedBaseUrl, "/order/market", body)
299
+ post: (body) => postJson(normalizedBaseUrl, "/order", toCreateMarketOrderRequest(body))
287
300
  };
288
301
  const limit = {
289
- post: (body) => postJson(normalizedBaseUrl, "/order/limit", body)
302
+ post: (body) => postJson(normalizedBaseUrl, "/order", toCreateLimitOrderRequest(body))
303
+ };
304
+ const liquidity = {
305
+ get: () => get(normalizedBaseUrl, "/liquidity")
290
306
  };
291
307
  const orders = {
292
308
  get: (query) => get(normalizedBaseUrl, `/orders${buildQueryString(query)}`)
293
309
  };
294
310
  return {
311
+ liquidity,
295
312
  quote: {
296
313
  post: (body) => postJson(normalizedBaseUrl, "/quote", body)
297
314
  },
@@ -376,45 +393,72 @@ class RiftSdk {
376
393
  }
377
394
  throw new SwapRouterApiError(message, status, value);
378
395
  }
396
+ normalizeQuoteParameters(params) {
397
+ const legacy = params;
398
+ const fromAsset = params.fromAsset ?? legacy.from;
399
+ const toAsset = params.toAsset ?? legacy.to;
400
+ if (!fromAsset || !toAsset) {
401
+ throw new Error("Quote parameters must include fromAsset/toAsset or legacy from/to.");
402
+ }
403
+ return {
404
+ ...params,
405
+ fromAsset,
406
+ toAsset
407
+ };
408
+ }
409
+ normalizeLimitOrderOptions(options) {
410
+ const legacy = options;
411
+ const fromAsset = options.fromAsset ?? legacy.from;
412
+ const toAsset = options.toAsset ?? legacy.to;
413
+ if (!fromAsset || !toAsset) {
414
+ throw new Error("Limit order options must include fromAsset/toAsset or legacy from/to.");
415
+ }
416
+ return {
417
+ ...options,
418
+ fromAsset,
419
+ toAsset
420
+ };
421
+ }
379
422
  async getQuote(params) {
423
+ params = this.normalizeQuoteParameters(params);
380
424
  if (!Number.isFinite(params.slippageBps) || !Number.isInteger(params.slippageBps)) {
381
425
  throw new Error("slippageBps must be an integer number of basis points");
382
426
  }
383
427
  if (params.slippageBps < 0 || params.slippageBps > 1e4) {
384
428
  throw new Error("slippageBps must be between 0 and 10000");
385
429
  }
386
- const route = detectRoute(params.from, params.to);
430
+ const route = detectRoute(params.fromAsset, params.toAsset);
387
431
  const quoteRequest = {
388
432
  type: params.mode === "exact_input" ? "EXACT_INPUT" : "EXACT_OUTPUT",
389
- from: params.from,
390
- to: params.to,
433
+ fromAsset: params.fromAsset,
434
+ toAsset: params.toAsset,
391
435
  amount: params.amount,
392
436
  slippageBps: params.slippageBps
393
437
  };
394
438
  const riftQuote = this.unwrapEdenResult(await this.riftClient.quote.post(quoteRequest));
395
439
  const quote = this.buildQuoteResult(riftQuote, params);
396
- const isChained = route.type === "direct_rift" && route.direction === "from_btc" && !isCbBtc(params.to);
440
+ const isChained = route.type === "direct_rift" && route.direction === "from_btc" && !isCbBtc(params.toAsset);
397
441
  return {
398
442
  quote,
399
443
  executeSwap: async (context) => {
400
444
  if (!context?.destinationAddress) {
401
445
  throw new Error("destinationAddress is required to execute swap");
402
446
  }
403
- if (params.from.chain.kind === "BITCOIN" && !context.refundAddress) {
447
+ if (params.fromAsset.chain.kind === "BITCOIN" && !context.refundAddress) {
404
448
  throw new Error("refundAddress is required for BTC swaps (Bitcoin refund address)");
405
449
  }
406
450
  this.logDebug("executeSwap called", {
407
451
  route: route.type,
408
452
  mode: params.mode,
409
- from: params.from,
410
- to: params.to,
453
+ fromAsset: params.fromAsset,
454
+ toAsset: params.toAsset,
411
455
  amount: params.amount
412
456
  });
413
457
  const refundAddress = context.refundAddress ?? this.getRefundAddress(params, context);
414
458
  this.logDebug("resolved refund address", { refundAddress });
415
459
  if (this.preflightCheckBalances) {
416
460
  this.logDebug("running preflight balance check");
417
- await this.assertSufficientBalance(params.from, quote.from.expected, context);
461
+ await this.assertSufficientBalance(params.fromAsset, quote.fromAsset.expected, context);
418
462
  }
419
463
  return this.executeOrderFlow({
420
464
  context,
@@ -422,7 +466,7 @@ class RiftSdk {
422
466
  chained: isChained,
423
467
  createOrder: async () => {
424
468
  this.logDebug("creating market order", { quoteId: riftQuote.id });
425
- const senderAddress = params.from.chain.kind === "EVM" ? this.getAddress(context) : undefined;
469
+ const senderAddress = params.fromAsset.chain.kind === "EVM" ? this.getAddress(context) : undefined;
426
470
  return this.unwrapEdenResult(await this.riftClient.market.post({
427
471
  id: riftQuote.id,
428
472
  ...senderAddress ? { senderAddress } : {},
@@ -437,15 +481,16 @@ class RiftSdk {
437
481
  };
438
482
  }
439
483
  async createLimitOrder(options) {
484
+ options = this.normalizeLimitOrderOptions(options);
440
485
  if (!options?.destinationAddress) {
441
486
  throw new Error("destinationAddress is required to create a limit order");
442
487
  }
443
- if (options.from.token.kind === "TOKEN") {
444
- if (!isAddress(options.from.token.address)) {
488
+ if (options.fromAsset.token.kind === "TOKEN") {
489
+ if (!isAddress(options.fromAsset.token.address)) {
445
490
  throw new Error("from.token.address must be a valid EVM token address");
446
491
  }
447
492
  }
448
- if (options.to.token.kind === "TOKEN" && !isAddress(options.to.token.address)) {
493
+ if (options.toAsset.token.kind === "TOKEN" && !isAddress(options.toAsset.token.address)) {
449
494
  throw new Error("to.token.address must be a valid EVM token address");
450
495
  }
451
496
  this.assertPositiveIntegerString(options.pricing.buyAmount, "pricing.buyAmount");
@@ -455,14 +500,14 @@ class RiftSdk {
455
500
  }
456
501
  let refundAddress;
457
502
  let senderAddress;
458
- if (options.from.chain.kind === "BITCOIN") {
459
- if (options.from.token.kind !== "NATIVE") {
503
+ if (options.fromAsset.chain.kind === "BITCOIN") {
504
+ if (options.fromAsset.token.kind !== "NATIVE") {
460
505
  throw new Error("BTC-start limit orders must use native BTC as the input");
461
506
  }
462
507
  if (!options.refundAddress) {
463
508
  throw new Error("refundAddress is required for BTC-start limit orders (Bitcoin refund address).");
464
509
  }
465
- if (isCbBtc(options.to)) {
510
+ if (isCbBtc(options.toAsset)) {
466
511
  throw new Error("BTC -> cbBTC limit orders are not supported");
467
512
  }
468
513
  refundAddress = options.refundAddress;
@@ -473,31 +518,31 @@ class RiftSdk {
473
518
  throw new Error("refundAddress must be a valid EVM address for EVM-start limit orders");
474
519
  }
475
520
  }
476
- if (options.to.chain.kind === "BITCOIN") {
477
- if (options.from.chain.kind !== "EVM") {
521
+ if (options.toAsset.chain.kind === "BITCOIN") {
522
+ if (options.fromAsset.chain.kind !== "EVM") {
478
523
  throw new Error("Bitcoin-payout limit orders require an EVM source currency.");
479
524
  }
480
- if (isCbBtc(options.from)) {
525
+ if (isCbBtc(options.fromAsset)) {
481
526
  throw new Error("cbBTC -> BTC limit orders are not supported");
482
527
  }
483
528
  } else {
484
529
  if (!isAddress(options.destinationAddress)) {
485
530
  throw new Error("destinationAddress must be a valid EVM address for EVM-destination limit orders");
486
531
  }
487
- if (options.to.chain.chainId !== 1 && options.to.chain.chainId !== 8453) {
488
- throw new Error(`Unsupported limit order chainId: ${options.to.chain.chainId}. Expected 1 or 8453.`);
532
+ if (options.toAsset.chain.chainId !== 1 && options.toAsset.chain.chainId !== 8453) {
533
+ throw new Error(`Unsupported limit order chainId: ${options.toAsset.chain.chainId}. Expected 1 or 8453.`);
489
534
  }
490
- if (options.from.chain.kind === "EVM") {
491
- if (options.from.chain.chainId !== options.to.chain.chainId) {
535
+ if (options.fromAsset.chain.kind === "EVM") {
536
+ if (options.fromAsset.chain.chainId !== options.toAsset.chain.chainId) {
492
537
  throw new Error("EVM-start limit orders currently require from/to on the same EVM chain.");
493
538
  }
494
539
  }
495
540
  }
496
541
  this.logDebug("resolved limit order refund address", { refundAddress });
497
- const route = detectRoute(options.from, options.to);
498
- if (this.preflightCheckBalances && options.from.chain.kind === "EVM") {
542
+ const route = detectRoute(options.fromAsset, options.toAsset);
543
+ if (this.preflightCheckBalances && options.fromAsset.chain.kind === "EVM") {
499
544
  this.logDebug("running limit-order preflight balance check");
500
- await this.assertSufficientBalance(options.from, options.pricing.sellAmount, options);
545
+ await this.assertSufficientBalance(options.fromAsset, options.pricing.sellAmount, options);
501
546
  }
502
547
  return this.executeOrderFlow({
503
548
  context: options,
@@ -505,8 +550,8 @@ class RiftSdk {
505
550
  chained: false,
506
551
  createOrder: async () => {
507
552
  const request2 = {
508
- from: options.from,
509
- to: options.to,
553
+ fromAsset: options.fromAsset,
554
+ toAsset: options.toAsset,
510
555
  ...senderAddress ? { senderAddress } : {},
511
556
  pricing: options.pricing,
512
557
  destinationAddress: options.destinationAddress,
@@ -516,7 +561,7 @@ class RiftSdk {
516
561
  integratorName: this.integratorName
517
562
  };
518
563
  this.logDebug("creating limit order", {
519
- to: request2.to,
564
+ toAsset: request2.toAsset,
520
565
  pricing: request2.pricing
521
566
  });
522
567
  return this.unwrapEdenResult(await this.riftClient.limit.post(request2));
@@ -833,8 +878,10 @@ class RiftSdk {
833
878
  return {
834
879
  mode: "exact_input",
835
880
  quoteId: riftQuote.id,
836
- from: riftQuote.from,
837
- to: riftQuote.to,
881
+ fromAsset: riftQuote.fromAsset,
882
+ from: riftQuote.fromAsset,
883
+ toAsset: riftQuote.toAsset,
884
+ to: riftQuote.toAsset,
838
885
  fees: riftQuote.fees,
839
886
  expiresAt: new Date(riftQuote.expiresAt)
840
887
  };
@@ -842,8 +889,10 @@ class RiftSdk {
842
889
  return {
843
890
  mode: "exact_output",
844
891
  quoteId: riftQuote.id,
845
- from: riftQuote.from,
846
- to: riftQuote.to,
892
+ fromAsset: riftQuote.fromAsset,
893
+ from: riftQuote.fromAsset,
894
+ toAsset: riftQuote.toAsset,
895
+ to: riftQuote.toAsset,
847
896
  fees: riftQuote.fees,
848
897
  expiresAt: new Date(riftQuote.expiresAt)
849
898
  };
@@ -959,7 +1008,7 @@ class RiftSdk {
959
1008
  return account.address;
960
1009
  }
961
1010
  getRefundAddress(params, context) {
962
- if (params.from.chain.kind === "BITCOIN") {
1011
+ if (params.fromAsset.chain.kind === "BITCOIN") {
963
1012
  throw new Error("refundAddress is required for BTC swaps (Bitcoin refund address)");
964
1013
  }
965
1014
  return this.getAddress(context);
@@ -1022,6 +1071,9 @@ class RiftSdk {
1022
1071
  async getOrders(options) {
1023
1072
  return this.unwrapEdenResult(await this.riftClient.orders.get(options));
1024
1073
  }
1074
+ async getLiquidity() {
1075
+ return this.unwrapEdenResult(await this.riftClient.liquidity.get());
1076
+ }
1025
1077
  async cancelOrder(options) {
1026
1078
  const walletClient = options.walletClient;
1027
1079
  const account = walletClient.account;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riftresearch/sdk",
3
- "version": "0.17.0",
3
+ "version": "0.19.0",
4
4
  "description": "SDK for swapping between bitcoin and evm chains",
5
5
  "license": "MIT",
6
6
  "files": [