@riftresearch/sdk 0.9.0 → 0.11.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/dist/index.d.ts CHANGED
@@ -57,7 +57,6 @@ interface CalculatedInputAmount {
57
57
  /** Maximum input required after slippage (optional - not all routes provide this) */
58
58
  maximum?: U256;
59
59
  }
60
- type QuoteQuality = "fast" | "optimal";
61
60
  /**
62
61
  * A single fee component with amount in native currency and USD equivalent.
63
62
  */
@@ -175,6 +174,8 @@ interface EvmCallStep {
175
174
  spenderAddress?: string;
176
175
  /** Amount for display/verification (for approval, transfer_evm) */
177
176
  amount?: U256;
177
+ /** DEX execution venue label (for dex_swap, e.g. "spandex.paraswap") */
178
+ venue?: string;
178
179
  }
179
180
  /**
180
181
  * BTC Transfer step - send Bitcoin to an address.
@@ -296,8 +297,6 @@ interface QuoteParameters {
296
297
  * `minimum`/`maximum` bounds; direct OTC routes may ignore it.
297
298
  */
298
299
  slippageBps: number;
299
- /** Optional DEX quote quality target for DEX-backed routes. */
300
- quoteQuality?: QuoteQuality;
301
300
  /**
302
301
  * Approval amount strategy for ERC20 swaps.
303
302
  * - "full" (default): approve max uint256
@@ -455,6 +454,8 @@ declare class RiftSdk {
455
454
  private executeBtcTransferStep;
456
455
  private buildQuoteResult;
457
456
  private buildSwapResult;
457
+ private buildDexSwapRevertMessage;
458
+ private resolveDexVenueLabel;
458
459
  private assertSufficientBalance;
459
460
  private getAddress;
460
461
  private getRefundAddress;
@@ -469,4 +470,4 @@ declare class RiftSdk {
469
470
  getSwapStatus(swapId: string): Promise<SwapStatusResponse>;
470
471
  }
471
472
  declare function createRiftSdk(options: RiftSdkOptions): RiftSdk;
472
- export { getSupportedModes, detectRoute, createRiftSdk, createCurrency, TokenIdentifier, SwapStatus, SwapRouterApiError, SwapRoute, SwapResult, SwapResponse, SupportedModes, SendBitcoinFn, RiftSwap, RiftSdkOptions, RiftSdk, QuoteResult, QuoteQuality, QuoteParameters, NativeToken, GetQuoteResult, ExecutionStep, ExecutionAction, ExecuteSwapStepType, ExecuteSwapOptions, ExecuteSwapOnExecuteStepCallback, EvmChain, EvmCallStep, EvmCallKind, Erc20Token, Currency, Currencies, Chain, BtcTransferStep, BtcTransferKind, BitcoinChain };
473
+ export { getSupportedModes, detectRoute, createRiftSdk, createCurrency, TokenIdentifier, SwapStatus, SwapRouterApiError, SwapRoute, SwapResult, SwapResponse, SupportedModes, SendBitcoinFn, RiftSwap, RiftSdkOptions, RiftSdk, QuoteResult, QuoteParameters, NativeToken, GetQuoteResult, ExecutionStep, ExecutionAction, ExecuteSwapStepType, ExecuteSwapOptions, ExecuteSwapOnExecuteStepCallback, EvmChain, EvmCallStep, EvmCallKind, Erc20Token, Currency, Currencies, Chain, BtcTransferStep, BtcTransferKind, BitcoinChain };
package/dist/index.js CHANGED
@@ -218,8 +218,7 @@ class RiftSdk {
218
218
  from: params.from,
219
219
  to: params.to,
220
220
  amount: params.amount,
221
- slippageBps: params.slippageBps,
222
- quoteQuality: params.quoteQuality
221
+ slippageBps: params.slippageBps
223
222
  };
224
223
  const riftQuote = this.unwrapEdenResult(await this.riftClient.quote.post(quoteRequest));
225
224
  const quote = this.buildQuoteResult(riftQuote, params);
@@ -268,7 +267,7 @@ class RiftSdk {
268
267
  kind: "kind" in step ? step.kind : undefined,
269
268
  chainId: "chainId" in step ? step.chainId : undefined
270
269
  });
271
- const result = await this.executeStep(step, context, swapResponse.swapId);
270
+ const result = await this.executeStep(step, context, swapResponse.swapId, route);
272
271
  this.logDebug("step completed", {
273
272
  stepId: step.id,
274
273
  txHash: result.txHash
@@ -300,15 +299,15 @@ class RiftSdk {
300
299
  }
301
300
  };
302
301
  }
303
- async executeStep(step, context, swapId) {
302
+ async executeStep(step, context, swapId, route) {
304
303
  switch (step.action) {
305
304
  case "evm_call":
306
- return this.executeEvmCallStep(step, context, swapId);
305
+ return this.executeEvmCallStep(step, context, swapId, route);
307
306
  case "btc_transfer":
308
307
  return this.executeBtcTransferStep(step, context);
309
308
  }
310
309
  }
311
- async executeEvmCallStep(step, context, swapId) {
310
+ async executeEvmCallStep(step, context, swapId, route) {
312
311
  const walletClient = this.requireWalletClient(context);
313
312
  const publicClient = this.requirePublicClient(context);
314
313
  const account = walletClient.account;
@@ -345,26 +344,30 @@ class RiftSdk {
345
344
  stepId: effectiveStep.id,
346
345
  error: estimateError instanceof Error ? estimateError.message : String(estimateError)
347
346
  });
348
- let refreshed;
349
347
  try {
350
- refreshed = this.unwrapEdenResult(await this.riftClient.swap({ swapId })["refresh-step"].post({ stepId: effectiveStep.id }));
351
- } catch (refreshError) {
352
- throw new Error(`estimateGas failed for dex_swap step and refresh-step failed: ${refreshError instanceof Error ? refreshError.message : String(refreshError)}`);
353
- }
354
- if (!refreshed?.step) {
355
- throw new Error("estimateGas failed for dex_swap step and refresh-step returned no step");
356
- }
357
- if (refreshed.step.kind !== "dex_swap") {
358
- throw new Error(`refresh-step returned unexpected step kind: ${refreshed.step.kind}`);
348
+ const refreshed = this.unwrapEdenResult(await this.riftClient.swap({ swapId })["refresh-step"].post({ stepId: effectiveStep.id }));
349
+ if (!refreshed?.step) {
350
+ throw new Error("estimateGas failed for dex_swap step and refresh-step returned no step");
351
+ }
352
+ if (refreshed.step.kind !== "dex_swap") {
353
+ throw new Error(`refresh-step returned unexpected step kind: ${refreshed.step.kind}`);
354
+ }
355
+ effectiveStep = refreshed.step;
356
+ txRequest = {
357
+ account,
358
+ to: effectiveStep.to,
359
+ data: effectiveStep.calldata,
360
+ value: effectiveStep.value ? BigInt(effectiveStep.value) : undefined
361
+ };
362
+ estimatedGas = await publicClient.estimateGas(txRequest);
363
+ } catch (retrySimulationError) {
364
+ this.logDebug("dex_swap simulation failed after refresh-step attempt", {
365
+ swapId,
366
+ stepId: effectiveStep.id,
367
+ error: retrySimulationError instanceof Error ? retrySimulationError.message : String(retrySimulationError)
368
+ });
369
+ throw new Error(this.buildDexSwapRevertMessage(route, effectiveStep.venue));
359
370
  }
360
- effectiveStep = refreshed.step;
361
- txRequest = {
362
- account,
363
- to: effectiveStep.to,
364
- data: effectiveStep.calldata,
365
- value: effectiveStep.value ? BigInt(effectiveStep.value) : undefined
366
- };
367
- estimatedGas = await publicClient.estimateGas(txRequest);
368
371
  }
369
372
  const gasLimit = (estimatedGas * GAS_LIMIT_MULTIPLIER_NUMERATOR + GAS_LIMIT_MULTIPLIER_DENOMINATOR - 1n) / GAS_LIMIT_MULTIPLIER_DENOMINATOR;
370
373
  this.logDebug("using buffered gas limit", {
@@ -381,6 +384,9 @@ class RiftSdk {
381
384
  hash: txHash
382
385
  });
383
386
  if (receipt.status !== "success") {
387
+ if (effectiveStep.kind === "dex_swap") {
388
+ throw new Error(this.buildDexSwapRevertMessage(route, effectiveStep.venue, txHash));
389
+ }
384
390
  throw new Error(`EVM step transaction reverted (${effectiveStep.kind}) with hash ${txHash}`);
385
391
  }
386
392
  return { txHash };
@@ -426,6 +432,17 @@ class RiftSdk {
426
432
  rift: swap
427
433
  };
428
434
  }
435
+ buildDexSwapRevertMessage(route, venue, txHash) {
436
+ const venueLabel = this.resolveDexVenueLabel(venue);
437
+ const baseMessage = route?.type === "dex_then_rift" ? `The pre-swap into cbBTC failed on ${venueLabel}; consider increasing slippage tolerance.` : `The DEX swap failed on ${venueLabel}; consider increasing slippage tolerance.`;
438
+ return txHash ? `${baseMessage} Transaction hash: ${txHash}` : baseMessage;
439
+ }
440
+ resolveDexVenueLabel(venue) {
441
+ if (typeof venue !== "string")
442
+ return "the selected venue";
443
+ const trimmed = venue.trim();
444
+ return trimmed.length > 0 ? trimmed : "the selected venue";
445
+ }
429
446
  async assertSufficientBalance(currency, amount, context) {
430
447
  if (currency.chain.kind !== "EVM")
431
448
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riftresearch/sdk",
3
- "version": "0.9.0",
3
+ "version": "0.11.0",
4
4
  "description": "SDK for swapping between bitcoin and evm chains",
5
5
  "license": "MIT",
6
6
  "files": [