@metamask/ramps-controller 22.0.0 → 23.0.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/CHANGELOG.md +17 -1
- package/dist/RampsController-method-action-types.d.ts +47 -1
- package/dist/RampsController-method-action-types.d.ts.map +1 -1
- package/dist/RampsController-method-action-types.js.map +1 -1
- package/dist/RampsController.d.ts +60 -1
- package/dist/RampsController.d.ts.map +1 -1
- package/dist/RampsController.js +141 -2
- package/dist/RampsController.js.map +1 -1
- package/dist/TransakService.d.ts +3 -1
- package/dist/TransakService.d.ts.map +1 -1
- package/dist/TransakService.js +10 -3
- package/dist/TransakService.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/RampsController.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { BaseController } from '@metamask/base-controller';
|
|
2
2
|
import { BrokenCircuitError } from '@metamask/controller-utils';
|
|
3
|
+
import { BigNumber } from 'bignumber.js';
|
|
3
4
|
import { applyAutorampRemoteStatus, createAutorampAccount, markAutorampNotified, } from './autorampAccount.js';
|
|
4
5
|
import { getHeadlessProviderAllowlist, isHeadlessAllProvidersEnabled, normalizeHeadlessProviderId, } from './featureFlags.js';
|
|
5
6
|
import { areOrdersEqual, deleteOrderInUserStorage, syncOrdersWithUserStorage as syncOrdersWithUserStorageInternal, updateOrderInUserStorage, } from './order-syncing/index.js';
|
|
@@ -409,6 +410,7 @@ const MESSENGER_EXPOSED_METHODS = [
|
|
|
409
410
|
'getPaymentMethodsForContext',
|
|
410
411
|
'setSelectedPaymentMethod',
|
|
411
412
|
'getQuotes',
|
|
413
|
+
'getQuoteWithFees',
|
|
412
414
|
'addOrder',
|
|
413
415
|
'removeOrder',
|
|
414
416
|
'addAutoramp',
|
|
@@ -474,6 +476,27 @@ function contextStillMatches(state, context) {
|
|
|
474
476
|
context.assetId &&
|
|
475
477
|
(state.providers.selected?.id.trim() ?? '') === context.providerId);
|
|
476
478
|
}
|
|
479
|
+
/**
|
|
480
|
+
* Provider codes that identify Transak's native (non-aggregator) integration,
|
|
481
|
+
* in the bare form produced by {@link normalizeHeadlessProviderId}.
|
|
482
|
+
*/
|
|
483
|
+
const NATIVE_TRANSAK_PROVIDER_CODES = [
|
|
484
|
+
'transak-native',
|
|
485
|
+
'transak-native-staging',
|
|
486
|
+
];
|
|
487
|
+
/**
|
|
488
|
+
* Coerces a quote fee value to a non-negative BigNumber, treating a missing or
|
|
489
|
+
* invalid value as zero.
|
|
490
|
+
*
|
|
491
|
+
* @param value - Raw fee value from a quote.
|
|
492
|
+
* @returns The fee as a non-negative BigNumber.
|
|
493
|
+
*/
|
|
494
|
+
function getSafeRampsFee(value) {
|
|
495
|
+
const fee = new BigNumber(value ?? 0);
|
|
496
|
+
return fee.isFinite() && fee.isGreaterThanOrEqualTo(0)
|
|
497
|
+
? fee
|
|
498
|
+
: new BigNumber(0);
|
|
499
|
+
}
|
|
477
500
|
export class RampsController extends BaseController {
|
|
478
501
|
/**
|
|
479
502
|
* Default TTL for cached requests.
|
|
@@ -1666,6 +1689,120 @@ export class RampsController extends BaseController {
|
|
|
1666
1689
|
],
|
|
1667
1690
|
};
|
|
1668
1691
|
}
|
|
1692
|
+
/**
|
|
1693
|
+
* Fetches the best on-ramp quote for a request and, when the resolved
|
|
1694
|
+
* provider is Transak Native, reconciles its fees to match what Transak
|
|
1695
|
+
* Native actually charges.
|
|
1696
|
+
*
|
|
1697
|
+
* The aggregator `/quotes` estimate of Transak's fee does not match the
|
|
1698
|
+
* native integration. When the resolved provider is Transak Native this
|
|
1699
|
+
* fetches the native buy quote (an unauthenticated, API-key-only lookup, so
|
|
1700
|
+
* it is safe at estimate time) and rewrites the returned quote's fee fields
|
|
1701
|
+
* to its `totalFee`, keeping the aggregator's `networkFee` on the network
|
|
1702
|
+
* line and placing the remainder in the provider fee so the breakdown
|
|
1703
|
+
* survives and `providerFee + networkFee` still equals the native total. A
|
|
1704
|
+
* non-native provider, a failed lookup, or an unusable native fee returns the
|
|
1705
|
+
* aggregator quote unchanged.
|
|
1706
|
+
*
|
|
1707
|
+
* Consumers (e.g. `TransactionPayController`) call this instead of owning the
|
|
1708
|
+
* provider check, asset-id parsing, and second native quote themselves.
|
|
1709
|
+
*
|
|
1710
|
+
* @param options - Quote options; see {@link getQuotes}, plus the fee mode.
|
|
1711
|
+
* @param options.amount - Fiat amount for the quote.
|
|
1712
|
+
* @param options.assetId - CAIP-19 asset id being bought.
|
|
1713
|
+
* @param options.fiat - Optional fiat currency; defaults like {@link getQuotes}.
|
|
1714
|
+
* @param options.paymentMethods - Optional payment method ids.
|
|
1715
|
+
* @param options.walletAddress - Wallet address receiving the on-ramped asset.
|
|
1716
|
+
* @param options.isFeeExcludedFromFiat - Whether Transak adds its fee on top
|
|
1717
|
+
* of the fiat amount (`true`, fee-on-top) or carves it out (`false`). Must
|
|
1718
|
+
* mirror the eventual checkout mode so the estimate equals the charge.
|
|
1719
|
+
* Defaults to `true`.
|
|
1720
|
+
* @param options.providers - See {@link getQuotes}.
|
|
1721
|
+
* @param options.autoSelectProvider - See {@link getQuotes}.
|
|
1722
|
+
* @param options.restrictToKnownOrNativeProviders - See {@link getQuotes}.
|
|
1723
|
+
* @param options.preferredProviderIds - See {@link getQuotes}.
|
|
1724
|
+
* @param options.region - See {@link getQuotes}.
|
|
1725
|
+
* @param options.redirectUrl - See {@link getQuotes}.
|
|
1726
|
+
* @param options.action - See {@link getQuotes}.
|
|
1727
|
+
* @param options.forceRefresh - See {@link getQuotes}.
|
|
1728
|
+
* @param options.ttl - See {@link getQuotes}.
|
|
1729
|
+
* @returns The best quote with native-reconciled fees, or `undefined` when
|
|
1730
|
+
* no quote is available.
|
|
1731
|
+
*/
|
|
1732
|
+
async getQuoteWithFees(options) {
|
|
1733
|
+
const { isFeeExcludedFromFiat = true, ...quoteOptions } = options;
|
|
1734
|
+
const response = await this.getQuotes(quoteOptions);
|
|
1735
|
+
const quote = response.success?.[0];
|
|
1736
|
+
if (!quote) {
|
|
1737
|
+
return undefined;
|
|
1738
|
+
}
|
|
1739
|
+
return this.#reconcileNativeTransakFee(quote, {
|
|
1740
|
+
amount: options.amount,
|
|
1741
|
+
assetId: options.assetId,
|
|
1742
|
+
fiat: options.fiat,
|
|
1743
|
+
// Use the resolved quote's own payment method, not the request list: the
|
|
1744
|
+
// aggregator may price a method other than `paymentMethods[0]` (or the
|
|
1745
|
+
// caller may omit the list), and the native lookup must match the quote
|
|
1746
|
+
// being reconciled.
|
|
1747
|
+
paymentMethod: quote.quote.paymentMethod,
|
|
1748
|
+
isFeeExcludedFromFiat,
|
|
1749
|
+
});
|
|
1750
|
+
}
|
|
1751
|
+
/**
|
|
1752
|
+
* Rewrites a quote's fees to Transak Native's own total when the resolved
|
|
1753
|
+
* provider is Transak Native, so an estimate matches the native charge.
|
|
1754
|
+
* Returns the quote unchanged for a non-native provider, a failed native
|
|
1755
|
+
* lookup, or an unusable native fee.
|
|
1756
|
+
*
|
|
1757
|
+
* @param quote - The resolved aggregator quote.
|
|
1758
|
+
* @param context - Native lookup inputs.
|
|
1759
|
+
* @param context.amount - Fiat amount for the native quote.
|
|
1760
|
+
* @param context.assetId - CAIP-19 asset id being bought.
|
|
1761
|
+
* @param context.fiat - Fiat currency for the native quote.
|
|
1762
|
+
* @param context.paymentMethod - Payment method id for the native quote.
|
|
1763
|
+
* @param context.isFeeExcludedFromFiat - Fee mode for the native quote.
|
|
1764
|
+
* @returns The quote with reconciled fees, or the original quote.
|
|
1765
|
+
*/
|
|
1766
|
+
async #reconcileNativeTransakFee(quote, { amount, assetId, fiat, paymentMethod, isFeeExcludedFromFiat, }) {
|
|
1767
|
+
// `normalizeHeadlessProviderId` strips the `/providers/` prefix and
|
|
1768
|
+
// lowercases, so `/providers/transak-native` and `transak-native` both match
|
|
1769
|
+
// the native codes below (and the aggregator `transak` does not).
|
|
1770
|
+
const providerCode = normalizeHeadlessProviderId(quote.provider);
|
|
1771
|
+
if (!NATIVE_TRANSAK_PROVIDER_CODES.includes(providerCode)) {
|
|
1772
|
+
return quote;
|
|
1773
|
+
}
|
|
1774
|
+
const fiatCurrency = fiat ?? this.state.userRegion?.country?.currency;
|
|
1775
|
+
if (!fiatCurrency || !paymentMethod) {
|
|
1776
|
+
return quote;
|
|
1777
|
+
}
|
|
1778
|
+
try {
|
|
1779
|
+
const network = assetId.split('/')[0];
|
|
1780
|
+
const nativeQuote = await this.messenger.call('TransakService:getBuyQuote', fiatCurrency, assetId, network, paymentMethod, String(amount), isFeeExcludedFromFiat);
|
|
1781
|
+
const nativeTotalFee = new BigNumber(nativeQuote.totalFee ?? NaN);
|
|
1782
|
+
if (!nativeTotalFee.isFinite() || nativeTotalFee.isLessThan(0)) {
|
|
1783
|
+
return quote;
|
|
1784
|
+
}
|
|
1785
|
+
// Transak Native returns a single total fee, so keep the aggregator's
|
|
1786
|
+
// network fee on the network line (clamped to the native total) and put
|
|
1787
|
+
// the remainder in the provider fee. The breakdown survives and
|
|
1788
|
+
// `providerFee + networkFee` still equals the native total.
|
|
1789
|
+
const aggregatorNetworkFee = getSafeRampsFee(quote.quote.networkFee);
|
|
1790
|
+
const networkFee = BigNumber.min(aggregatorNetworkFee, nativeTotalFee);
|
|
1791
|
+
const providerFee = nativeTotalFee.minus(networkFee);
|
|
1792
|
+
return {
|
|
1793
|
+
...quote,
|
|
1794
|
+
quote: {
|
|
1795
|
+
...quote.quote,
|
|
1796
|
+
providerFee: providerFee.toString(10),
|
|
1797
|
+
networkFee: networkFee.toString(10),
|
|
1798
|
+
totalFees: nativeTotalFee.toString(10),
|
|
1799
|
+
},
|
|
1800
|
+
};
|
|
1801
|
+
}
|
|
1802
|
+
catch {
|
|
1803
|
+
return quote;
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1669
1806
|
/**
|
|
1670
1807
|
* Selects the best quote from a widened multi-provider response.
|
|
1671
1808
|
*
|
|
@@ -2825,16 +2962,18 @@ export class RampsController extends BaseController {
|
|
|
2825
2962
|
* @param network - The blockchain network identifier.
|
|
2826
2963
|
* @param paymentMethod - The payment method identifier.
|
|
2827
2964
|
* @param fiatAmount - The fiat amount as a string.
|
|
2965
|
+
* @param isFeeExcludedFromFiat - Whether fees are added to the fiat amount.
|
|
2966
|
+
* Defaults to true to preserve Unified Buy's native Transak behavior.
|
|
2828
2967
|
* @returns The buy quote with pricing and fee details.
|
|
2829
2968
|
*/
|
|
2830
|
-
async transakGetBuyQuote(fiatCurrency, cryptoCurrency, network, paymentMethod, fiatAmount) {
|
|
2969
|
+
async transakGetBuyQuote(fiatCurrency, cryptoCurrency, network, paymentMethod, fiatAmount, isFeeExcludedFromFiat = true) {
|
|
2831
2970
|
this.update((state) => {
|
|
2832
2971
|
state.nativeProviders.transak.buyQuote.isLoading = true;
|
|
2833
2972
|
state.nativeProviders.transak.buyQuote.error = null;
|
|
2834
2973
|
delete state.nativeProviders.transak.buyQuote.errorKey;
|
|
2835
2974
|
});
|
|
2836
2975
|
try {
|
|
2837
|
-
const quote = await this.messenger.call('TransakService:getBuyQuote', fiatCurrency, cryptoCurrency, network, paymentMethod, fiatAmount);
|
|
2976
|
+
const quote = await this.messenger.call('TransakService:getBuyQuote', fiatCurrency, cryptoCurrency, network, paymentMethod, fiatAmount, isFeeExcludedFromFiat);
|
|
2838
2977
|
this.update((state) => {
|
|
2839
2978
|
state.nativeProviders.transak.buyQuote.data = quote;
|
|
2840
2979
|
state.nativeProviders.transak.buyQuote.isLoading = false;
|