diff --git a/client/src/PublicRequest.ts b/client/src/PublicRequest.ts index 567471098..84ea02212 100644 --- a/client/src/PublicRequest.ts +++ b/client/src/PublicRequest.ts @@ -285,8 +285,8 @@ export type SignSwapRequestCommon = SimpleRequest & { refundKeyPath: string, // To validate that we own the HTLC script's refund address }> ) | ( - {type: 'USDC'} - & Omit + {type: 'USDC_MATIC'} + & Omit ) | ( {type: 'EUR'} & { @@ -320,8 +320,8 @@ export type SignSwapRequestCommon = SimpleRequest & { output: BitcoinTransactionChangeOutput, } ) | ( - {type: 'USDC'} - & Omit + {type: 'USDC_MATIC'} + & Omit & { amount: number, } @@ -401,7 +401,7 @@ export type SignSwapTransactionsRequest = { type: 'BTC', htlcScript: Uint8Array, } | { - type: 'USDC', + type: 'USDC_MATIC', htlcData: string, } | { type: 'EUR', @@ -419,7 +419,7 @@ export type SignSwapTransactionsRequest = { transactionHash: string, outputIndex: number; } | { - type: 'USDC', + type: 'USDC_MATIC', hash: string, timeout: number, htlcId: string, diff --git a/src/components/BalanceDistributionBar.js b/src/components/BalanceDistributionBar.js index d2f16f0d9..6d4d70c21 100644 --- a/src/components/BalanceDistributionBar.js +++ b/src/components/BalanceDistributionBar.js @@ -3,7 +3,7 @@ /* global CryptoUtils */ /** @typedef {{address: string, balance: number, active: boolean, newBalance: number}} Segment */ -/** @typedef {'NIM' | 'BTC' | 'USDC' | 'EUR'} Asset */ +/** @typedef {'NIM' | 'BTC' | 'USDC_MATIC' | 'EUR'} Asset */ class BalanceDistributionBar { // eslint-disable-line no-unused-vars /** @@ -34,7 +34,7 @@ class BalanceDistributionBar { // eslint-disable-line no-unused-vars newBalance: CryptoUtils.unitsToCoins(leftAsset, segment.newBalance) * leftFiatRate, backgroundClass: leftAsset === 'NIM' ? LoginFileConfig[IqonHash.getBackgroundColorIndex(segment.address)].className - : leftAsset.toLowerCase(), + : CryptoUtils.assetToCurrency(leftAsset), active: segment.active, })); @@ -43,7 +43,7 @@ class BalanceDistributionBar { // eslint-disable-line no-unused-vars newBalance: CryptoUtils.unitsToCoins(rightAsset, segment.newBalance) * rightFiatRate, backgroundClass: rightAsset === 'NIM' ? LoginFileConfig[IqonHash.getBackgroundColorIndex(segment.address)].className - : rightAsset.toLowerCase(), + : CryptoUtils.assetToCurrency(rightAsset), active: segment.active, })); diff --git a/src/components/SwapFeesTooltip.js b/src/components/SwapFeesTooltip.js index d92492d38..2c14e48ec 100644 --- a/src/components/SwapFeesTooltip.js +++ b/src/components/SwapFeesTooltip.js @@ -56,17 +56,17 @@ class SwapFeesTooltip { // eslint-disable-line no-unused-vars } // Show USDC fees next - if (fundTx.type === 'USDC' || redeemTx.type === 'USDC') { - const myFee = fundTx.type === 'USDC' + if (fundTx.type === 'USDC_MATIC' || redeemTx.type === 'USDC_MATIC') { + const myFee = fundTx.type === 'USDC_MATIC' ? fundTx.description.args.fee.toNumber() - : redeemTx.type === 'USDC' + : redeemTx.type === 'USDC_MATIC' ? redeemTx.description.args.fee.toNumber() : 0; - const theirFee = fundTx.type === 'USDC' ? fundFees.redeeming : redeemFees.funding; + const theirFee = fundTx.type === 'USDC_MATIC' ? fundFees.redeeming : redeemFees.funding; - const fiatRate = fundTx.type === 'USDC' ? fundingFiatRate : redeemingFiatRate; - const fiatFee = CryptoUtils.unitsToCoins('USDC', myFee + theirFee) * fiatRate; + const fiatRate = fundTx.type === 'USDC_MATIC' ? fundingFiatRate : redeemingFiatRate; + const fiatFee = CryptoUtils.unitsToCoins('USDC_MATIC', myFee + theirFee) * fiatRate; const rows = this._createUsdcLine(fiatFee, fiatCurrency); this.$tooltip.appendChild(rows[0]); diff --git a/src/config/config.local.js b/src/config/config.local.js index 8371066c9..92770c236 100644 --- a/src/config/config.local.js +++ b/src/config/config.local.js @@ -18,10 +18,10 @@ const CONFIG = { // eslint-disable-line no-unused-vars POLYGON_CHAIN_ID: 80001, BRIDGED_USDC_CONTRACT_ADDRESS: '0x0FA8781a83E46826621b3BC094Ea2A0212e71B23', - BRIDGED_USDC_HTLC_CONTRACT_ADDRESS: '0x2EB7cd7791b947A25d629219ead941fCd8f364BF', NATIVE_USDC_CONTRACT_ADDRESS: '0x9999f7Fea5938fD3b1E26A12c3f2fb024e194f97', NATIVE_USDC_TRANSFER_CONTRACT_ADDRESS: '0x5D101A320547f8D640c44fDfe5d1f35224f00B8B', // v1 + NATIVE_USDC_HTLC_CONTRACT_ADDRESS: '0xA9fAbABE97375565e4A9Ac69A57Df33c91FCB897', USDC_SWAP_CONTRACT_ADDRESS: '0x72e64Cff5cfFD4BFbC5b8d4fB081B33B9EE3e30e', }; diff --git a/src/config/config.mainnet.js b/src/config/config.mainnet.js index 0ea16cc40..0f58372c0 100644 --- a/src/config/config.mainnet.js +++ b/src/config/config.mainnet.js @@ -9,10 +9,10 @@ const CONFIG = { // eslint-disable-line no-unused-vars POLYGON_CHAIN_ID: 137, BRIDGED_USDC_CONTRACT_ADDRESS: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174', - BRIDGED_USDC_HTLC_CONTRACT_ADDRESS: '0xF615bD7EA00C4Cc7F39Faad0895dB5f40891359f', NATIVE_USDC_CONTRACT_ADDRESS: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359', NATIVE_USDC_TRANSFER_CONTRACT_ADDRESS: '0x3157d422cd1be13AC4a7cb00957ed717e648DFf2', // v1 + NATIVE_USDC_HTLC_CONTRACT_ADDRESS: '', USDC_SWAP_CONTRACT_ADDRESS: '', }; diff --git a/src/config/config.testnet.js b/src/config/config.testnet.js index 306ae17a1..6f55ae275 100644 --- a/src/config/config.testnet.js +++ b/src/config/config.testnet.js @@ -9,10 +9,10 @@ const CONFIG = { // eslint-disable-line no-unused-vars POLYGON_CHAIN_ID: 80001, BRIDGED_USDC_CONTRACT_ADDRESS: '0x0FA8781a83E46826621b3BC094Ea2A0212e71B23', - BRIDGED_USDC_HTLC_CONTRACT_ADDRESS: '0x2EB7cd7791b947A25d629219ead941fCd8f364BF', NATIVE_USDC_CONTRACT_ADDRESS: '0x9999f7Fea5938fD3b1E26A12c3f2fb024e194f97', NATIVE_USDC_TRANSFER_CONTRACT_ADDRESS: '0x5D101A320547f8D640c44fDfe5d1f35224f00B8B', // v1 + NATIVE_USDC_HTLC_CONTRACT_ADDRESS: '0xA9fAbABE97375565e4A9Ac69A57Df33c91FCB897', USDC_SWAP_CONTRACT_ADDRESS: '0x72e64Cff5cfFD4BFbC5b8d4fB081B33B9EE3e30e', }; diff --git a/src/lib/polygon/PolygonContractABIs.full.js.txt b/src/lib/polygon/PolygonContractABIs.full.js.txt index 275215d27..23d7df3dc 100644 --- a/src/lib/polygon/PolygonContractABIs.full.js.txt +++ b/src/lib/polygon/PolygonContractABIs.full.js.txt @@ -74,62 +74,6 @@ const PolygonContractABIsFull = { // eslint-disable-line no-unused-vars 'function withdrawWithAuthorization(address owner, uint256 value, uint256 validAfter, uint256 validBefore, bytes32 nonce, uint8 v, bytes32 r, bytes32 s)', ], - BRIDGED_USDC_HTLC_CONTRACT_ABI: [ - 'constructor()', - 'event DomainRegistered(bytes32 indexed domainSeparator, bytes domainValue)', - 'event Open(bytes32 indexed id, address token, uint256 amount, address recipient, bytes32 hash, uint256 timeout)', - 'event OwnershipTransferred(address indexed previousOwner, address indexed newOwner)', - 'event Redeem(bytes32 indexed id, bytes32 secret)', - 'event Refund(bytes32 indexed id)', - 'event RequestTypeRegistered(bytes32 indexed typeHash, string typeStr)', - 'function EIP712_DOMAIN_TYPE() view returns (string)', - 'function deposits(address) view returns (uint256)', - 'function domains(bytes32) view returns (bool)', - 'function execute(tuple(address from, address to, uint256 value, uint256 gas, uint256 nonce, bytes data, uint256 validUntil) request, bytes32 domainSeparator, bytes32 requestTypeHash, bytes suffixData, bytes signature) payable returns (bool success, bytes ret)', - 'function getGasAndDataLimits() view returns (tuple(uint256 acceptanceBudget, uint256 preRelayedCallGasLimit, uint256 postRelayedCallGasLimit, uint256 calldataSizeLimit) limits)', - 'function getHubAddr() view returns (address)', - 'function getMinimumRelayFee(tuple(uint256 gasPrice, uint256 pctRelayFee, uint256 baseRelayFee, address relayWorker, address paymaster, address forwarder, bytes paymasterData, uint256 clientId) relayData) view returns (uint256 amount)', - 'function getNonce(address from) view returns (uint256)', - 'function getRelayHubDeposit() view returns (uint256)', - 'function getRequiredRelayFee(tuple(uint256 gasPrice, uint256 pctRelayFee, uint256 baseRelayFee, address relayWorker, address paymaster, address forwarder, bytes paymasterData, uint256 clientId) relayData, bytes4 methodId) view returns (uint256 amount)', - 'function getRequiredRelayGas(bytes4 methodId) view returns (uint256 gas)', - 'function htlcs(bytes32) view returns (address token, uint256 amount, address refund, address recipient, bytes32 hash, uint256 timeout)', - 'function isTrustedForwarder(address forwarder) view returns (bool)', - 'function open(bytes32 id, address token, uint256 amount, address refundAddress, address recipientAddress, bytes32 hash, uint256 timeout, uint256 fee)', - 'function openWithApproval(bytes32 id, address token, uint256 amount, address refundAddress, address recipientAddress, bytes32 hash, uint256 timeout, uint256 fee, uint256 approval, bytes32 sigR, bytes32 sigS, uint8 sigV)', - 'function owner() view returns (address)', - 'function postRelayedCall(bytes context, bool success, uint256 gasUseWithoutPost, tuple(uint256 gasPrice, uint256 pctRelayFee, uint256 baseRelayFee, address relayWorker, address paymaster, address forwarder, bytes paymasterData, uint256 clientId) relayData)', - 'function preRelayedCall(tuple(tuple(address from, address to, uint256 value, uint256 gas, uint256 nonce, bytes data, uint256 validUntil) request, tuple(uint256 gasPrice, uint256 pctRelayFee, uint256 baseRelayFee, address relayWorker, address paymaster, address forwarder, bytes paymasterData, uint256 clientId) relayData) relayRequest, bytes signature, bytes approvalData, uint256 maxPossibleGas) returns (bytes context, bool revertOnRecipientRevert)', - 'function redeem(bytes32 id, address target, bytes32 secret, uint256 fee)', - 'function redeemWithSecretInData(bytes32 id, address target, uint256 fee)', - 'function refund(bytes32 id, address target, uint256 fee)', - 'function registerDomainSeparator(string name, string version)', - 'function registerRequestType(string typeName, string typeSuffix)', - 'function registerToken(address token, address pool)', - 'function registeredTokenPool(address) view returns (address)', - 'function registeredTokenPoolFee(address token) view returns (uint24 fee)', - 'function relayWithoutGsn(tuple(tuple(address from, address to, uint256 value, uint256 gas, uint256 nonce, bytes data, uint256 validUntil) request, tuple(uint256 gasPrice, uint256 pctRelayFee, uint256 baseRelayFee, address relayWorker, address paymaster, address forwarder, bytes paymasterData, uint256 clientId) relayData) relayRequest, bytes signature, bytes approvalData, address relay)', - 'function renounceOwnership()', - 'function requiredRelayGas() view returns (uint256)', - 'function setGasAndDataLimits(tuple(uint256 acceptanceBudget, uint256 preRelayedCallGasLimit, uint256 postRelayedCallGasLimit, uint256 calldataSizeLimit) limits)', - 'function setMaxRequiredRelayGas(uint256 gas)', - 'function setRelayHub(address hub)', - 'function setRequiredRelayGas(bytes4 methodId, uint256 gas)', - 'function setWrappedChainToken(address _wrappedChainToken)', - 'function transferOwnership(address newOwner)', - 'function trustedForwarder() view returns (address forwarder)', - 'function typeHashes(bytes32) view returns (bool)', - 'function uniswapV3SwapCallback(int256 amount0Delta, int256 amount1Delta, bytes _data)', - 'function unregisterToken(address token)', - 'function verify(tuple(address from, address to, uint256 value, uint256 gas, uint256 nonce, bytes data, uint256 validUntil) forwardRequest, bytes32 domainSeparator, bytes32 requestTypeHash, bytes suffixData, bytes signature) view', - 'function versionPaymaster() view returns (string)', - 'function versionRecipient() view returns (string)', - 'function withdraw(uint256 amount, address target)', - 'function withdrawRelayHubDeposit(uint256 amount, address target)', - 'function withdrawToken(address token, uint256 amount, address target)', - 'function wrappedChainToken() view returns (address)', - ], - NATIVE_USDC_CONTRACT_ABI: [ 'event Approval(address indexed owner, address indexed spender, uint256 value)', 'event AuthorizationCanceled(address indexed authorizer, bytes32 indexed nonce)', @@ -248,6 +192,62 @@ const PolygonContractABIsFull = { // eslint-disable-line no-unused-vars 'function wrappedChainToken() view returns (address)', ], + NATIVE_USDC_HTLC_CONTRACT_ABI: [ + 'constructor()', + 'event DomainRegistered(bytes32 indexed domainSeparator, bytes domainValue)', + 'event Open(bytes32 indexed id, address token, uint256 amount, address recipient, bytes32 hash, uint256 timeout)', + 'event OwnershipTransferred(address indexed previousOwner, address indexed newOwner)', + 'event Redeem(bytes32 indexed id, bytes32 secret)', + 'event Refund(bytes32 indexed id)', + 'event RequestTypeRegistered(bytes32 indexed typeHash, string typeStr)', + 'function EIP712_DOMAIN_TYPE() view returns (string)', + 'function deposits(address) view returns (uint256)', + 'function domains(bytes32) view returns (bool)', + 'function execute(tuple(address from, address to, uint256 value, uint256 gas, uint256 nonce, bytes data, uint256 validUntil) request, bytes32 domainSeparator, bytes32 requestTypeHash, bytes suffixData, bytes signature) payable returns (bool success, bytes ret)', + 'function getGasAndDataLimits() view returns (tuple(uint256 acceptanceBudget, uint256 preRelayedCallGasLimit, uint256 postRelayedCallGasLimit, uint256 calldataSizeLimit) limits)', + 'function getHubAddr() view returns (address)', + 'function getMinimumRelayFee(tuple(uint256 gasPrice, uint256 pctRelayFee, uint256 baseRelayFee, address relayWorker, address paymaster, address forwarder, bytes paymasterData, uint256 clientId) relayData) view returns (uint256 amount)', + 'function getNonce(address from) view returns (uint256)', + 'function getRelayHubDeposit() view returns (uint256)', + 'function getRequiredRelayFee(tuple(uint256 gasPrice, uint256 pctRelayFee, uint256 baseRelayFee, address relayWorker, address paymaster, address forwarder, bytes paymasterData, uint256 clientId) relayData, bytes4 methodId) view returns (uint256 amount)', + 'function getRequiredRelayGas(bytes4 methodId) view returns (uint256 gas)', + 'function htlcs(bytes32) view returns (address token, uint256 amount, address refund, address recipient, bytes32 hash, uint256 timeout)', + 'function isTrustedForwarder(address forwarder) view returns (bool)', + 'function open(bytes32 id, address token, uint256 amount, address refundAddress, address recipientAddress, bytes32 hash, uint256 timeout, uint256 fee)', + 'function openWithPermit(bytes32 id, address token, uint256 amount, address refundAddress, address recipientAddress, bytes32 hash, uint256 timeout, uint256 fee, uint256 value, bytes32 sigR, bytes32 sigS, uint8 sigV)', + 'function owner() view returns (address)', + 'function postRelayedCall(bytes context, bool success, uint256 gasUseWithoutPost, tuple(uint256 gasPrice, uint256 pctRelayFee, uint256 baseRelayFee, address relayWorker, address paymaster, address forwarder, bytes paymasterData, uint256 clientId) relayData)', + 'function preRelayedCall(tuple(tuple(address from, address to, uint256 value, uint256 gas, uint256 nonce, bytes data, uint256 validUntil) request, tuple(uint256 gasPrice, uint256 pctRelayFee, uint256 baseRelayFee, address relayWorker, address paymaster, address forwarder, bytes paymasterData, uint256 clientId) relayData) relayRequest, bytes signature, bytes approvalData, uint256 maxPossibleGas) returns (bytes context, bool revertOnRecipientRevert)', + 'function redeem(bytes32 id, address target, bytes32 secret, uint256 fee)', + 'function redeemWithSecretInData(bytes32 id, address target, uint256 fee)', + 'function refund(bytes32 id, address target, uint256 fee)', + 'function registerDomainSeparator(string name, string version)', + 'function registerRequestType(string typeName, string typeSuffix)', + 'function registerToken(address token, address pool)', + 'function registeredTokenPool(address) view returns (address)', + 'function registeredTokenPoolFee(address token) view returns (uint24 fee)', + 'function relayWithoutGsn(tuple(tuple(address from, address to, uint256 value, uint256 gas, uint256 nonce, bytes data, uint256 validUntil) request, tuple(uint256 gasPrice, uint256 pctRelayFee, uint256 baseRelayFee, address relayWorker, address paymaster, address forwarder, bytes paymasterData, uint256 clientId) relayData) relayRequest, bytes signature, bytes approvalData, address relay)', + 'function renounceOwnership()', + 'function requiredRelayGas() view returns (uint256)', + 'function setGasAndDataLimits(tuple(uint256 acceptanceBudget, uint256 preRelayedCallGasLimit, uint256 postRelayedCallGasLimit, uint256 calldataSizeLimit) limits)', + 'function setMaxRequiredRelayGas(uint256 gas)', + 'function setRelayHub(address hub)', + 'function setRequiredRelayGas(bytes4 methodId, uint256 gas)', + 'function setWrappedChainToken(address _wrappedChainToken)', + 'function transferOwnership(address newOwner)', + 'function trustedForwarder() view returns (address forwarder)', + 'function typeHashes(bytes32) view returns (bool)', + 'function uniswapV3SwapCallback(int256 amount0Delta, int256 amount1Delta, bytes _data)', + 'function unregisterToken(address token)', + 'function verify(tuple(address from, address to, uint256 value, uint256 gas, uint256 nonce, bytes data, uint256 validUntil) forwardRequest, bytes32 domainSeparator, bytes32 requestTypeHash, bytes suffixData, bytes signature) view', + 'function versionPaymaster() view returns (string)', + 'function versionRecipient() view returns (string)', + 'function withdraw(uint256 amount, address target)', + 'function withdrawRelayHubDeposit(uint256 amount, address target)', + 'function withdrawToken(address token, uint256 amount, address target)', + 'function wrappedChainToken() view returns (address)', + ], + SWAP_CONTRACT_ABI: [ "constructor()", "event DomainRegistered(bytes32 indexed domainSeparator, bytes domainValue)", diff --git a/src/lib/polygon/PolygonContractABIs.js b/src/lib/polygon/PolygonContractABIs.js index 767c59967..04e77125c 100644 --- a/src/lib/polygon/PolygonContractABIs.js +++ b/src/lib/polygon/PolygonContractABIs.js @@ -4,14 +4,6 @@ const PolygonContractABIs = { // eslint-disable-line no-unused-vars 'function approve(address spender, uint256 amount) returns (bool)', ], - BRIDGED_USDC_HTLC_CONTRACT_ABI: [ - 'function open(bytes32 id, address token, uint256 amount, address refundAddress, address recipientAddress, bytes32 hash, uint256 timeout, uint256 fee)', - 'function openWithApproval(bytes32 id, address token, uint256 amount, address refundAddress, address recipientAddress, bytes32 hash, uint256 timeout, uint256 fee, uint256 approval, bytes32 sigR, bytes32 sigS, uint8 sigV)', - 'function redeem(bytes32 id, address target, bytes32 secret, uint256 fee)', - 'function redeemWithSecretInData(bytes32 id, address target, uint256 fee)', - 'function refund(bytes32 id, address target, uint256 fee)', - ], - NATIVE_USDC_CONTRACT_ABI: [], NATIVE_USDC_TRANSFER_CONTRACT_ABI: [ @@ -19,6 +11,14 @@ const PolygonContractABIs = { // eslint-disable-line no-unused-vars 'function transferWithPermit(address token, uint256 amount, address target, uint256 fee, uint256 value, bytes32 sigR, bytes32 sigS, uint8 sigV)', ], + NATIVE_USDC_HTLC_CONTRACT_ABI: [ + 'function open(bytes32 id, address token, uint256 amount, address refundAddress, address recipientAddress, bytes32 hash, uint256 timeout, uint256 fee)', + 'function openWithPermit(bytes32 id, address token, uint256 amount, address refundAddress, address recipientAddress, bytes32 hash, uint256 timeout, uint256 fee, uint256 value, bytes32 sigR, bytes32 sigS, uint8 sigV)', + 'function redeem(bytes32 id, address target, bytes32 secret, uint256 fee)', + 'function redeemWithSecretInData(bytes32 id, address target, uint256 fee)', + 'function refund(bytes32 id, address target, uint256 fee)', + ], + SWAP_CONTRACT_ABI: [ 'function swap(address token, uint256 amount, address pool, uint256 targetAmount, uint256 fee)', 'function swapWithApproval(address token, uint256 amount, address pool, uint256 targetAmount, uint256 fee, uint256 approval, bytes32 sigR, bytes32 sigS, uint8 sigV)', diff --git a/src/lib/swap/CryptoUtils.js b/src/lib/swap/CryptoUtils.js index 954e3f83c..65e0d68d8 100644 --- a/src/lib/swap/CryptoUtils.js +++ b/src/lib/swap/CryptoUtils.js @@ -8,7 +8,7 @@ class CryptoUtils { // eslint-disable-line no-unused-vars /** - * @param {'NIM' | 'BTC' | 'USDC' | 'EUR'} asset + * @param {'NIM' | 'BTC' | 'USDC_MATIC' | 'EUR'} asset * @param {number} units * @returns {number} */ @@ -16,23 +16,42 @@ class CryptoUtils { // eslint-disable-line no-unused-vars switch (asset) { case 'NIM': return Nimiq.Policy.lunasToCoins(units); case 'BTC': return BitcoinUtils.satoshisToCoins(units); - case 'USDC': return PolygonUtils.unitsToCoins(units); + case 'USDC_MATIC': return PolygonUtils.unitsToCoins(units); case 'EUR': return EuroUtils.centsToCoins(units); default: throw new Error(`Invalid asset ${asset}`); } } /** - * @param {'NIM' | 'BTC' | 'USDC' | 'EUR'} asset + * @param {'NIM' | 'BTC' | 'USDC_MATIC' | 'EUR'} asset * @returns {number} */ static assetDecimals(asset) { switch (asset) { case 'NIM': return Math.log10(Nimiq.Policy.LUNAS_PER_COIN); case 'BTC': return Math.log10(BitcoinConstants.SATOSHIS_PER_COIN); - case 'USDC': return Math.log10(PolygonConstants.UNITS_PER_COIN); + case 'USDC_MATIC': return Math.log10(PolygonConstants.UNITS_PER_COIN); case 'EUR': return Math.log10(EuroConstants.CENTS_PER_COIN); default: throw new Error(`Invalid asset ${asset}`); } } + + /** + * @param {'NIM' | 'BTC' | 'USDC_MATIC' | 'EUR'} asset + * @returns {'nim' | 'btc' | 'usdc' | 'eur'} + */ + static assetToCurrency(asset) { + switch (asset) { + case 'NIM': + return 'nim'; + case 'BTC': + return 'btc'; + case 'USDC_MATIC': + return 'usdc'; + case 'EUR': + return 'eur'; + default: + throw new Error('Invalid asset'); + } + } } diff --git a/src/request/sign-polygon-transaction/SignPolygonTransactionApi.js b/src/request/sign-polygon-transaction/SignPolygonTransactionApi.js index ff6669726..a9eba546e 100644 --- a/src/request/sign-polygon-transaction/SignPolygonTransactionApi.js +++ b/src/request/sign-polygon-transaction/SignPolygonTransactionApi.js @@ -95,10 +95,10 @@ class SignPolygonTransactionApi extends PolygonRequestParserMixin(TopLevelApi) { if (!['transfer', 'transferWithPermit'].includes(description.name)) { throw new Errors.InvalidRequestError('Requested Polygon contract method is invalid'); } - } else if (forwardRequest.to === CONFIG.BRIDGED_USDC_HTLC_CONTRACT_ADDRESS) { + } else if (forwardRequest.to === CONFIG.NATIVE_USDC_HTLC_CONTRACT_ADDRESS) { const usdcHtlcContract = new ethers.Contract( - CONFIG.BRIDGED_USDC_HTLC_CONTRACT_ADDRESS, - PolygonContractABIs.BRIDGED_USDC_HTLC_CONTRACT_ABI, + CONFIG.NATIVE_USDC_HTLC_CONTRACT_ADDRESS, + PolygonContractABIs.NATIVE_USDC_HTLC_CONTRACT_ABI, ); /** @type {PolygonRefundDescription} */ @@ -137,9 +137,11 @@ class SignPolygonTransactionApi extends PolygonRequestParserMixin(TopLevelApi) { const targetAmount = /** @type {PolygonSwapDescription | PolygonSwapWithApprovalDescription} */ (description) // eslint-disable-line max-len .args .targetAmount; - if (targetAmount.lt(inputAmount.mul(99).div(100))) { + // Allow 1% slippage for swaps on Polygon mainnet, but up to 5% for testnet + const minTargetAmountPercentile = CONFIG.POLYGON_CHAIN_ID === 137 ? 99 : 95; + if (targetAmount.lt(inputAmount.mul(minTargetAmountPercentile).div(100))) { throw new Errors.InvalidRequestError( - 'Requested Polygon swap `targetAmount` more than 1% lower than the input `amount`', + 'Requested USDC swap `targetAmount` is too low', ); } } else { diff --git a/src/request/sign-swap/SignSwap.js b/src/request/sign-swap/SignSwap.js index 4047c7c3b..3c6897653 100644 --- a/src/request/sign-swap/SignSwap.js +++ b/src/request/sign-swap/SignSwap.js @@ -83,7 +83,7 @@ class SignSwap { case 'NIM': swapFromValue = fundTx.transaction.value + fundTx.transaction.fee; break; case 'BTC': swapFromValue = fundTx.inputs.reduce((sum, input) => sum + input.witnessUtxo.value, 0) - (fundTx.changeOutput ? fundTx.changeOutput.value : 0); break; - case 'USDC': swapFromValue = fundTx.description.args.amount + case 'USDC_MATIC': swapFromValue = fundTx.description.args.amount .add(fundTx.description.args.fee).toNumber(); break; case 'EUR': swapFromValue = fundTx.amount + fundTx.fee; break; default: throw new Errors.KeyguardError('Invalid asset'); @@ -94,7 +94,7 @@ class SignSwap { switch (redeemTx.type) { case 'NIM': swapToValue = redeemTx.transaction.value; break; case 'BTC': swapToValue = redeemTx.output.value; break; - case 'USDC': swapToValue = redeemTx.amount; break; + case 'USDC_MATIC': swapToValue = redeemTx.amount; break; case 'EUR': swapToValue = redeemTx.amount - redeemTx.fee; break; default: throw new Errors.KeyguardError('Invalid asset'); } @@ -111,19 +111,21 @@ class SignSwap { $swapLeftValue.textContent = NumberFormatting.formatNumber( CryptoUtils.unitsToCoins(leftAsset, leftAmount), - leftAsset === 'USDC' ? 2 : CryptoUtils.assetDecimals(leftAsset), - leftAsset === 'EUR' || leftAsset === 'USDC' ? 2 : 0, + leftAsset === 'USDC_MATIC' ? 2 : CryptoUtils.assetDecimals(leftAsset), + leftAsset === 'EUR' || leftAsset === 'USDC_MATIC' ? 2 : 0, ); $swapRightValue.textContent = NumberFormatting.formatNumber( CryptoUtils.unitsToCoins(rightAsset, rightAmount), - rightAsset === 'USDC' ? 2 : CryptoUtils.assetDecimals(rightAsset), - rightAsset === 'EUR' || rightAsset === 'USDC' ? 2 : 0, + rightAsset === 'USDC_MATIC' ? 2 : CryptoUtils.assetDecimals(rightAsset), + rightAsset === 'EUR' || rightAsset === 'USDC_MATIC' ? 2 : 0, ); - $swapValues.classList.add(`${fundTx.type.toLowerCase()}-to-${redeemTx.type.toLowerCase()}`); + $swapValues.classList.add( + `${CryptoUtils.assetToCurrency(fundTx.type)}-to-${CryptoUtils.assetToCurrency(redeemTx.type)}`, + ); - /** @type {'NIM' | 'BTC' | 'USDC' | 'EUR'} */ + /** @type {'NIM' | 'BTC' | 'USDC_MATIC' | 'EUR'} */ let exchangeBaseAsset; // If EUR is part of the swap, the other currency is the base asset if (fundTx.type === 'EUR') exchangeBaseAsset = redeemTx.type; @@ -177,8 +179,8 @@ class SignSwap { ); if (request.layout === SignSwapApi.Layouts.STANDARD) { - $leftAccount.classList.add(request.fund.type.toLocaleLowerCase()); - $rightAccount.classList.add(request.redeem.type.toLocaleLowerCase()); + $leftAccount.classList.add(CryptoUtils.assetToCurrency(request.fund.type)); + $rightAccount.classList.add(CryptoUtils.assetToCurrency(request.redeem.type)); // Add ticker symbols /** @type {HTMLSpanElement} */ @@ -186,8 +188,8 @@ class SignSwap { /** @type {HTMLSpanElement} */ const $toSymbol = (this.$el.querySelector('.swap-values .to-symbol')); - $fromSymbol.classList.add(`${request.fund.type.toLowerCase()}-symbol`); - $toSymbol.classList.add(`${request.redeem.type.toLowerCase()}-symbol`); + $fromSymbol.classList.add(`${CryptoUtils.assetToCurrency(request.fund.type)}-symbol`); + $toSymbol.classList.add(`${CryptoUtils.assetToCurrency(request.redeem.type)}-symbol`); if (request.fund.type === 'NIM') { const address = request.fund.transaction.sender.toUserFriendlyAddress(); @@ -196,7 +198,7 @@ class SignSwap { } else if (request.fund.type === 'BTC') { $leftIdenticon.innerHTML = TemplateTags.hasVars(0)``; $leftLabel.textContent = I18n.translatePhrase('bitcoin'); - } else if (request.fund.type === 'USDC') { + } else if (request.fund.type === 'USDC_MATIC') { $leftIdenticon.innerHTML = TemplateTags.hasVars(0)``; $leftLabel.textContent = I18n.translatePhrase('usd-coin'); } else if (request.fund.type === 'EUR') { @@ -211,7 +213,7 @@ class SignSwap { } else if (request.redeem.type === 'BTC') { $rightIdenticon.innerHTML = TemplateTags.hasVars(0)``; $rightLabel.textContent = I18n.translatePhrase('bitcoin'); - } else if (request.redeem.type === 'USDC') { + } else if (request.redeem.type === 'USDC_MATIC') { $rightIdenticon.innerHTML = TemplateTags.hasVars(0)``; $rightLabel.textContent = I18n.translatePhrase('usd-coin'); } else if (request.redeem.type === 'EUR') { @@ -242,8 +244,8 @@ class SignSwap { /** @type {HTMLSpanElement} */ const $swapRightSymbol = (this.$el.querySelector('#swap-right-symbol')); - $swapLeftSymbol.classList.add(`${leftAsset.toLowerCase()}-symbol`); - $swapRightSymbol.classList.add(`${rightAsset.toLowerCase()}-symbol`); + $swapLeftSymbol.classList.add(`${CryptoUtils.assetToCurrency(leftAsset)}-symbol`); + $swapRightSymbol.classList.add(`${CryptoUtils.assetToCurrency(rightAsset)}-symbol`); /** @type {string | undefined} */ let swapNimAddress; @@ -269,10 +271,10 @@ class SignSwap { (leftAsset === 'BTC' ? $leftLabel : $rightLabel).textContent = I18n.translatePhrase('bitcoin'); } - if (leftAsset === 'USDC' || rightAsset === 'USDC') { - (leftAsset === 'USDC' ? $leftIdenticon : $rightIdenticon) + if (leftAsset === 'USDC_MATIC' || rightAsset === 'USDC_MATIC') { + (leftAsset === 'USDC_MATIC' ? $leftIdenticon : $rightIdenticon) .innerHTML = TemplateTags.hasVars(0)``; - (leftAsset === 'USDC' ? $leftLabel : $rightLabel).textContent = I18n.translatePhrase('usd-coin'); + (leftAsset === 'USDC_MATIC' ? $leftLabel : $rightLabel).textContent = I18n.translatePhrase('usd-coin'); } // Add signs in front of swap amounts @@ -363,19 +365,19 @@ class SignSwap { else rightSegments = segments; } - if (leftAsset === 'USDC' || rightAsset === 'USDC') { - const amount = leftAsset === 'USDC' ? leftAmount : rightAmount; + if (leftAsset === 'USDC_MATIC' || rightAsset === 'USDC_MATIC') { + const amount = leftAsset === 'USDC_MATIC' ? leftAmount : rightAmount; const newBalance = request.polygonAddresses[0].usdcBalance - + (amount * (fundTx.type === 'USDC' ? -1 : 1)); + + (amount * (fundTx.type === 'USDC_MATIC' ? -1 : 1)); const newBalanceFormatted = NumberFormatting.formatNumber( - CryptoUtils.unitsToCoins('USDC', newBalance), 2, 2, + CryptoUtils.unitsToCoins('USDC_MATIC', newBalance), 2, 2, ); - if (leftAsset === 'USDC') { + if (leftAsset === 'USDC_MATIC') { $leftNewBalance.textContent = `${newBalanceFormatted} USDC`; $leftAccount.classList.add('usdc'); - } else if (rightAsset === 'USDC') { + } else if (rightAsset === 'USDC_MATIC') { $rightNewBalance.textContent = `${newBalanceFormatted} USDC`; $rightAccount.classList.add('usdc'); } @@ -388,7 +390,7 @@ class SignSwap { newBalance, }]; - if (leftAsset === 'USDC') leftSegments = segments; + if (leftAsset === 'USDC_MATIC') leftSegments = segments; else rightSegments = segments; } @@ -425,7 +427,7 @@ class SignSwap { } /** - * @param {'NIM' | 'BTC' | 'USDC' | 'EUR'} asset + * @param {'NIM' | 'BTC' | 'USDC_MATIC' | 'EUR'} asset * @param {Parsed} request * @returns {number} */ @@ -452,11 +454,11 @@ class SignSwap { // The HTLC balance is represented by the redeeming tx input value. ? redeemTx.input.witnessUtxo.value + request.redeemFees.funding : 0; // Should never happen, if parsing works correctly - case 'USDC': - return fundTx.type === 'USDC' + case 'USDC_MATIC': + return fundTx.type === 'USDC_MATIC' // When the user funds USDC, the service receives the HTLC balance - their network fee. ? fundTx.description.args.amount.toNumber() - request.fundFees.redeeming - : redeemTx.type === 'USDC' + : redeemTx.type === 'USDC_MATIC' // When the user redeems USDC, the service lost the HTLC balance + their network fee. // The transaction value is "HTLC balance - tx fee", therefore the "HTLC balance" // is the transaction value + tx fee. @@ -544,24 +546,20 @@ class SignSwap { request.fund.refundAddress = bitcoinKey.deriveAddress(request.fund.refundKeyPath); } - if (request.fund.type === 'USDC') { - if (request.fund.description.name === 'openWithApproval') { - const { sigR, sigS, sigV } = await polygonKey.signUsdcApproval( + if (request.fund.type === 'USDC_MATIC') { + if (request.fund.description.name === 'openWithPermit') { + const { sigR, sigS, sigV } = await polygonKey.signUsdcPermit( request.fund.keyPath, - new ethers.Contract( - CONFIG.BRIDGED_USDC_CONTRACT_ADDRESS, - PolygonContractABIs.BRIDGED_USDC_CONTRACT_ABI, - ), - CONFIG.BRIDGED_USDC_HTLC_CONTRACT_ADDRESS, - request.fund.description.args.approval, - // Has been validated to be defined when function called is `openWithApproval` - /** @type {{ tokenNonce: number }} */ (request.fund.approval).tokenNonce, + CONFIG.NATIVE_USDC_HTLC_CONTRACT_ADDRESS, + request.fund.description.args.value, + // Has been validated to be defined when function called is `openWithPermit` + /** @type {{ tokenNonce: number }} */ (request.fund.permit).tokenNonce, request.fund.request.from, ); const htlcContract = new ethers.Contract( - CONFIG.BRIDGED_USDC_HTLC_CONTRACT_ADDRESS, - PolygonContractABIs.BRIDGED_USDC_HTLC_CONTRACT_ABI, + CONFIG.NATIVE_USDC_HTLC_CONTRACT_ADDRESS, + PolygonContractABIs.NATIVE_USDC_HTLC_CONTRACT_ABI, ); request.fund.request.data = htlcContract.interface.encodeFunctionData(request.fund.description.name, [ @@ -573,7 +571,7 @@ class SignSwap { /* bytes32 hash */ request.fund.description.args.hash, /* uint256 timeout */ request.fund.description.args.timeout, /* uint256 fee */ request.fund.description.args.fee, - /* uint256 approval */ request.fund.description.args.approval, + /* uint256 value */ request.fund.description.args.value, /* bytes32 sigR */ sigR, /* bytes32 sigS */ sigS, /* uint8 sigV */ sigV, @@ -608,7 +606,7 @@ class SignSwap { request.redeem.output.address = address; } - if (request.redeem.type === 'USDC') { + if (request.redeem.type === 'USDC_MATIC') { const wallet = polygonKey.deriveKeyPair(request.redeem.keyPath); privateKeys.usdc = wallet.privateKey; } diff --git a/src/request/sign-swap/SignSwapApi.js b/src/request/sign-swap/SignSwapApi.js index 3baa8329e..368c03953 100644 --- a/src/request/sign-swap/SignSwapApi.js +++ b/src/request/sign-swap/SignSwapApi.js @@ -73,20 +73,20 @@ class SignSwapApi extends PolygonRequestParserMixin(BitcoinRequestParserMixin(To throw new Errors.InvalidRequestError('For locktime to be effective, at least one input must have a ' + 'sequence number < 0xffffffff'); } - } else if (request.fund.type === 'USDC') { + } else if (request.fund.type === 'USDC_MATIC') { const [forwardRequest, description] = this.parseOpenGsnForwardRequest( request.fund, - ['open', 'openWithApproval'], + ['open', 'openWithPermit'], ); parsedRequest.fund = { - type: 'USDC', + type: 'USDC_MATIC', keyPath: this.parsePolygonPath(request.fund.keyPath, 'fund.keyPath'), // eslint-disable-next-line object-shorthand - description: /** @type {PolygonOpenDescription | PolygonOpenWithApprovalDescription} */ (description), + description: /** @type {PolygonOpenDescription | PolygonOpenWithPermitDescription} */ (description), request: forwardRequest, relayData: this.parseOpenGsnRelayData(request.fund.relayData), - approval: request.fund.approval, + permit: request.fund.permit, }; } else if (request.fund.type === 'EUR') { parsedRequest.fund = { @@ -128,14 +128,14 @@ class SignSwapApi extends PolygonRequestParserMixin(BitcoinRequestParserMixin(To request.redeem.output, false, 'redeem.output', )), }; - } else if (request.redeem.type === 'USDC') { + } else if (request.redeem.type === 'USDC_MATIC') { const [forwardRequest, description] = this.parseOpenGsnForwardRequest( request.redeem, ['redeem', 'redeemWithSecretInData'], ); parsedRequest.redeem = { - type: 'USDC', + type: 'USDC_MATIC', keyPath: this.parsePolygonPath(request.redeem.keyPath, 'fund.keyPath'), // eslint-disable-next-line object-shorthand description: /** @type {PolygonRedeemDescription | PolygonRedeemWithSecretInDataDescription} */ @@ -182,7 +182,7 @@ class SignSwapApi extends PolygonRequestParserMixin(BitcoinRequestParserMixin(To if (request.layout === SignSwapApi.Layouts.SLIDER && parsedRequest.layout === SignSwapApi.Layouts.SLIDER) { // SLIDER layout is only allowed for crypto-to-crypto swaps - const assets = ['NIM', 'BTC', 'USDC']; + const assets = ['NIM', 'BTC', 'USDC_MATIC']; if (!assets.includes(parsedRequest.fund.type) || !assets.includes(parsedRequest.redeem.type)) { throw new Errors.InvalidRequestError( 'The \'slider\' layout is only allowed for swaps between NIM, BTC and USDC', @@ -227,9 +227,9 @@ class SignSwapApi extends PolygonRequestParserMixin(BitcoinRequestParserMixin(To } // Verify that used Polygon address is in polygonAddresses[] and has enough balance - const polygonAddress = parsedRequest.fund.type === 'USDC' + const polygonAddress = parsedRequest.fund.type === 'USDC_MATIC' ? parsedRequest.fund.request.from - : parsedRequest.redeem.type === 'USDC' + : parsedRequest.redeem.type === 'USDC_MATIC' // Even for redeeming, the user's address is the `from` address, // because in EVM, redeeming is still an interaction with a contract. // Triggering the payout means calling a function on the HTLC contract, @@ -245,7 +245,7 @@ class SignSwapApi extends PolygonRequestParserMixin(BitcoinRequestParserMixin(To 'The address details of the Polygon address doing the swap must be provided', ); } else if ( - parsedRequest.fund.type === 'USDC' + parsedRequest.fund.type === 'USDC_MATIC' && activePolygonAddress.usdcBalance < parsedRequest.fund.description.args.amount .add(parsedRequest.fund.description.args.fee).toNumber() ) { @@ -307,12 +307,12 @@ class SignSwapApi extends PolygonRequestParserMixin(BitcoinRequestParserMixin(To // eslint-disable-next-line valid-jsdoc /** * - * @param {KeyguardRequest.PolygonTransactionInfo} request - * @param {Array<'open' | 'openWithApproval' | 'redeem' | 'redeemWithSecretInData'>} allowedMethods + * @param {Omit} request + * @param {Array<'open' | 'openWithPermit' | 'redeem' | 'redeemWithSecretInData'>} allowedMethods * @returns {[ * KeyguardRequest.OpenGsnForwardRequest, * PolygonOpenDescription - * | PolygonOpenWithApprovalDescription + * | PolygonOpenWithPermitDescription * | PolygonRedeemDescription * | PolygonRedeemWithSecretInDataDescription, * ]} @@ -320,19 +320,19 @@ class SignSwapApi extends PolygonRequestParserMixin(BitcoinRequestParserMixin(To parseOpenGsnForwardRequest(request, allowedMethods) { const forwardRequest = this.parseOpenGsnForwardRequestRoot(request.request); - if (forwardRequest.to !== CONFIG.BRIDGED_USDC_HTLC_CONTRACT_ADDRESS) { + if (forwardRequest.to !== CONFIG.NATIVE_USDC_HTLC_CONTRACT_ADDRESS) { throw new Errors.InvalidRequestError('request.to address is not allowed'); } const usdcHtlcContract = new ethers.Contract( - CONFIG.BRIDGED_USDC_HTLC_CONTRACT_ADDRESS, - PolygonContractABIs.BRIDGED_USDC_HTLC_CONTRACT_ABI, + CONFIG.NATIVE_USDC_HTLC_CONTRACT_ADDRESS, + PolygonContractABIs.NATIVE_USDC_HTLC_CONTRACT_ABI, ); // eslint-disable-next-line operator-linebreak const description = /** @type {PolygonOpenDescription - * | PolygonOpenWithApprovalDescription + * | PolygonOpenWithPermitDescription * | PolygonRedeemDescription * | PolygonRedeemWithSecretInDataDescription} */ (usdcHtlcContract.interface.parseTransaction({ @@ -344,8 +344,8 @@ class SignSwapApi extends PolygonRequestParserMixin(BitcoinRequestParserMixin(To throw new Errors.InvalidRequestError('Requested Polygon contract method is invalid'); } - if (description.name === 'open' || description.name === 'openWithApproval') { - if (description.args.token !== CONFIG.BRIDGED_USDC_CONTRACT_ADDRESS) { + if (description.name === 'open' || description.name === 'openWithPermit') { + if (description.args.token !== CONFIG.NATIVE_USDC_CONTRACT_ADDRESS) { throw new Errors.InvalidRequestError('Invalid USDC token contract in request data'); } @@ -360,10 +360,10 @@ class SignSwapApi extends PolygonRequestParserMixin(BitcoinRequestParserMixin(To } } - // Check that approval object exists when method is 'openWithApproval', and unset for other methods. - if ((description.name === 'openWithApproval') !== !!request.approval) { - throw new Errors.InvalidRequestError('`approval` object is only allowed for contract method ' - + '"openWithApproval"'); + // Check that permit object exists when method is 'openWithPermit', and unset for other methods. + if ((description.name === 'openWithPermit') !== !!request.permit) { + throw new Errors.InvalidRequestError('`permit` object is only allowed for contract method ' + + '"openWithPermit"'); } return [forwardRequest, description]; diff --git a/src/request/swap-iframe/SwapIFrameApi.js b/src/request/swap-iframe/SwapIFrameApi.js index 5f02cc55d..973ab2e77 100644 --- a/src/request/swap-iframe/SwapIFrameApi.js +++ b/src/request/swap-iframe/SwapIFrameApi.js @@ -62,7 +62,7 @@ class SwapIFrameApi extends BitcoinRequestParserMixin(RequestParser) { // eslint } } - if (request.fund.type === 'USDC' || request.redeem.type === 'USDC') { + if (request.fund.type === 'USDC_MATIC' || request.redeem.type === 'USDC_MATIC') { if (!privateKeys.usdc) throw new Error('No USDC key stored in SessionStorage'); if (privateKeys.usdc.length !== 66) throw new Error('Invalid USDC key stored in SessionStorage'); } @@ -85,10 +85,10 @@ class SwapIFrameApi extends BitcoinRequestParserMixin(RequestParser) { // eslint ); } } - if (storedRawRequest.fund.type === 'USDC') { + if (storedRawRequest.fund.type === 'USDC_MATIC') { const usdcHtlcContract = new ethers.Contract( - CONFIG.BRIDGED_USDC_HTLC_CONTRACT_ADDRESS, - PolygonContractABIs.BRIDGED_USDC_HTLC_CONTRACT_ABI, + CONFIG.NATIVE_USDC_HTLC_CONTRACT_ADDRESS, + PolygonContractABIs.NATIVE_USDC_HTLC_CONTRACT_ABI, ); storedRawRequest.fund.description = usdcHtlcContract.interface.parseTransaction({ @@ -100,10 +100,10 @@ class SwapIFrameApi extends BitcoinRequestParserMixin(RequestParser) { // eslint if (storedRawRequest.redeem.type === 'NIM') { storedRawRequest.redeem.transaction = Nimiq.Transaction.fromPlain(storedRawRequest.redeem.transaction); } - if (storedRawRequest.redeem.type === 'USDC') { + if (storedRawRequest.redeem.type === 'USDC_MATIC') { const usdcHtlcContract = new ethers.Contract( - CONFIG.BRIDGED_USDC_HTLC_CONTRACT_ADDRESS, - PolygonContractABIs.BRIDGED_USDC_HTLC_CONTRACT_ABI, + CONFIG.NATIVE_USDC_HTLC_CONTRACT_ADDRESS, + PolygonContractABIs.NATIVE_USDC_HTLC_CONTRACT_ABI, ); storedRawRequest.redeem.description = usdcHtlcContract.interface.parseTransaction({ @@ -224,10 +224,10 @@ class SwapIFrameApi extends BitcoinRequestParserMixin(RequestParser) { // eslint }; } - if (request.fund.type === 'USDC' && storedRequest.fund.type === 'USDC') { + if (request.fund.type === 'USDC_MATIC' && storedRequest.fund.type === 'USDC_MATIC') { const usdcHtlcContract = new ethers.Contract( - CONFIG.BRIDGED_USDC_HTLC_CONTRACT_ADDRESS, - PolygonContractABIs.BRIDGED_USDC_HTLC_CONTRACT_ABI, + CONFIG.NATIVE_USDC_HTLC_CONTRACT_ADDRESS, + PolygonContractABIs.NATIVE_USDC_HTLC_CONTRACT_ABI, ); const description = /** @type {PolygonOpenDescription} */ (usdcHtlcContract.interface.parseTransaction({ @@ -236,14 +236,14 @@ class SwapIFrameApi extends BitcoinRequestParserMixin(RequestParser) { // eslint })); // The htlcData given by Fastspot and forwarded here is always for the open() function, not for - // openWithApproval(). The approval, if requested, is added below, from the stored request where + // openWithPermit(). The permit, if requested, is added below, from the stored request where // the user gave their authorization. if (description.name !== 'open') { throw new Errors.InvalidRequestError('Invalid method in HTLC data'); } // Verify already known parts of the data - if (description.args.token !== CONFIG.BRIDGED_USDC_CONTRACT_ADDRESS) { + if (description.args.token !== CONFIG.NATIVE_USDC_CONTRACT_ADDRESS) { throw new Errors.InvalidRequestError('Invalid USDC token contract in HTLC data'); } @@ -256,14 +256,14 @@ class SwapIFrameApi extends BitcoinRequestParserMixin(RequestParser) { // eslint } fund = { - type: 'USDC', + type: 'USDC_MATIC', description, }; } - if (request.redeem.type === 'USDC' && storedRequest.redeem.type === 'USDC') { + if (request.redeem.type === 'USDC_MATIC' && storedRequest.redeem.type === 'USDC_MATIC') { redeem = { - type: 'USDC', + type: 'USDC_MATIC', htlcId: `0x${Nimiq.BufferUtils.toHex(Nimiq.BufferUtils.fromAny( request.redeem.htlcId.replace(/^0x/i, ''), ))}`, @@ -544,10 +544,10 @@ class SwapIFrameApi extends BitcoinRequestParserMixin(RequestParser) { // eslint } } - if (parsedRequest.fund.type === 'USDC' && storedRequest.fund.type === 'USDC') { + if (parsedRequest.fund.type === 'USDC_MATIC' && storedRequest.fund.type === 'USDC_MATIC') { const usdcHtlcContract = new ethers.Contract( - CONFIG.BRIDGED_USDC_HTLC_CONTRACT_ADDRESS, - PolygonContractABIs.BRIDGED_USDC_HTLC_CONTRACT_ABI, + CONFIG.NATIVE_USDC_HTLC_CONTRACT_ADDRESS, + PolygonContractABIs.NATIVE_USDC_HTLC_CONTRACT_ABI, ); // Place contract details into existing function call data @@ -563,8 +563,8 @@ class SwapIFrameApi extends BitcoinRequestParserMixin(RequestParser) { // eslint /* uint256 timeout */ parsedRequest.fund.description.args.timeout, /* uint256 fee */ storedRequest.fund.description.args.fee, - ...(storedRequest.fund.description.name === 'openWithApproval' ? [ - /* uint256 approval */ storedRequest.fund.description.args.approval, + ...(storedRequest.fund.description.name === 'openWithPermit' ? [ + /* uint256 value */ storedRequest.fund.description.args.value, /* bytes32 sigR */ storedRequest.fund.description.args.sigR, /* bytes32 sigS */ storedRequest.fund.description.args.sigS, /* uint8 sigV */ storedRequest.fund.description.args.sigV, @@ -574,7 +574,7 @@ class SwapIFrameApi extends BitcoinRequestParserMixin(RequestParser) { // eslint const typedData = new OpenGSN.TypedRequestData( CONFIG.POLYGON_CHAIN_ID, - CONFIG.BRIDGED_USDC_HTLC_CONTRACT_ADDRESS, + CONFIG.NATIVE_USDC_HTLC_CONTRACT_ADDRESS, { request: storedRequest.fund.request, relayData: storedRequest.fund.relayData, @@ -697,10 +697,10 @@ class SwapIFrameApi extends BitcoinRequestParserMixin(RequestParser) { // eslint }; } - if (parsedRequest.redeem.type === 'USDC' && storedRequest.redeem.type === 'USDC') { + if (parsedRequest.redeem.type === 'USDC_MATIC' && storedRequest.redeem.type === 'USDC_MATIC') { const usdcHtlcContract = new ethers.Contract( - CONFIG.BRIDGED_USDC_HTLC_CONTRACT_ADDRESS, - PolygonContractABIs.BRIDGED_USDC_HTLC_CONTRACT_ABI, + CONFIG.NATIVE_USDC_HTLC_CONTRACT_ADDRESS, + PolygonContractABIs.NATIVE_USDC_HTLC_CONTRACT_ABI, ); // Place contract details into existing function call data @@ -718,7 +718,7 @@ class SwapIFrameApi extends BitcoinRequestParserMixin(RequestParser) { // eslint const typedData = new OpenGSN.TypedRequestData( CONFIG.POLYGON_CHAIN_ID, - CONFIG.BRIDGED_USDC_HTLC_CONTRACT_ADDRESS, + CONFIG.NATIVE_USDC_HTLC_CONTRACT_ADDRESS, { request: storedRequest.redeem.request, relayData: storedRequest.redeem.relayData, diff --git a/types/Keyguard.d.ts b/types/Keyguard.d.ts index 9dd3a3b8c..147f00177 100644 --- a/types/Keyguard.d.ts +++ b/types/Keyguard.d.ts @@ -104,11 +104,11 @@ type PolygonOpenDescription = ethers.utils.TransactionDescription & { readonly args: PolygonOpenArgs, }; -interface PolygonOpenWithApprovalArgs extends PolygonOpenArgs, PolygonUsdcApproval {} +interface PolygonOpenWithPermitArgs extends PolygonOpenArgs, PolygonUsdcPermit {} -type PolygonOpenWithApprovalDescription = ethers.utils.TransactionDescription & { - readonly name: 'openWithApproval', - readonly args: PolygonOpenWithApprovalArgs, +type PolygonOpenWithPermitDescription = ethers.utils.TransactionDescription & { + readonly name: 'openWithPermit', + readonly args: PolygonOpenWithPermitArgs, }; interface PolygonRedeemArgs extends ReadonlyArray { @@ -209,9 +209,9 @@ type ConstructSwap = Transform< locktime?: number; refundKeyPath: string, refundAddress: string, - } | Transform | { type: 'EUR', amount: number, @@ -234,8 +234,8 @@ type ConstructSwap = Transform< keyPath: string, }, output: KeyguardRequest.BitcoinTransactionChangeOutput, - } | Transform | { @@ -341,7 +341,7 @@ type Parsed = htlcScript: Uint8Array, htlcAddress: string, } | { - type: 'USDC', + type: 'USDC_MATIC', description: PolygonOpenDescription, } | { type: 'EUR', @@ -361,7 +361,7 @@ type Parsed = outputIndex: number, outputScript: Buffer, } | { - type: 'USDC', + type: 'USDC_MATIC', htlcId: string, htlcDetails: { hash: string,