From 0e44785eb6e1076bc7938022fc4ae3d2309754d7 Mon Sep 17 00:00:00 2001 From: Maxi Date: Wed, 5 Jun 2024 19:07:22 +0200 Subject: [PATCH 1/6] feat: refactor EuroAssetAdapter to allow other fiat currencies --- README.md | 2 +- src/{EuroAssetAdapter.ts => FiatAssetAdapter.ts} | 12 +++++++----- src/IAssetAdapter.ts | 9 ++++++--- src/SwapHandler.ts | 8 +++++--- 4 files changed, 19 insertions(+), 12 deletions(-) rename src/{EuroAssetAdapter.ts => FiatAssetAdapter.ts} (93%) diff --git a/README.md b/README.md index 55e204d..9b9fcd5 100644 --- a/README.md +++ b/README.md @@ -107,7 +107,7 @@ await swapHandler.settleIncoming(serializedSettlementTx, secret) /** * 5. Await confirmation of settled HTLC * - * This is especially relevant for EUR contracts, as they may take a + * This is especially relevant for EUR and CRC contracts, as they may take a * few minutes to confirm after they were settled. * * The optional `onUpdate` callback receives the transaction object: diff --git a/src/EuroAssetAdapter.ts b/src/FiatAssetAdapter.ts similarity index 93% rename from src/EuroAssetAdapter.ts rename to src/FiatAssetAdapter.ts index a4d56f6..5cbf9cb 100644 --- a/src/EuroAssetAdapter.ts +++ b/src/FiatAssetAdapter.ts @@ -1,5 +1,5 @@ import { Htlc as OasisHtlc, HtlcStatus, SettlementInstruction, SettlementStatus } from '@nimiq/oasis-api'; -import { AssetAdapter, SwapAsset } from './IAssetAdapter'; +import { AssetAdapter, FiatSwapAsset, SwapAsset, Transaction } from './IAssetAdapter'; export type HtlcDetails = OasisHtlc; @@ -8,7 +8,7 @@ export interface OasisClient { settleHtlc(id: string, secret: string, settlementJWS: string, authorizationToken?: string): Promise; } -export class EuroAssetAdapter implements AssetAdapter { +export class FiatAssetAdapter implements AssetAdapter { private cancelCallback: ((reason: Error) => void) | null = null; private stopped = false; @@ -82,7 +82,7 @@ export class EuroAssetAdapter implements AssetAdapter { // eslint-disable-next-line class-methods-use-this public async fundHtlc(): Promise { - throw new Error('Method "fundHtlc" not available for EUR HTLCs'); + throw new Error('Method "fundHtlc" not available for EUR/CRC HTLCs'); } public async awaitHtlcSettlement(id: string): Promise> { @@ -103,7 +103,7 @@ export class EuroAssetAdapter implements AssetAdapter { hash: string, authorizationToken?: string, ): Promise { - if (this.stopped) throw new Error('EuroAssetAdapter called while stopped'); + if (this.stopped) throw new Error('FiatAssetAdapter called while stopped'); const jwsBody = settlementJWS.split('.')[1]; // JWS is encoded as Base64Url @@ -112,7 +112,9 @@ export class EuroAssetAdapter implements AssetAdapter { let htlc: HtlcDetails; try { - htlc = await this.client.settleHtlc(payload.contractId, secret, settlementJWS, authorizationToken); + htlc = await this.client.settleHtlc(payload.contractId, secret, settlementJWS, { + authorization: authorizationToken, + }); } catch (error) { console.error(error); // eslint-disable-line no-console htlc = await this.client.getHtlc(payload.contractId); diff --git a/src/IAssetAdapter.ts b/src/IAssetAdapter.ts index ce5e4b6..1736878 100644 --- a/src/IAssetAdapter.ts +++ b/src/IAssetAdapter.ts @@ -1,6 +1,6 @@ import { BitcoinClient, TransactionDetails as BitcoinTransactionDetails } from './BitcoinAssetAdapter'; import { GenericEvent as Erc20TransactionDetails, Web3Client } from './Erc20AssetAdapter'; -import { HtlcDetails as EuroHtlcDetails, OasisClient } from './EuroAssetAdapter'; +import { HtlcDetails, OasisClient } from './FiatAssetAdapter'; import { NimiqClient, TransactionDetails as NimiqTransactionDetails } from './NimiqAssetAdapter'; export enum SwapAsset { @@ -10,18 +10,21 @@ export enum SwapAsset { USDC_MATIC = 'USDC_MATIC', USDT = 'USDT', // Alternatively USDT_MATIC EUR = 'EUR', + CRC = 'CRC', } +export type FiatSwapAsset = SwapAsset.EUR | SwapAsset.CRC; + export type Transaction = TAsset extends SwapAsset.NIM ? NimiqTransactionDetails : TAsset extends SwapAsset.BTC ? BitcoinTransactionDetails : TAsset extends SwapAsset.USDC | SwapAsset.USDC_MATIC | SwapAsset.USDT ? Erc20TransactionDetails - : TAsset extends SwapAsset.EUR ? EuroHtlcDetails + : TAsset extends FiatSwapAsset ? HtlcDetails : never; export type Client = TAsset extends SwapAsset.NIM ? NimiqClient : TAsset extends SwapAsset.BTC ? BitcoinClient : TAsset extends SwapAsset.USDC | SwapAsset.USDC_MATIC | SwapAsset.USDT ? Web3Client - : TAsset extends SwapAsset.EUR ? OasisClient + : TAsset extends FiatSwapAsset ? OasisClient : never; export interface AssetAdapter { diff --git a/src/SwapHandler.ts b/src/SwapHandler.ts index 2c2b55d..07eaac2 100644 --- a/src/SwapHandler.ts +++ b/src/SwapHandler.ts @@ -1,6 +1,6 @@ import { BitcoinAssetAdapter } from './BitcoinAssetAdapter'; import { Erc20AssetAdapter } from './Erc20AssetAdapter'; -import { EuroAssetAdapter } from './EuroAssetAdapter'; +import { FiatAssetAdapter } from './FiatAssetAdapter'; import { AssetAdapter, SwapAsset } from './IAssetAdapter'; import type { Client, Transaction } from './IAssetAdapter'; import { NimiqAssetAdapter } from './NimiqAssetAdapter'; @@ -54,7 +54,9 @@ export class SwapHandler SwapAsset >; case SwapAsset.EUR: - return new EuroAssetAdapter(client as Client) as AssetAdapter; + return new FiatAssetAdapter(client as Client) as AssetAdapter; + case SwapAsset.CRC: + return new FiatAssetAdapter(client as Client) as AssetAdapter; default: throw new Error(`Unsupported asset: ${asset}`); } @@ -127,7 +129,7 @@ export class SwapHandler serializedTx, secret, this.swap.hash, - authorizationToken, + { authorization: authorizationToken }, ); } From bd42ccb4aa1620dff62d79653b80598ccc88f830 Mon Sep 17 00:00:00 2001 From: Maxi Date: Wed, 5 Jun 2024 20:01:52 +0200 Subject: [PATCH 2/6] feat: settleHtlc now accepts an object for tokens --- src/FiatAssetAdapter.ts | 17 +++++++++++------ src/IAssetAdapter.ts | 10 +++++----- src/SwapHandler.ts | 5 +++-- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/FiatAssetAdapter.ts b/src/FiatAssetAdapter.ts index 5cbf9cb..3b898f1 100644 --- a/src/FiatAssetAdapter.ts +++ b/src/FiatAssetAdapter.ts @@ -1,11 +1,18 @@ import { Htlc as OasisHtlc, HtlcStatus, SettlementInstruction, SettlementStatus } from '@nimiq/oasis-api'; -import { AssetAdapter, FiatSwapAsset, SwapAsset, Transaction } from './IAssetAdapter'; +import type { AssetAdapter, FiatSwapAsset } from './IAssetAdapter'; export type HtlcDetails = OasisHtlc; +export type SettleHtlcTokens = { authorization: string, smsApi: string }; + export interface OasisClient { getHtlc(id: string): Promise; - settleHtlc(id: string, secret: string, settlementJWS: string, authorizationToken?: string): Promise; + settleHtlc( + id: string, + secret: string, + settlementJWS: string, + tokens?: Partial, + ): Promise; } export class FiatAssetAdapter implements AssetAdapter { @@ -101,7 +108,7 @@ export class FiatAssetAdapter implements AssetAdapter { settlementJWS: string, secret: string, hash: string, - authorizationToken?: string, + tokens?: Partial, ): Promise { if (this.stopped) throw new Error('FiatAssetAdapter called while stopped'); @@ -112,9 +119,7 @@ export class FiatAssetAdapter implements AssetAdapter { let htlc: HtlcDetails; try { - htlc = await this.client.settleHtlc(payload.contractId, secret, settlementJWS, { - authorization: authorizationToken, - }); + htlc = await this.client.settleHtlc(payload.contractId, secret, settlementJWS, tokens); } catch (error) { console.error(error); // eslint-disable-line no-console htlc = await this.client.getHtlc(payload.contractId); diff --git a/src/IAssetAdapter.ts b/src/IAssetAdapter.ts index 1736878..9f690a8 100644 --- a/src/IAssetAdapter.ts +++ b/src/IAssetAdapter.ts @@ -1,7 +1,7 @@ -import { BitcoinClient, TransactionDetails as BitcoinTransactionDetails } from './BitcoinAssetAdapter'; -import { GenericEvent as Erc20TransactionDetails, Web3Client } from './Erc20AssetAdapter'; -import { HtlcDetails, OasisClient } from './FiatAssetAdapter'; -import { NimiqClient, TransactionDetails as NimiqTransactionDetails } from './NimiqAssetAdapter'; +import type { BitcoinClient, TransactionDetails as BitcoinTransactionDetails } from './BitcoinAssetAdapter'; +import type { GenericEvent as Erc20TransactionDetails, Web3Client } from './Erc20AssetAdapter'; +import type { HtlcDetails, OasisClient, SettleHtlcTokens } from './FiatAssetAdapter'; +import type { NimiqClient, TransactionDetails as NimiqTransactionDetails } from './NimiqAssetAdapter'; export enum SwapAsset { NIM = 'NIM', @@ -52,7 +52,7 @@ export interface AssetAdapter { serializedTx: string, secret: string, hash: string, - authorizationToken?: string, + tokens?: Partial, ): Promise>; awaitSettlementConfirmation( diff --git a/src/SwapHandler.ts b/src/SwapHandler.ts index 07eaac2..2c4c7b2 100644 --- a/src/SwapHandler.ts +++ b/src/SwapHandler.ts @@ -1,6 +1,7 @@ import { BitcoinAssetAdapter } from './BitcoinAssetAdapter'; import { Erc20AssetAdapter } from './Erc20AssetAdapter'; import { FiatAssetAdapter } from './FiatAssetAdapter'; +import type { SettleHtlcTokens } from './FiatAssetAdapter'; import { AssetAdapter, SwapAsset } from './IAssetAdapter'; import type { Client, Transaction } from './IAssetAdapter'; import { NimiqAssetAdapter } from './NimiqAssetAdapter'; @@ -123,13 +124,13 @@ export class SwapHandler public async settleIncoming( serializedTx: string, secret: string, - authorizationToken?: string, + tokens?: Partial, ): Promise> { return this.toAssetAdapter.settleHtlc( serializedTx, secret, this.swap.hash, - { authorization: authorizationToken }, + tokens, ); } From 13b045dd7d809248ac61f3b8cd067c562047c57f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren?= Date: Fri, 14 Jun 2024 12:39:43 +0300 Subject: [PATCH 3/6] Use CRC-enabled OASIS API package, streamline re-exports --- package.json | 2 +- src/FiatAssetAdapter.ts | 39 ++++++++++++++++----------------------- src/IAssetAdapter.ts | 6 +++--- src/SwapHandler.ts | 4 ++-- yarn.lock | 5 ++--- 5 files changed, 24 insertions(+), 32 deletions(-) diff --git a/package.json b/package.json index 8e8897f..3d6de03 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "dependencies": { "@nimiq/core-web": "^1.5.8", "@nimiq/electrum-client": "https://github.com/nimiq/electrum-client#build", - "@nimiq/oasis-api": "^1.0.1", + "@nimiq/oasis-api": "https://github.com/nimiq/oasis-api-js#9d63fac0ab1364e4e1494334ee2d74f3d6f96b35", "ethers": "^5.7.2", "promise.prototype.finally": "^3.1.3" }, diff --git a/src/FiatAssetAdapter.ts b/src/FiatAssetAdapter.ts index 3b898f1..c38933f 100644 --- a/src/FiatAssetAdapter.ts +++ b/src/FiatAssetAdapter.ts @@ -1,18 +1,11 @@ -import { Htlc as OasisHtlc, HtlcStatus, SettlementInstruction, SettlementStatus } from '@nimiq/oasis-api'; +import { Htlc, HtlcStatus, SettlementInstruction, SettlementStatus, SettlementTokens } from '@nimiq/oasis-api'; import type { AssetAdapter, FiatSwapAsset } from './IAssetAdapter'; -export type HtlcDetails = OasisHtlc; - -export type SettleHtlcTokens = { authorization: string, smsApi: string }; +export { Htlc as OasisHtlcDetails, SettlementTokens as OasisSettlementTokens }; export interface OasisClient { - getHtlc(id: string): Promise; - settleHtlc( - id: string, - secret: string, - settlementJWS: string, - tokens?: Partial, - ): Promise; + getHtlc(id: string): Promise; + settleHtlc(id: string, secret: string, settlementJWS: string, tokens?: SettlementTokens): Promise; } export class FiatAssetAdapter implements AssetAdapter { @@ -23,9 +16,9 @@ export class FiatAssetAdapter implements AssetAdapter { private async findTransaction( id: string, - test: (htlc: HtlcDetails) => boolean, - ): Promise { - const check = async (): Promise => { + test: (htlc: Htlc) => boolean, + ): Promise { + const check = async (): Promise => { try { const htlc = await this.client.getHtlc(id); if (test(htlc)) return htlc; @@ -71,8 +64,8 @@ export class FiatAssetAdapter implements AssetAdapter { value: number, data?: string, confirmations?: number, - onUpdate?: (htlc: HtlcDetails) => any, - ): Promise { + onUpdate?: (htlc: Htlc) => any, + ): Promise { return this.findTransaction( id, (htlc) => { @@ -88,15 +81,15 @@ export class FiatAssetAdapter implements AssetAdapter { } // eslint-disable-next-line class-methods-use-this - public async fundHtlc(): Promise { + public async fundHtlc(): Promise { throw new Error('Method "fundHtlc" not available for EUR/CRC HTLCs'); } - public async awaitHtlcSettlement(id: string): Promise> { + public async awaitHtlcSettlement(id: string): Promise> { return this.findTransaction( id, (htlc) => typeof htlc.preimage.value === 'string', - ) as Promise>; + ) as Promise>; } public async awaitSwapSecret(id: string): Promise { @@ -108,8 +101,8 @@ export class FiatAssetAdapter implements AssetAdapter { settlementJWS: string, secret: string, hash: string, - tokens?: Partial, - ): Promise { + tokens?: SettlementTokens, + ): Promise { if (this.stopped) throw new Error('FiatAssetAdapter called while stopped'); const jwsBody = settlementJWS.split('.')[1]; @@ -117,7 +110,7 @@ export class FiatAssetAdapter implements AssetAdapter { const jsonBody = atob(jwsBody.replace(/_/g, '/').replace(/-/g, '+')); const payload = JSON.parse(jsonBody) as SettlementInstruction; - let htlc: HtlcDetails; + let htlc: Htlc; try { htlc = await this.client.settleHtlc(payload.contractId, secret, settlementJWS, tokens); } catch (error) { @@ -132,7 +125,7 @@ export class FiatAssetAdapter implements AssetAdapter { return htlc; } - public async awaitSettlementConfirmation(id: string, onUpdate?: (tx: HtlcDetails) => any): Promise { + public async awaitSettlementConfirmation(id: string, onUpdate?: (tx: Htlc) => any): Promise { return this.findTransaction(id, (htlc) => { if (htlc.status !== HtlcStatus.SETTLED) return false; diff --git a/src/IAssetAdapter.ts b/src/IAssetAdapter.ts index 9f690a8..b8427eb 100644 --- a/src/IAssetAdapter.ts +++ b/src/IAssetAdapter.ts @@ -1,6 +1,6 @@ import type { BitcoinClient, TransactionDetails as BitcoinTransactionDetails } from './BitcoinAssetAdapter'; import type { GenericEvent as Erc20TransactionDetails, Web3Client } from './Erc20AssetAdapter'; -import type { HtlcDetails, OasisClient, SettleHtlcTokens } from './FiatAssetAdapter'; +import type { OasisClient, OasisHtlcDetails, OasisSettlementTokens } from './FiatAssetAdapter'; import type { NimiqClient, TransactionDetails as NimiqTransactionDetails } from './NimiqAssetAdapter'; export enum SwapAsset { @@ -18,7 +18,7 @@ export type FiatSwapAsset = SwapAsset.EUR | SwapAsset.CRC; export type Transaction = TAsset extends SwapAsset.NIM ? NimiqTransactionDetails : TAsset extends SwapAsset.BTC ? BitcoinTransactionDetails : TAsset extends SwapAsset.USDC | SwapAsset.USDC_MATIC | SwapAsset.USDT ? Erc20TransactionDetails - : TAsset extends FiatSwapAsset ? HtlcDetails + : TAsset extends FiatSwapAsset ? OasisHtlcDetails : never; export type Client = TAsset extends SwapAsset.NIM ? NimiqClient @@ -52,7 +52,7 @@ export interface AssetAdapter { serializedTx: string, secret: string, hash: string, - tokens?: Partial, + tokens?: OasisSettlementTokens, ): Promise>; awaitSettlementConfirmation( diff --git a/src/SwapHandler.ts b/src/SwapHandler.ts index 2c4c7b2..e5f9773 100644 --- a/src/SwapHandler.ts +++ b/src/SwapHandler.ts @@ -1,7 +1,7 @@ import { BitcoinAssetAdapter } from './BitcoinAssetAdapter'; import { Erc20AssetAdapter } from './Erc20AssetAdapter'; import { FiatAssetAdapter } from './FiatAssetAdapter'; -import type { SettleHtlcTokens } from './FiatAssetAdapter'; +import type { OasisSettlementTokens } from './FiatAssetAdapter'; import { AssetAdapter, SwapAsset } from './IAssetAdapter'; import type { Client, Transaction } from './IAssetAdapter'; import { NimiqAssetAdapter } from './NimiqAssetAdapter'; @@ -124,7 +124,7 @@ export class SwapHandler public async settleIncoming( serializedTx: string, secret: string, - tokens?: Partial, + tokens?: OasisSettlementTokens, ): Promise> { return this.toAssetAdapter.settleHtlc( serializedTx, diff --git a/yarn.lock b/yarn.lock index 84f460c..fdbb1c9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -395,10 +395,9 @@ dependencies: bitcoinjs-lib "^5.1.10" -"@nimiq/oasis-api@^1.0.1": +"@nimiq/oasis-api@https://github.com/nimiq/oasis-api-js#9d63fac0ab1364e4e1494334ee2d74f3d6f96b35": version "1.1.1" - resolved "https://registry.yarnpkg.com/@nimiq/oasis-api/-/oasis-api-1.1.1.tgz#d1aa3d0f9afabf9116205809a0fc72d2e392bafa" - integrity sha512-jXNO7nvE0mzAyDCrucByv5AcyDWZjyqb9810YctysxqUtOxNG27hPkhomL+WW6nrnTVgvriJo3yaTFPTfLphKw== + resolved "https://github.com/nimiq/oasis-api-js#9d63fac0ab1364e4e1494334ee2d74f3d6f96b35" "@oxlint/darwin-arm64@0.10.3": version "0.10.3" From 34d3a849215037e95b58e8ef04444fc8826c603f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren?= Date: Fri, 26 Jul 2024 09:52:59 +0200 Subject: [PATCH 4/6] Update @nimiq/oasis-api dep --- package.json | 2 +- yarn.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 3d6de03..b907fa9 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "dependencies": { "@nimiq/core-web": "^1.5.8", "@nimiq/electrum-client": "https://github.com/nimiq/electrum-client#build", - "@nimiq/oasis-api": "https://github.com/nimiq/oasis-api-js#9d63fac0ab1364e4e1494334ee2d74f3d6f96b35", + "@nimiq/oasis-api": "github:nimiq/oasis-api-js#dbfcdf4707c8a030022b3474126f4596bacbc1c1", "ethers": "^5.7.2", "promise.prototype.finally": "^3.1.3" }, diff --git a/yarn.lock b/yarn.lock index fdbb1c9..680275e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -395,9 +395,9 @@ dependencies: bitcoinjs-lib "^5.1.10" -"@nimiq/oasis-api@https://github.com/nimiq/oasis-api-js#9d63fac0ab1364e4e1494334ee2d74f3d6f96b35": +"@nimiq/oasis-api@github:nimiq/oasis-api-js#dbfcdf4707c8a030022b3474126f4596bacbc1c1": version "1.1.1" - resolved "https://github.com/nimiq/oasis-api-js#9d63fac0ab1364e4e1494334ee2d74f3d6f96b35" + resolved "https://codeload.github.com/nimiq/oasis-api-js/tar.gz/dbfcdf4707c8a030022b3474126f4596bacbc1c1" "@oxlint/darwin-arm64@0.10.3": version "0.10.3" From 020fe24b35053da09a5f315f16f52f60ed74f235 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren?= Date: Fri, 26 Jul 2024 10:12:08 +0200 Subject: [PATCH 5/6] Sort some imports --- src/SwapHandler.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SwapHandler.ts b/src/SwapHandler.ts index e5f9773..0365bed 100644 --- a/src/SwapHandler.ts +++ b/src/SwapHandler.ts @@ -2,8 +2,8 @@ import { BitcoinAssetAdapter } from './BitcoinAssetAdapter'; import { Erc20AssetAdapter } from './Erc20AssetAdapter'; import { FiatAssetAdapter } from './FiatAssetAdapter'; import type { OasisSettlementTokens } from './FiatAssetAdapter'; -import { AssetAdapter, SwapAsset } from './IAssetAdapter'; -import type { Client, Transaction } from './IAssetAdapter'; +import { SwapAsset } from './IAssetAdapter'; +import type { AssetAdapter, Client, Transaction } from './IAssetAdapter'; import { NimiqAssetAdapter } from './NimiqAssetAdapter'; // Re-export to centralize exports From cabdaf253552fb5b87d8a2cf39377a1ba4445d66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren?= Date: Mon, 12 Aug 2024 11:52:43 +0200 Subject: [PATCH 6/6] Update @nimiq/oasis-api dep --- package.json | 2 +- yarn.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index b907fa9..98af380 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "dependencies": { "@nimiq/core-web": "^1.5.8", "@nimiq/electrum-client": "https://github.com/nimiq/electrum-client#build", - "@nimiq/oasis-api": "github:nimiq/oasis-api-js#dbfcdf4707c8a030022b3474126f4596bacbc1c1", + "@nimiq/oasis-api": "github:nimiq/oasis-api-js#fbd74179a5b9590f8e6dfe9b08ca47122db2ce1e", "ethers": "^5.7.2", "promise.prototype.finally": "^3.1.3" }, diff --git a/yarn.lock b/yarn.lock index 680275e..7045bf7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -395,9 +395,9 @@ dependencies: bitcoinjs-lib "^5.1.10" -"@nimiq/oasis-api@github:nimiq/oasis-api-js#dbfcdf4707c8a030022b3474126f4596bacbc1c1": +"@nimiq/oasis-api@github:nimiq/oasis-api-js#fbd74179a5b9590f8e6dfe9b08ca47122db2ce1e": version "1.1.1" - resolved "https://codeload.github.com/nimiq/oasis-api-js/tar.gz/dbfcdf4707c8a030022b3474126f4596bacbc1c1" + resolved "https://codeload.github.com/nimiq/oasis-api-js/tar.gz/fbd74179a5b9590f8e6dfe9b08ca47122db2ce1e" "@oxlint/darwin-arm64@0.10.3": version "0.10.3"