UNPKG

@nimiq/libswap

Version:

Typed Javascript library to handle atomic swaps.

100 lines (99 loc) 3.55 kB
import { HtlcStatus, SettlementStatus } from '@nimiq/oasis-api'; export class EuroAssetAdapter { constructor(client) { this.client = client; this.cancelCallback = null; this.stopped = false; } async findTransaction(id, test) { const check = async () => { try { const htlc = await this.client.getHtlc(id); if (test(htlc)) return htlc; } catch (error) { console.error(error); if (error.message !== 'HTLC not found') { } } return null; }; const htlc = await check(); if (htlc) return htlc; return new Promise((resolve, reject) => { const interval = window.setInterval(() => { check().then((htlc) => { if (!htlc) return; cleanup(); resolve(htlc); }); }, 5 * 1000); const cleanup = () => { window.clearInterval(interval); this.cancelCallback = null; }; this.cancelCallback = (reason) => { cleanup(); reject(reason); }; }); } async awaitHtlcFunding(id, value, data, confirmations, onUpdate) { return this.findTransaction(id, (htlc) => { if (htlc.status === HtlcStatus.CLEARED || htlc.status === HtlcStatus.SETTLED) return true; if (typeof onUpdate === 'function') onUpdate(htlc); return false; }); } async fundHtlc() { throw new Error('Method "fundHtlc" not available for EUR HTLCs'); } async awaitHtlcSettlement(id) { return this.findTransaction(id, (htlc) => typeof htlc.preimage.value === 'string'); } async awaitSwapSecret(id) { const tx = await this.awaitHtlcSettlement(id); return tx.preimage.value; } async settleHtlc(settlementJWS, secret, hash, authorizationToken) { if (this.stopped) throw new Error('EuroAssetAdapter called while stopped'); const jwsBody = settlementJWS.split('.')[1]; const jsonBody = atob(jwsBody.replace(/_/g, '/').replace(/-/g, '+')); const payload = JSON.parse(jsonBody); let htlc; try { htlc = await this.client.settleHtlc(payload.contractId, secret, settlementJWS, authorizationToken); } catch (error) { console.error(error); htlc = await this.client.getHtlc(payload.contractId); } if (htlc.status !== HtlcStatus.SETTLED || htlc.settlement.status === SettlementStatus.WAITING) { throw new Error('Could not settle OASIS HTLC (invalid secret or authorization token?)'); } return htlc; } async awaitSettlementConfirmation(id, onUpdate) { return this.findTransaction(id, (htlc) => { if (htlc.status !== HtlcStatus.SETTLED) return false; if (htlc.settlement.status === SettlementStatus.ACCEPTED || htlc.settlement.status === SettlementStatus.CONFIRMED) return true; if (typeof onUpdate === 'function') onUpdate(htlc); return false; }); } stop(reason) { if (this.cancelCallback) this.cancelCallback(reason); this.stopped = true; } }