From 9af183481ab11c9c8e956e778cde73700ade1ab8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren?= Date: Thu, 22 Feb 2024 13:56:21 +0100 Subject: [PATCH] Allow use of sign-polygon-transaction flow for re-signing swap redeem transactions --- .../SignPolygonTransaction.js | 24 +++++++----------- .../SignPolygonTransactionApi.js | 25 +++++++++++++------ src/request/swap-iframe/SwapIFrameApi.js | 2 +- types/Keyguard.d.ts | 2 ++ 4 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/request/sign-polygon-transaction/SignPolygonTransaction.js b/src/request/sign-polygon-transaction/SignPolygonTransaction.js index 9db5dba6c..e0509191b 100644 --- a/src/request/sign-polygon-transaction/SignPolygonTransaction.js +++ b/src/request/sign-polygon-transaction/SignPolygonTransaction.js @@ -32,7 +32,7 @@ class SignPolygonTransaction { /** @type {HTMLLinkElement} */ const $sender = (this.$el.querySelector('.accounts .sender')); - if (request.description.name === 'refund') { + if (['redeem', 'redeemWithSecretInData', 'refund'].includes(request.description.name)) { new PolygonAddressInfo(relayRequest.to, request.senderLabel, 'unknown').renderTo($sender); } else if (request.description.name === 'swap' || request.description.name === 'swapWithApproval') { new PolygonAddressInfo(relayRequest.from, 'USDC.e', 'usdc_dark').renderTo($sender); @@ -42,20 +42,14 @@ class SignPolygonTransaction { /** @type {HTMLLinkElement} */ const $recipient = (this.$el.querySelector('.accounts .recipient')); - if (request.description.name === 'refund') { - new PolygonAddressInfo( - /** @type {string} */ (request.description.args.target), - request.keyLabel, - 'usdc', - ).renderTo($recipient); + if (['redeem', 'redeemWithSecretInData', 'refund'].includes(request.description.name)) { + const recipientAddress = /** @type {string} */ (request.description.args.target); + new PolygonAddressInfo(recipientAddress, request.keyLabel, 'usdc').renderTo($recipient); } else if (request.description.name === 'swap' || request.description.name === 'swapWithApproval') { new PolygonAddressInfo(relayRequest.from, 'USDC', 'usdc').renderTo($recipient); } else { - new PolygonAddressInfo( - /** @type {string} */ (request.description.args.target), - request.recipientLabel, - 'none', - ).renderTo($recipient); + const recipientAddress = /** @type {string} */ (request.description.args.target); + new PolygonAddressInfo(recipientAddress, request.recipientLabel, 'none').renderTo($recipient); } /** @type {HTMLDivElement} */ @@ -65,7 +59,7 @@ class SignPolygonTransaction { // Set value and fee. $value.textContent = NumberFormatting.formatNumber( - PolygonUtils.unitsToCoins(request.description.name === 'refund' + PolygonUtils.unitsToCoins(['redeem', 'redeemWithSecretInData', 'refund'].includes(request.description.name) ? /** @type {number} */ (request.amount) : request.description.args.amount.toNumber()), 6, @@ -192,10 +186,10 @@ class SignPolygonTransaction { ]); } - if (request.description.name === 'refund') { + if (['redeem', 'redeemWithSecretInData', 'refund'].includes(request.description.name)) { const derivedAddress = polygonKey.deriveAddress(request.keyPath); if (request.description.args.target !== derivedAddress) { - reject(new Errors.InvalidRequestError('Refund target does not match derived address')); + reject(new Errors.InvalidRequestError('Target address argument does not match derived address')); return; } } diff --git a/src/request/sign-polygon-transaction/SignPolygonTransactionApi.js b/src/request/sign-polygon-transaction/SignPolygonTransactionApi.js index bc60013dd..301869acb 100644 --- a/src/request/sign-polygon-transaction/SignPolygonTransactionApi.js +++ b/src/request/sign-polygon-transaction/SignPolygonTransactionApi.js @@ -59,6 +59,8 @@ class SignPolygonTransactionApi extends PolygonRequestParserMixin(TopLevelApi) { * KeyguardRequest.OpenGsnForwardRequest, * PolygonTransferDescription * | PolygonTransferWithPermitDescription + * | PolygonRedeemDescription + * | PolygonRedeemWithSecretInDataDescription * | PolygonRefundDescription * | PolygonSwapDescription * | PolygonSwapWithApprovalDescription, @@ -70,6 +72,8 @@ class SignPolygonTransactionApi extends PolygonRequestParserMixin(TopLevelApi) { /** * @type {PolygonTransferDescription * | PolygonTransferWithPermitDescription + * | PolygonRedeemDescription + * | PolygonRedeemWithSecretInDataDescription * | PolygonRefundDescription * | PolygonSwapDescription * | PolygonSwapWithApprovalDescription} @@ -101,13 +105,18 @@ class SignPolygonTransactionApi extends PolygonRequestParserMixin(TopLevelApi) { PolygonContractABIs.NATIVE_USDC_HTLC_CONTRACT_ABI, ); - /** @type {PolygonRefundDescription} */ + /** + * @type {PolygonRedeemDescription + * | PolygonRedeemWithSecretInDataDescription + * | PolygonRefundDescription + * } + */ description = (usdcHtlcContract.interface.parseTransaction({ data: forwardRequest.data, value: forwardRequest.value, })); - if (!['refund'].includes(description.name)) { + if (!['redeem', 'redeemWithSecretInData', 'refund'].includes(description.name)) { throw new Errors.InvalidRequestError('Requested Polygon contract method is invalid'); } } else if (forwardRequest.to === CONFIG.BRIDGED_USDC_HTLC_CONTRACT_ADDRESS) { @@ -164,17 +173,19 @@ class SignPolygonTransactionApi extends PolygonRequestParserMixin(TopLevelApi) { throw new Errors.InvalidRequestError('request.to address is not allowed'); } + // Check that amount exists when request is for refund or redeem, and unset for other methods. + if (['redeem', 'redeemWithSecretInData', 'refund'].includes(description.name) !== !!request.amount) { + throw new Errors.InvalidRequestError( + '`amount` is only allowed for contract methods "refund", "redeem" and "redeemWithSecretInData"', + ); + } + // Check that permit object exists when method is 'transferWithPermit', and unset for other methods. if ((description.name === 'transferWithPermit') !== !!request.permit) { throw new Errors.InvalidRequestError('`permit` object is only allowed for contract method ' + '"transferWithPermit"'); } - // Check that amount exists when method is 'refund', and unset for other methods. - if ((description.name === 'refund') !== !!request.amount) { - throw new Errors.InvalidRequestError('`amount` is only allowed for contract method "refund"'); - } - // Check that approval object exists when method is 'swapWithApproval', and unset for other methods. if ((description.name === 'swapWithApproval') !== !!request.approval) { throw new Errors.InvalidRequestError('`approval` object is only allowed for contract method ' diff --git a/src/request/swap-iframe/SwapIFrameApi.js b/src/request/swap-iframe/SwapIFrameApi.js index 973ab2e77..fcb605229 100644 --- a/src/request/swap-iframe/SwapIFrameApi.js +++ b/src/request/swap-iframe/SwapIFrameApi.js @@ -710,7 +710,7 @@ class SwapIFrameApi extends BitcoinRequestParserMixin(RequestParser) { // eslint /* bytes32 id */ parsedRequest.redeem.htlcId, /* address target */ storedRequest.redeem.description.args.target, ...(storedRequest.redeem.description.name === 'redeem' ? [ - /* uint256 secret */ storedRequest.redeem.description.args.secret, + /* bytes32 secret */ storedRequest.redeem.description.args.secret, ] : []), /* uint256 fee */ storedRequest.redeem.description.args.fee, ], diff --git a/types/Keyguard.d.ts b/types/Keyguard.d.ts index 147f00177..e98ca1ac8 100644 --- a/types/Keyguard.d.ts +++ b/types/Keyguard.d.ts @@ -306,6 +306,8 @@ type Parsed = KeyId2KeyInfo & { description: PolygonTransferDescription | PolygonTransferWithPermitDescription + | PolygonRedeemDescription + | PolygonRedeemWithSecretInDataDescription | PolygonRefundDescription | PolygonSwapDescription | PolygonSwapWithApprovalDescription } :