From 35eb80133b3610fc9fc5928cb8ab1fc8e210a592 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren?= Date: Mon, 4 Mar 2024 13:52:39 +0100 Subject: [PATCH] Allow native USDC `openWithPermit` function And switch to `SwapAsset.USDC_MATIC`. --- client/PublicRequestTypes.ts | 10 +++++----- client/package.json | 2 +- client/yarn.lock | 8 ++++---- package.json | 4 ++-- src/lib/RequestParser.ts | 24 ++++++++++++------------ src/lib/RequestTypes.ts | 8 ++++---- src/views/RefundSwap.vue | 2 +- src/views/RefundSwapSuccess.vue | 5 ++++- src/views/SetupSwap.vue | 11 +++++------ src/views/SetupSwapSuccess.vue | 24 ++++++++++++------------ yarn.lock | 16 ++++++++-------- 11 files changed, 58 insertions(+), 56 deletions(-) diff --git a/client/PublicRequestTypes.ts b/client/PublicRequestTypes.ts index 554f9315..a7cde705 100644 --- a/client/PublicRequestTypes.ts +++ b/client/PublicRequestTypes.ts @@ -271,12 +271,12 @@ export interface BitcoinHtlcCreationInstructions { } export interface PolygonHtlcCreationInstructions extends RelayRequest { - type: 'USDC'; + type: 'USDC_MATIC'; /** * The sender's nonce in the token contract, required when calling the - * contract function `openWithApproval`. + * contract function `openWithPermit`. */ - approval?: { + permit?: { tokenNonce: number, }; } @@ -312,7 +312,7 @@ export interface BitcoinHtlcSettlementInstructions { } export interface PolygonHtlcSettlementInstructions extends RelayRequest { - type: 'USDC'; + type: 'USDC_MATIC'; amount: number; } @@ -360,7 +360,7 @@ export interface BitcoinHtlcRefundInstructions { } export interface PolygonHtlcRefundInstructions extends RelayRequest { - type: 'USDC'; + type: 'USDC_MATIC' | 'USDC'; amount: number; } diff --git a/client/package.json b/client/package.json index 7538fffb..65a9823d 100644 --- a/client/package.json +++ b/client/package.json @@ -10,7 +10,7 @@ "types": "types/index.d.ts", "dependencies": { "@nimiq/core-web": "^1.6.1", - "@nimiq/fastspot-api": "^1.7.0", + "@nimiq/fastspot-api": "^1.8.0", "@nimiq/rpc": "^0.4.0", "@nimiq/utils": "^0.5.0", "@opengsn/common": "^2.2.5", diff --git a/client/yarn.lock b/client/yarn.lock index 58fc2b5e..cd1a205c 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -232,10 +232,10 @@ resolved "https://registry.yarnpkg.com/@nimiq/core-web/-/core-web-1.6.1.tgz#97cb5b43b257c7f6f6808ef603e9bf686377241f" integrity sha512-WYw2brIxUXa/SQ0JRp0RXWQKzBFhROXrEjF9Eh+tRlC+NrI2ObwRQkwJCbP2qmPtYldIimfyECmsDVHFoyLXjQ== -"@nimiq/fastspot-api@^1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@nimiq/fastspot-api/-/fastspot-api-1.7.0.tgz#eea496f4898139c51971f0b177583c6cc6b06611" - integrity sha512-k7vSjYdjAiAQar+21v681Zrp9kN9uHMUw7/dyG2D/IrXqNPHkD133JyrzxPBga+myW411SUR4mtdPQRPQm3d/A== +"@nimiq/fastspot-api@^1.8.0": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@nimiq/fastspot-api/-/fastspot-api-1.8.0.tgz#705a9e79e425c3e6536d8994fd0b39d88af1b268" + integrity sha512-qNkibJnxS8ndOn4tuy1m3lSNKybBYApo+wy1ajTKcQ0lHo3VfLY0sAJ+WRE7diVWCa7iumu6wsFVudyc3k8/NQ== "@nimiq/rpc@^0.4.0": version "0.4.0" diff --git a/package.json b/package.json index 44faf1d5..3cf60d9d 100644 --- a/package.json +++ b/package.json @@ -21,9 +21,9 @@ "dependencies": { "@nimiq/browser-warning": "^1.1.1", "@nimiq/electrum-client": "https://github.com/nimiq/electrum-client#build", - "@nimiq/fastspot-api": "^1.7.0", + "@nimiq/fastspot-api": "^1.8.0", "@nimiq/iqons": "^1.5.2", - "@nimiq/keyguard-client": "^1.5.4", + "@nimiq/keyguard-client": "^1.6.0", "@nimiq/ledger-api": "^2.3.0", "@nimiq/network-client": "^0.6.2", "@nimiq/oasis-api": "^1.1.1", diff --git a/src/lib/RequestParser.ts b/src/lib/RequestParser.ts index 509cee2f..c5ea0577 100644 --- a/src/lib/RequestParser.ts +++ b/src/lib/RequestParser.ts @@ -527,11 +527,11 @@ export class RequestParser { // Validate and parse only what we use in the Hub - if (!['NIM', 'BTC', 'USDC', 'EUR'].includes(setupSwapRequest.fund.type)) { + if (!['NIM', 'BTC', 'USDC_MATIC', 'EUR'].includes(setupSwapRequest.fund.type)) { throw new Error('Funding type is not supported'); } - if (!['NIM', 'BTC', 'USDC', 'EUR'].includes(setupSwapRequest.redeem.type)) { + if (!['NIM', 'BTC', 'USDC_MATIC', 'EUR'].includes(setupSwapRequest.redeem.type)) { throw new Error('Redeeming type is not supported'); } @@ -562,9 +562,9 @@ export class RequestParser { throw new Error('When using the "slider" layout, `bitcoinAccount` must be provided'); } - const nimiqAddress = setupSwapRequest.fund.type === 'NIM' + const nimiqAddress = setupSwapRequest.fund.type === SwapAsset.NIM ? Nimiq.Address.fromAny(setupSwapRequest.fund.sender) - : setupSwapRequest.redeem.type === 'NIM' + : setupSwapRequest.redeem.type === SwapAsset.NIM ? Nimiq.Address.fromAny(setupSwapRequest.redeem.recipient) : undefined; if (nimiqAddress && !setupSwapRequest.nimiqAddresses.some( @@ -572,9 +572,9 @@ export class RequestParser { throw new Error('The address details of the NIM address doing the swap must be provided'); } - const polygonAddress = setupSwapRequest.fund.type === 'USDC' + const polygonAddress = setupSwapRequest.fund.type === SwapAsset.USDC_MATIC ? setupSwapRequest.fund.request.from - : setupSwapRequest.redeem.type === 'USDC' + : setupSwapRequest.redeem.type === SwapAsset.USDC_MATIC ? setupSwapRequest.redeem.request.from : undefined; if (polygonAddress && !setupSwapRequest.polygonAddresses.some( @@ -583,7 +583,7 @@ export class RequestParser { } } - if (setupSwapRequest.redeem.type === 'NIM') { + if (setupSwapRequest.redeem.type === SwapAsset.NIM) { if (!setupSwapRequest.redeem.validityStartHeight || setupSwapRequest.redeem.validityStartHeight < 1) { throw new Error( @@ -592,7 +592,7 @@ export class RequestParser { } } - if (setupSwapRequest.fund.type === 'NIM') { + if (setupSwapRequest.fund.type === SwapAsset.NIM) { if (!setupSwapRequest.fund.validityStartHeight || setupSwapRequest.fund.validityStartHeight < 1) { throw new Error(`Invalid validity start height: ${setupSwapRequest.fund.validityStartHeight}`); @@ -628,7 +628,7 @@ export class RequestParser { } : setupSwapRequest.fund.type === 'BTC' ? { ...setupSwapRequest.fund, type: SwapAsset[setupSwapRequest.fund.type], - } : setupSwapRequest.fund.type === 'USDC' ? { + } : setupSwapRequest.fund.type === 'USDC_MATIC' ? { ...setupSwapRequest.fund, type: SwapAsset[setupSwapRequest.fund.type], } : { // EUR @@ -646,7 +646,7 @@ export class RequestParser { } : setupSwapRequest.redeem.type === 'BTC' ? { ...setupSwapRequest.redeem, type: SwapAsset[setupSwapRequest.redeem.type], - } : setupSwapRequest.redeem.type === 'USDC' ? { + } : setupSwapRequest.redeem.type === 'USDC_MATIC' ? { ...setupSwapRequest.redeem, type: SwapAsset[setupSwapRequest.redeem.type], } : { // EUR @@ -664,8 +664,8 @@ export class RequestParser { // Only basic parsing and validation. Refund transaction specific data will be validated by the Keyguard // or subsequent Ledger transaction signing requests. - if (!['NIM', 'BTC', 'USDC'].includes(refundSwapRequest.refund.type)) { - throw new Error('Refunding object type must be "NIM", "BTC", or "USDC"'); + if (!['NIM', 'BTC', 'USDC', 'USDC_MATIC'].includes(refundSwapRequest.refund.type)) { + throw new Error('Refunding object type must be "NIM", "BTC", "USDC", or "USDC_MATIC"'); } const parsedRefundSwapRequest: ParsedRefundSwapRequest = { diff --git a/src/lib/RequestTypes.ts b/src/lib/RequestTypes.ts index 7fa425da..ada6919c 100644 --- a/src/lib/RequestTypes.ts +++ b/src/lib/RequestTypes.ts @@ -198,8 +198,8 @@ export interface ParsedSetupSwapRequest extends ParsedSimpleRequest { // htlcScript: Uint8Array, refundAddress: string, } | ({ - type: SwapAsset.USDC, - approval?: { + type: SwapAsset.USDC_MATIC, + permit?: { tokenNonce: number, }, } & RelayRequest) | { @@ -232,7 +232,7 @@ export interface ParsedSetupSwapRequest extends ParsedSimpleRequest { value: number, // Sats }; } | ({ - type: SwapAsset.USDC, + type: SwapAsset.USDC_MATIC, amount: number, } & RelayRequest) | { type: SwapAsset.EUR, @@ -311,7 +311,7 @@ export interface ParsedRefundSwapRequest extends ParsedSimpleRequest { }; refundAddress: string; // My address, must be refund address of HTLC } | ({ - type: SwapAsset.USDC, + type: SwapAsset.USDC_MATIC | SwapAsset.USDC, amount: number, } & RelayRequest); } diff --git a/src/views/RefundSwap.vue b/src/views/RefundSwap.vue index e91697cc..b1db757a 100644 --- a/src/views/RefundSwap.vue +++ b/src/views/RefundSwap.vue @@ -122,7 +122,7 @@ export default class RefundSwap extends BitcoinSyncBaseView { this._signTransaction(signRequest); } - if (refundInfo.type === SwapAsset.USDC) { + if (refundInfo.type === SwapAsset.USDC_MATIC || refundInfo.type === SwapAsset.USDC) { const signer = account.polygonAddresses.find((ai) => ai.address === refundInfo.request.from); if (!signer) { diff --git a/src/views/RefundSwapSuccess.vue b/src/views/RefundSwapSuccess.vue index 13f22709..9244a03c 100644 --- a/src/views/RefundSwapSuccess.vue +++ b/src/views/RefundSwapSuccess.vue @@ -55,7 +55,10 @@ export default class SignBtcTransactionSuccess extends Vue { return; } - if ('message' in this.keyguardResult && this.request.refund.type === SwapAsset.USDC) { + if ( + 'message' in this.keyguardResult + && (this.request.refund.type === SwapAsset.USDC_MATIC || this.request.refund.type === SwapAsset.USDC) + ) { const result: SignedPolygonTransaction = { message: this.keyguardResult.message, signature: this.keyguardResult.signature, diff --git a/src/views/SetupSwap.vue b/src/views/SetupSwap.vue index 949bffbd..ba698a40 100644 --- a/src/views/SetupSwap.vue +++ b/src/views/SetupSwap.vue @@ -11,7 +11,6 @@ import { WalletInfo } from '../lib/WalletInfo'; import { BtcAddressInfo } from '../lib/bitcoin/BtcAddressInfo'; import { SwapAsset } from '@nimiq/fastspot-api'; import { DEFAULT_KEY_PATH } from '../lib/Constants'; -import { threadId } from 'worker_threads'; // Import only types to avoid bundling of KeyguardClient in Ledger request if not required. // (But note that currently, the KeyguardClient is still always bundled in the RpcApi). @@ -183,7 +182,7 @@ export default class SetupSwap extends BitcoinSyncBaseView { }; } - if (this.request.fund.type === SwapAsset.USDC) { + if (this.request.fund.type === SwapAsset.USDC_MATIC) { const senderAddress = this.request.fund.request.from; const signer = this._account.polygonAddresses.find((ai) => ai.address === senderAddress); @@ -192,11 +191,11 @@ export default class SetupSwap extends BitcoinSyncBaseView { } fundingInfo = { - type: SwapAsset.USDC, + type: SwapAsset.USDC_MATIC, keyPath: signer.path, request: this.request.fund.request, relayData: this.request.fund.relayData, - approval: this.request.fund.approval, + permit: this.request.fund.permit, }; } @@ -255,7 +254,7 @@ export default class SetupSwap extends BitcoinSyncBaseView { }; } - if (this.request.redeem.type === SwapAsset.USDC) { + if (this.request.redeem.type === SwapAsset.USDC_MATIC) { const senderAddress = this.request.redeem.request.from; const signer = this._account.polygonAddresses.find((ai) => ai.address === senderAddress); @@ -264,7 +263,7 @@ export default class SetupSwap extends BitcoinSyncBaseView { } redeemingInfo = { - type: SwapAsset.USDC, + type: SwapAsset.USDC_MATIC, keyPath: signer.path, request: this.request.redeem.request, relayData: this.request.redeem.relayData, diff --git a/src/views/SetupSwapSuccess.vue b/src/views/SetupSwapSuccess.vue index 890e6b2b..a75b0b1a 100644 --- a/src/views/SetupSwapSuccess.vue +++ b/src/views/SetupSwapSuccess.vue @@ -84,7 +84,7 @@ export default class SetupSwapSuccess extends BitcoinSyncBaseView { case SwapAsset.BTC: refundAddress = this.request.fund.refundAddress; break; - case SwapAsset.USDC: + case SwapAsset.USDC_MATIC: refundAddress = this.request.fund.request.from; break; default: break; @@ -98,7 +98,7 @@ export default class SetupSwapSuccess extends BitcoinSyncBaseView { case SwapAsset.BTC: redeemAddress = this.request.redeem.output.address; break; - case SwapAsset.USDC: + case SwapAsset.USDC_MATIC: redeemAddress = this.request.redeem.request.from; break; case SwapAsset.EUR: @@ -228,8 +228,8 @@ export default class SetupSwapSuccess extends BitcoinSyncBaseView { } } - if (confirmedSwap.from.asset === SwapAsset.USDC || confirmedSwap.to.asset === SwapAsset.USDC) { - const contract = confirmedSwap.contracts[SwapAsset.USDC] as Contract; + if (confirmedSwap.from.asset === SwapAsset.USDC_MATIC || confirmedSwap.to.asset === SwapAsset.USDC_MATIC) { + const contract = confirmedSwap.contracts[SwapAsset.USDC_MATIC] as Contract; const htlc = contract.htlc as UsdcHtlcDetails; const contractData = { @@ -254,11 +254,11 @@ export default class SetupSwapSuccess extends BitcoinSyncBaseView { } hashRoot = contractData.hash; - if (confirmedSwap.from.asset === SwapAsset.USDC && refundAddress !== contractData.refundAddress) { + if (confirmedSwap.from.asset === SwapAsset.USDC_MATIC && refundAddress !== contractData.refundAddress) { this.$rpc.reject(new Error('Unknown HTLC refund address')); return; } - if (confirmedSwap.to.asset === SwapAsset.USDC && redeemAddress !== contractData.recipientAddress) { + if (confirmedSwap.to.asset === SwapAsset.USDC_MATIC && redeemAddress !== contractData.recipientAddress) { this.$rpc.reject(new Error('Unknown HTLC redeem address')); return; } @@ -304,8 +304,8 @@ export default class SetupSwapSuccess extends BitcoinSyncBaseView { }; } - if (this.request.fund.type === SwapAsset.USDC) { - const usdcHtlcData = confirmedSwap.contracts[SwapAsset.USDC]!.htlc as UsdcHtlcDetails; + if (this.request.fund.type === SwapAsset.USDC_MATIC) { + const usdcHtlcData = confirmedSwap.contracts[SwapAsset.USDC_MATIC]!.htlc as UsdcHtlcDetails; if (!usdcHtlcData.data) { // TODO: Create data with ethersJS @@ -313,7 +313,7 @@ export default class SetupSwapSuccess extends BitcoinSyncBaseView { } fundingHtlcInfo = { - type: SwapAsset.USDC, + type: SwapAsset.USDC_MATIC, htlcData: usdcHtlcData.data, }; } @@ -409,12 +409,12 @@ export default class SetupSwapSuccess extends BitcoinSyncBaseView { } } - if (this.request.redeem.type === SwapAsset.USDC) { - const usdcContract = confirmedSwap.contracts[SwapAsset.USDC] as Contract; + if (this.request.redeem.type === SwapAsset.USDC_MATIC) { + const usdcContract = confirmedSwap.contracts[SwapAsset.USDC_MATIC] as Contract; const usdcHtlcData = usdcContract.htlc as UsdcHtlcDetails; redeemingHtlcInfo = { - type: SwapAsset.USDC, + type: SwapAsset.USDC_MATIC, hash: confirmedSwap.hash, timeout: usdcContract.timeout, htlcId: usdcHtlcData.address, diff --git a/yarn.lock b/yarn.lock index 886ddbcf..4428cec4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1520,10 +1520,10 @@ dependencies: bitcoinjs-lib "^5.1.10" -"@nimiq/fastspot-api@^1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@nimiq/fastspot-api/-/fastspot-api-1.7.0.tgz#eea496f4898139c51971f0b177583c6cc6b06611" - integrity sha512-k7vSjYdjAiAQar+21v681Zrp9kN9uHMUw7/dyG2D/IrXqNPHkD133JyrzxPBga+myW411SUR4mtdPQRPQm3d/A== +"@nimiq/fastspot-api@^1.8.0": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@nimiq/fastspot-api/-/fastspot-api-1.8.0.tgz#705a9e79e425c3e6536d8994fd0b39d88af1b268" + integrity sha512-qNkibJnxS8ndOn4tuy1m3lSNKybBYApo+wy1ajTKcQ0lHo3VfLY0sAJ+WRE7diVWCa7iumu6wsFVudyc3k8/NQ== "@nimiq/iqons@^1.5.2", "@nimiq/iqons@^1.6.0": version "1.6.0" @@ -1541,10 +1541,10 @@ btoa "^1.1.2" node-lmdb "^0.9.6" -"@nimiq/keyguard-client@^1.5.4": - version "1.5.4" - resolved "https://registry.yarnpkg.com/@nimiq/keyguard-client/-/keyguard-client-1.5.4.tgz#0842386e1c36e2b203cae94ac62ffafd48ee79fa" - integrity sha512-E4sQys66nSPCiMRm2NN9ibm0RZCA9VbyP7UApSEBShBCHkCCSYp1zjfuPm9+v4VKwA7yw+pEDZ5RE7Mlf2OdIQ== +"@nimiq/keyguard-client@^1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@nimiq/keyguard-client/-/keyguard-client-1.6.0.tgz#e2cb22c1af5ae68dac74e5ead9e69aeaba2ffc8b" + integrity sha512-DDi+PycBtiTJO5Jwk3mHZzBP2FHARNCIR+9C6+uhw6kRlT/pcDS+vE6GeTGOwZsRGOtowLG3d9n43xWoPOOcGQ== dependencies: "@nimiq/core-web" "1.5.8" "@nimiq/rpc" "^0.3.0"