Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/transaction-pay-controller/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Add MMPay `FiatStrategy` quotes flow ([#8121](https://github.com/MetaMask/core/pull/8121))

## [16.3.0]

### Added
Expand Down
1 change: 1 addition & 0 deletions packages/transaction-pay-controller/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"@metamask/messenger": "^0.3.0",
"@metamask/metamask-eth-abis": "^3.1.1",
"@metamask/network-controller": "^30.0.0",
"@metamask/ramps-controller": "^10.2.0",
"@metamask/remote-feature-flag-controller": "^4.1.0",
"@metamask/transaction-controller": "^62.20.0",
"@metamask/utils": "^11.9.0",
Expand Down
32 changes: 32 additions & 0 deletions packages/transaction-pay-controller/src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { TransactionType } from '@metamask/transaction-controller';
import type { Hex } from '@metamask/utils';

export const CONTROLLER_NAME = 'TransactionPayController';
Expand All @@ -14,6 +15,36 @@ export const ARBITRUM_USDC_ADDRESS =
export const POLYGON_USDCE_ADDRESS =
'0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174' as Hex;

export type TransactionPayFiatAsset = {
address: Hex;
caipAssetId: string;
chainId: Hex;
decimals: number;
};

const POLYGON_POL_FIAT_ASSET: TransactionPayFiatAsset = {
address: '0x0000000000000000000000000000000000001010',
caipAssetId: 'eip155:137/slip44:966',
chainId: CHAIN_ID_POLYGON,
decimals: 18,
};

const ARBITRUM_ETH_FIAT_ASSET: TransactionPayFiatAsset = {
address: NATIVE_TOKEN_ADDRESS,
caipAssetId: 'eip155:42161/slip44:60',
chainId: CHAIN_ID_ARBITRUM,
decimals: 18,
};

// We might use feature flags to determine these later.
export const MMPAY_FIAT_ASSET_ID_BY_TX_TYPE: Partial<
Record<TransactionType, TransactionPayFiatAsset>
> = {
[TransactionType.predictDeposit]: POLYGON_POL_FIAT_ASSET,
[TransactionType.perpsDeposit]: ARBITRUM_ETH_FIAT_ASSET,
[TransactionType.perpsDepositAndOrder]: ARBITRUM_ETH_FIAT_ASSET,
};

export const STABLECOINS: Record<Hex, Hex[]> = {
// Mainnet
'0x1': [
Expand All @@ -34,6 +65,7 @@ export const STABLECOINS: Record<Hex, Hex[]> = {

export enum TransactionPayStrategy {
Bridge = 'bridge',
Fiat = 'fiat',
Relay = 'relay',
Test = 'test',
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import type { TransactionMeta } from '@metamask/transaction-controller';

import { getFiatQuotes } from './fiat-quotes';
import { submitFiatQuotes } from './fiat-submit';
import { FiatStrategy } from './FiatStrategy';
import type { FiatOriginalQuote } from './types';
import type { TransactionPayControllerMessenger } from '../..';
import type { TransactionPayQuote } from '../../types';

jest.mock('./fiat-quotes');
jest.mock('./fiat-submit');

const QUOTE_MOCK = {
estimatedDuration: 5,
} as TransactionPayQuote<FiatOriginalQuote>;

describe('FiatStrategy', () => {
const getFiatQuotesMock = jest.mocked(getFiatQuotes);
const submitFiatQuotesMock = jest.mocked(submitFiatQuotes);

beforeEach(() => {
jest.resetAllMocks();
getFiatQuotesMock.mockResolvedValue([QUOTE_MOCK]);
});

describe('getQuotes', () => {
it('returns result from util', async () => {
const result = new FiatStrategy().getQuotes({
messenger: {} as TransactionPayControllerMessenger,
requests: [],
transaction: {} as TransactionMeta,
});

expect(await result).toStrictEqual([QUOTE_MOCK]);
});
});

describe('execute', () => {
it('calls util', async () => {
await new FiatStrategy().execute({
isSmartTransaction: () => false,
quotes: [QUOTE_MOCK],
messenger: {} as TransactionPayControllerMessenger,
transaction: { txParams: { from: '0x1' } } as TransactionMeta,
});

expect(submitFiatQuotesMock).toHaveBeenCalledTimes(1);
expect(
submitFiatQuotesMock.mock.calls[0][0].transaction.txParams.from,
).toBe('0x1');
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { getFiatQuotes } from './fiat-quotes';
import { submitFiatQuotes } from './fiat-submit';
import type { FiatOriginalQuote } from './types';
import type {
PayStrategy,
PayStrategyExecuteRequest,
PayStrategyGetQuotesRequest,
TransactionPayQuote,
} from '../../types';

export class FiatStrategy implements PayStrategy<FiatOriginalQuote> {
async getQuotes(
request: PayStrategyGetQuotesRequest,
): Promise<TransactionPayQuote<FiatOriginalQuote>[]> {
return getFiatQuotes(request);
}

async execute(
request: PayStrategyExecuteRequest<FiatOriginalQuote>,
): ReturnType<PayStrategy<FiatOriginalQuote>['execute']> {
return await submitFiatQuotes(request);
}
}
Loading
Loading