@metamask/transaction-pay-controller 20.0.1 → 20.2.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 +28 -1
- package/dist/helpers/TransactionPayPublishHook.cjs +2 -1
- package/dist/helpers/TransactionPayPublishHook.cjs.map +1 -1
- package/dist/helpers/TransactionPayPublishHook.d.cts.map +1 -1
- package/dist/helpers/TransactionPayPublishHook.d.mts.map +1 -1
- package/dist/helpers/TransactionPayPublishHook.mjs +2 -1
- package/dist/helpers/TransactionPayPublishHook.mjs.map +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/strategy/across/across-quotes.cjs +4 -2
- package/dist/strategy/across/across-quotes.cjs.map +1 -1
- package/dist/strategy/across/across-quotes.mjs +4 -2
- package/dist/strategy/across/across-quotes.mjs.map +1 -1
- package/dist/strategy/relay/RelayStrategy.cjs +7 -1
- package/dist/strategy/relay/RelayStrategy.cjs.map +1 -1
- package/dist/strategy/relay/RelayStrategy.d.cts.map +1 -1
- package/dist/strategy/relay/RelayStrategy.d.mts.map +1 -1
- package/dist/strategy/relay/RelayStrategy.mjs +7 -1
- package/dist/strategy/relay/RelayStrategy.mjs.map +1 -1
- package/dist/strategy/relay/relay-api.cjs +31 -5
- package/dist/strategy/relay/relay-api.cjs.map +1 -1
- package/dist/strategy/relay/relay-api.d.cts +2 -1
- package/dist/strategy/relay/relay-api.d.cts.map +1 -1
- package/dist/strategy/relay/relay-api.d.mts +2 -1
- package/dist/strategy/relay/relay-api.d.mts.map +1 -1
- package/dist/strategy/relay/relay-api.mjs +31 -5
- package/dist/strategy/relay/relay-api.mjs.map +1 -1
- package/dist/strategy/relay/relay-quotes.cjs +2 -3
- package/dist/strategy/relay/relay-quotes.cjs.map +1 -1
- package/dist/strategy/relay/relay-quotes.mjs +2 -3
- package/dist/strategy/relay/relay-quotes.mjs.map +1 -1
- package/dist/strategy/relay/relay-submit.cjs +8 -1
- package/dist/strategy/relay/relay-submit.cjs.map +1 -1
- package/dist/strategy/relay/relay-submit.mjs +8 -1
- package/dist/strategy/relay/relay-submit.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +10 -0
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +10 -0
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/utils/quotes.cjs +60 -7
- package/dist/utils/quotes.cjs.map +1 -1
- package/dist/utils/quotes.d.cts +6 -1
- package/dist/utils/quotes.d.cts.map +1 -1
- package/dist/utils/quotes.d.mts +6 -1
- package/dist/utils/quotes.d.mts.map +1 -1
- package/dist/utils/quotes.mjs +60 -7
- package/dist/utils/quotes.mjs.map +1 -1
- package/dist/utils/required-tokens.cjs +2 -46
- package/dist/utils/required-tokens.cjs.map +1 -1
- package/dist/utils/required-tokens.d.cts.map +1 -1
- package/dist/utils/required-tokens.d.mts.map +1 -1
- package/dist/utils/required-tokens.mjs +3 -47
- package/dist/utils/required-tokens.mjs.map +1 -1
- package/package.json +5 -5
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { Interface } from "@ethersproject/abi";
|
|
2
2
|
import { toHex } from "@metamask/controller-utils";
|
|
3
3
|
import { abiERC20 } from "@metamask/metamask-eth-abis";
|
|
4
|
-
import {
|
|
5
|
-
import { BigNumber } from "bignumber.js";
|
|
6
|
-
import { computeTokenAmounts, getNativeToken, getTokenBalance, getTokenFiatRate, getTokenInfo } from "./token.mjs";
|
|
4
|
+
import { computeTokenAmounts, getTokenBalance, getTokenFiatRate, getTokenInfo } from "./token.mjs";
|
|
7
5
|
const FOUR_BYTE_TOKEN_TRANSFER = '0xa9059cbb';
|
|
8
6
|
/**
|
|
9
7
|
* Parse required tokens from a transaction.
|
|
@@ -23,10 +21,8 @@ export function parseRequiredTokens(transaction, messenger) {
|
|
|
23
21
|
.filter(Boolean);
|
|
24
22
|
return assetTokens;
|
|
25
23
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
getGasFeeToken(transaction, messenger),
|
|
29
|
-
].filter(Boolean);
|
|
24
|
+
const transferToken = getTokenTransferToken(transaction, messenger);
|
|
25
|
+
return transferToken ? [transferToken] : [];
|
|
30
26
|
}
|
|
31
27
|
/**
|
|
32
28
|
* Parse a required token from a token transfer.
|
|
@@ -53,46 +49,6 @@ function getTokenTransferToken(transaction, messenger) {
|
|
|
53
49
|
}
|
|
54
50
|
return buildRequiredToken(transaction, to, transferAmount, messenger);
|
|
55
51
|
}
|
|
56
|
-
/**
|
|
57
|
-
* Get the gas fee token required for a transaction.
|
|
58
|
-
*
|
|
59
|
-
* @param transaction - Transaction metadata.
|
|
60
|
-
* @param messenger - Controller messenger.
|
|
61
|
-
* @returns The gas fee token or undefined if it could not be determined.
|
|
62
|
-
*/
|
|
63
|
-
function getGasFeeToken(transaction, messenger) {
|
|
64
|
-
const { chainId, txParams } = transaction;
|
|
65
|
-
const { gas, maxFeePerGas } = txParams;
|
|
66
|
-
const nativeTokenAddress = getNativeToken(chainId);
|
|
67
|
-
const maxGasCostRawHex = add0x(new BigNumber(gas ?? '0x0')
|
|
68
|
-
.multipliedBy(new BigNumber(maxFeePerGas ?? '0x0'))
|
|
69
|
-
.toString(16));
|
|
70
|
-
const token = buildRequiredToken(transaction, nativeTokenAddress, maxGasCostRawHex, messenger);
|
|
71
|
-
if (!token) {
|
|
72
|
-
return undefined;
|
|
73
|
-
}
|
|
74
|
-
const amountUsdValue = new BigNumber(token.amountUsd);
|
|
75
|
-
const hasBalance = new BigNumber(token.balanceRaw).isGreaterThanOrEqualTo(token.amountRaw);
|
|
76
|
-
if (hasBalance || amountUsdValue.isGreaterThanOrEqualTo(1)) {
|
|
77
|
-
return {
|
|
78
|
-
...token,
|
|
79
|
-
allowUnderMinimum: true,
|
|
80
|
-
skipIfBalance: true,
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
const fiatRates = getTokenFiatRate(messenger, nativeTokenAddress, chainId);
|
|
84
|
-
const oneDollarRawHex = add0x(new BigNumber(1).dividedBy(fiatRates.usdRate).shiftedBy(18).toString(16));
|
|
85
|
-
const oneDollarToken = buildRequiredToken(transaction, nativeTokenAddress, oneDollarRawHex, messenger);
|
|
86
|
-
/* istanbul ignore next */
|
|
87
|
-
if (!oneDollarToken) {
|
|
88
|
-
return undefined;
|
|
89
|
-
}
|
|
90
|
-
return {
|
|
91
|
-
...oneDollarToken,
|
|
92
|
-
allowUnderMinimum: true,
|
|
93
|
-
skipIfBalance: true,
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
52
|
/**
|
|
97
53
|
* Get the full token properties for a specific token and amount.
|
|
98
54
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"required-tokens.mjs","sourceRoot":"","sources":["../../src/utils/required-tokens.ts"],"names":[],"mappings":"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","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport { toHex } from '@metamask/controller-utils';\nimport { abiERC20 } from '@metamask/metamask-eth-abis';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport { add0x } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport type {\n FiatRates,\n TransactionPayControllerMessenger,\n TransactionPayRequiredToken,\n} from '../types';\nimport {\n computeTokenAmounts,\n getNativeToken,\n getTokenBalance,\n getTokenFiatRate,\n getTokenInfo,\n} from './token';\n\nconst FOUR_BYTE_TOKEN_TRANSFER = '0xa9059cbb';\n\n/**\n * Parse required tokens from a transaction.\n *\n * If the transaction has `requiredAssets`, those are used to determine required tokens.\n * Otherwise, falls back to parsing the transaction data for token transfers.\n *\n * @param transaction - Transaction metadata.\n * @param messenger - Controller messenger.\n * @returns An array of required tokens.\n */\nexport function parseRequiredTokens(\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): TransactionPayRequiredToken[] {\n const { requiredAssets } = transaction;\n\n if (requiredAssets?.length) {\n const assetTokens = requiredAssets\n .map((asset) =>\n buildRequiredToken(transaction, asset.address, asset.amount, messenger),\n )\n .filter(Boolean) as TransactionPayRequiredToken[];\n\n return assetTokens;\n }\n\n return [\n getTokenTransferToken(transaction, messenger),\n getGasFeeToken(transaction, messenger),\n ].filter(Boolean) as TransactionPayRequiredToken[];\n}\n\n/**\n * Parse a required token from a token transfer.\n *\n * @param transaction - Transaction metadata.\n * @param messenger - Controller messenger.\n * @returns The required token or undefined if the transaction is not a token transfer.\n */\nfunction getTokenTransferToken(\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): TransactionPayRequiredToken | undefined {\n const { data, to } = getTokenTransferData(transaction) ?? {};\n\n if (!to || !data) {\n return undefined;\n }\n\n let transferAmount: Hex | undefined;\n\n try {\n const result = new Interface(abiERC20).decodeFunctionData('transfer', data);\n transferAmount = toHex(result._value);\n } catch {\n // Intentionally empty\n }\n\n if (transferAmount === undefined) {\n return undefined;\n }\n\n return buildRequiredToken(transaction, to, transferAmount, messenger);\n}\n\n/**\n * Get the gas fee token required for a transaction.\n *\n * @param transaction - Transaction metadata.\n * @param messenger - Controller messenger.\n * @returns The gas fee token or undefined if it could not be determined.\n */\nfunction getGasFeeToken(\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): TransactionPayRequiredToken | undefined {\n const { chainId, txParams } = transaction;\n const { gas, maxFeePerGas } = txParams;\n const nativeTokenAddress = getNativeToken(chainId);\n\n const maxGasCostRawHex = add0x(\n new BigNumber(gas ?? '0x0')\n .multipliedBy(new BigNumber(maxFeePerGas ?? '0x0'))\n .toString(16),\n );\n\n const token = buildRequiredToken(\n transaction,\n nativeTokenAddress,\n maxGasCostRawHex,\n messenger,\n );\n\n if (!token) {\n return undefined;\n }\n\n const amountUsdValue = new BigNumber(token.amountUsd);\n\n const hasBalance = new BigNumber(token.balanceRaw).isGreaterThanOrEqualTo(\n token.amountRaw,\n );\n\n if (hasBalance || amountUsdValue.isGreaterThanOrEqualTo(1)) {\n return {\n ...token,\n allowUnderMinimum: true,\n skipIfBalance: true,\n };\n }\n\n const fiatRates = getTokenFiatRate(\n messenger,\n nativeTokenAddress,\n chainId,\n ) as FiatRates;\n\n const oneDollarRawHex = add0x(\n new BigNumber(1).dividedBy(fiatRates.usdRate).shiftedBy(18).toString(16),\n );\n\n const oneDollarToken = buildRequiredToken(\n transaction,\n nativeTokenAddress,\n oneDollarRawHex,\n messenger,\n );\n\n /* istanbul ignore next */\n if (!oneDollarToken) {\n return undefined;\n }\n\n return {\n ...oneDollarToken,\n allowUnderMinimum: true,\n skipIfBalance: true,\n };\n}\n\n/**\n * Get the full token properties for a specific token and amount.\n *\n * @param transaction - Transaction metadata.\n * @param tokenAddress - Token address.\n * @param amountRawHex - Raw token amount in hexadecimal format.\n * @param messenger - Controller messenger.\n * @returns The full token properties or undefined if the token data could not be retrieved.\n */\nfunction buildRequiredToken(\n transaction: TransactionMeta,\n tokenAddress: Hex,\n amountRawHex: Hex,\n messenger: TransactionPayControllerMessenger,\n): TransactionPayRequiredToken | undefined {\n const { chainId, txParams } = transaction;\n const from = txParams.from as Hex;\n\n const { decimals: tokenDecimals, symbol } =\n getTokenInfo(messenger, tokenAddress, chainId) ?? {};\n\n const fiatRates = getTokenFiatRate(messenger, tokenAddress, chainId);\n const tokenBalance = getTokenBalance(messenger, from, chainId, tokenAddress);\n\n if (tokenDecimals === undefined || !symbol || fiatRates === undefined) {\n return undefined;\n }\n\n const {\n human: balanceHuman,\n raw: balanceRaw,\n fiat: balanceFiat,\n usd: balanceUsd,\n } = computeTokenAmounts(tokenBalance, tokenDecimals, fiatRates);\n\n const {\n human: amountHuman,\n raw: amountRaw,\n fiat: amountFiat,\n usd: amountUsd,\n } = computeTokenAmounts(amountRawHex, tokenDecimals, fiatRates);\n\n return {\n address: tokenAddress,\n allowUnderMinimum: false,\n amountFiat,\n amountHuman,\n amountRaw,\n amountUsd,\n balanceFiat,\n balanceHuman,\n balanceRaw,\n balanceUsd,\n chainId,\n decimals: tokenDecimals,\n skipIfBalance: false,\n symbol,\n };\n}\n\n/**\n * Find token transfer data in a transaction.\n *\n * @param transactionMeta - Transaction metadata.\n * @returns - Token transfer data or undefined if not found.\n */\nfunction getTokenTransferData(transactionMeta: TransactionMeta):\n | {\n data: Hex;\n to: Hex;\n index?: number;\n }\n | undefined {\n const { nestedTransactions, txParams } = transactionMeta;\n const { data: singleData } = txParams;\n const singleTo = txParams?.to as Hex | undefined;\n\n if (singleData?.startsWith(FOUR_BYTE_TOKEN_TRANSFER) && singleTo) {\n return { data: singleData as Hex, to: singleTo, index: undefined };\n }\n\n const nestedCallIndex = nestedTransactions?.findIndex((call) =>\n call.data?.startsWith(FOUR_BYTE_TOKEN_TRANSFER),\n );\n\n const nestedCall =\n nestedCallIndex === undefined || nestedCallIndex === -1\n ? undefined\n : nestedTransactions?.[nestedCallIndex];\n\n if (nestedCall?.data && nestedCall.to) {\n return {\n data: nestedCall.data,\n to: nestedCall.to,\n index: nestedCallIndex,\n };\n }\n\n return undefined;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"required-tokens.mjs","sourceRoot":"","sources":["../../src/utils/required-tokens.ts"],"names":[],"mappings":"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","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport { toHex } from '@metamask/controller-utils';\nimport { abiERC20 } from '@metamask/metamask-eth-abis';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\n\nimport type {\n TransactionPayControllerMessenger,\n TransactionPayRequiredToken,\n} from '../types';\nimport {\n computeTokenAmounts,\n getTokenBalance,\n getTokenFiatRate,\n getTokenInfo,\n} from './token';\n\nconst FOUR_BYTE_TOKEN_TRANSFER = '0xa9059cbb';\n\n/**\n * Parse required tokens from a transaction.\n *\n * If the transaction has `requiredAssets`, those are used to determine required tokens.\n * Otherwise, falls back to parsing the transaction data for token transfers.\n *\n * @param transaction - Transaction metadata.\n * @param messenger - Controller messenger.\n * @returns An array of required tokens.\n */\nexport function parseRequiredTokens(\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): TransactionPayRequiredToken[] {\n const { requiredAssets } = transaction;\n\n if (requiredAssets?.length) {\n const assetTokens = requiredAssets\n .map((asset) =>\n buildRequiredToken(transaction, asset.address, asset.amount, messenger),\n )\n .filter(Boolean) as TransactionPayRequiredToken[];\n\n return assetTokens;\n }\n\n const transferToken = getTokenTransferToken(transaction, messenger);\n return transferToken ? [transferToken] : [];\n}\n\n/**\n * Parse a required token from a token transfer.\n *\n * @param transaction - Transaction metadata.\n * @param messenger - Controller messenger.\n * @returns The required token or undefined if the transaction is not a token transfer.\n */\nfunction getTokenTransferToken(\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): TransactionPayRequiredToken | undefined {\n const { data, to } = getTokenTransferData(transaction) ?? {};\n\n if (!to || !data) {\n return undefined;\n }\n\n let transferAmount: Hex | undefined;\n\n try {\n const result = new Interface(abiERC20).decodeFunctionData('transfer', data);\n transferAmount = toHex(result._value);\n } catch {\n // Intentionally empty\n }\n\n if (transferAmount === undefined) {\n return undefined;\n }\n\n return buildRequiredToken(transaction, to, transferAmount, messenger);\n}\n\n/**\n * Get the full token properties for a specific token and amount.\n *\n * @param transaction - Transaction metadata.\n * @param tokenAddress - Token address.\n * @param amountRawHex - Raw token amount in hexadecimal format.\n * @param messenger - Controller messenger.\n * @returns The full token properties or undefined if the token data could not be retrieved.\n */\nfunction buildRequiredToken(\n transaction: TransactionMeta,\n tokenAddress: Hex,\n amountRawHex: Hex,\n messenger: TransactionPayControllerMessenger,\n): TransactionPayRequiredToken | undefined {\n const { chainId, txParams } = transaction;\n const from = txParams.from as Hex;\n\n const { decimals: tokenDecimals, symbol } =\n getTokenInfo(messenger, tokenAddress, chainId) ?? {};\n\n const fiatRates = getTokenFiatRate(messenger, tokenAddress, chainId);\n const tokenBalance = getTokenBalance(messenger, from, chainId, tokenAddress);\n\n if (tokenDecimals === undefined || !symbol || fiatRates === undefined) {\n return undefined;\n }\n\n const {\n human: balanceHuman,\n raw: balanceRaw,\n fiat: balanceFiat,\n usd: balanceUsd,\n } = computeTokenAmounts(tokenBalance, tokenDecimals, fiatRates);\n\n const {\n human: amountHuman,\n raw: amountRaw,\n fiat: amountFiat,\n usd: amountUsd,\n } = computeTokenAmounts(amountRawHex, tokenDecimals, fiatRates);\n\n return {\n address: tokenAddress,\n allowUnderMinimum: false,\n amountFiat,\n amountHuman,\n amountRaw,\n amountUsd,\n balanceFiat,\n balanceHuman,\n balanceRaw,\n balanceUsd,\n chainId,\n decimals: tokenDecimals,\n skipIfBalance: false,\n symbol,\n };\n}\n\n/**\n * Find token transfer data in a transaction.\n *\n * @param transactionMeta - Transaction metadata.\n * @returns - Token transfer data or undefined if not found.\n */\nfunction getTokenTransferData(transactionMeta: TransactionMeta):\n | {\n data: Hex;\n to: Hex;\n index?: number;\n }\n | undefined {\n const { nestedTransactions, txParams } = transactionMeta;\n const { data: singleData } = txParams;\n const singleTo = txParams?.to as Hex | undefined;\n\n if (singleData?.startsWith(FOUR_BYTE_TOKEN_TRANSFER) && singleTo) {\n return { data: singleData as Hex, to: singleTo, index: undefined };\n }\n\n const nestedCallIndex = nestedTransactions?.findIndex((call) =>\n call.data?.startsWith(FOUR_BYTE_TOKEN_TRANSFER),\n );\n\n const nestedCall =\n nestedCallIndex === undefined || nestedCallIndex === -1\n ? undefined\n : nestedTransactions?.[nestedCallIndex];\n\n if (nestedCall?.data && nestedCall.to) {\n return {\n data: nestedCall.data,\n to: nestedCall.to,\n index: nestedCallIndex,\n };\n }\n\n return undefined;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metamask/transaction-pay-controller",
|
|
3
|
-
"version": "20.0
|
|
3
|
+
"version": "20.2.0",
|
|
4
4
|
"description": "Manages alternate payment strategies to provide required funds for transactions in MetaMask",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Ethereum",
|
|
@@ -57,16 +57,16 @@
|
|
|
57
57
|
"@ethersproject/abi": "^5.7.0",
|
|
58
58
|
"@ethersproject/contracts": "^5.7.0",
|
|
59
59
|
"@ethersproject/providers": "^5.7.0",
|
|
60
|
-
"@metamask/assets-controller": "^6.
|
|
61
|
-
"@metamask/assets-controllers": "^105.
|
|
60
|
+
"@metamask/assets-controller": "^6.3.0",
|
|
61
|
+
"@metamask/assets-controllers": "^105.1.0",
|
|
62
62
|
"@metamask/base-controller": "^9.1.0",
|
|
63
63
|
"@metamask/bridge-controller": "^71.0.0",
|
|
64
64
|
"@metamask/bridge-status-controller": "^71.1.0",
|
|
65
65
|
"@metamask/controller-utils": "^11.20.0",
|
|
66
66
|
"@metamask/gas-fee-controller": "^26.1.1",
|
|
67
|
-
"@metamask/messenger": "^1.
|
|
67
|
+
"@metamask/messenger": "^1.2.0",
|
|
68
68
|
"@metamask/metamask-eth-abis": "^3.1.1",
|
|
69
|
-
"@metamask/network-controller": "^30.0
|
|
69
|
+
"@metamask/network-controller": "^30.1.0",
|
|
70
70
|
"@metamask/ramps-controller": "^13.2.0",
|
|
71
71
|
"@metamask/remote-feature-flag-controller": "^4.2.0",
|
|
72
72
|
"@metamask/transaction-controller": "^65.0.0",
|