UNPKG

lotus-sdk

Version:

Central repository for several classes of tools for integrating with, and building for, the Lotusia ecosystem

164 lines (163 loc) 4.93 kB
import { Address } from './address.js'; const DEFAULT_PREFIX = 'giveto:'; const URI_PREFIXES = [DEFAULT_PREFIX]; export class URI { _address; _amount; _label; _message; _otherParams = {}; constructor(data, knownParams) { if (typeof data === 'string') { this._fromString(data, knownParams); } else if (typeof data === 'object') { this._fromObject(data); } else { throw new Error('Invalid URI data'); } } static fromString(data) { return new URI(data); } static fromObject(data) { return new URI(data); } static isValid(data, knownParams) { try { new URI(data, knownParams); return true; } catch (e) { return false; } } _fromString(uriString, knownParams) { const index = URI_PREFIXES.findIndex(prefix => uriString.startsWith(prefix)); if (index === -1) { throw new Error('Invalid Lotus URI'); } const prefix = URI_PREFIXES[index]; const uri = uriString.substring(prefix.length); const parts = uri.split('?'); if (parts.length === 0) { throw new Error('Invalid Lotus URI format'); } const addressPart = parts[0]; if (addressPart) { try { this._address = Address.fromString(addressPart); } catch (e) { throw new Error('Invalid Lotus address in URI'); } } if (parts.length > 1) { const queryString = parts[1]; const params = new URLSearchParams(queryString); for (const [key, value] of params) { switch (key) { case 'amount': this._amount = parseFloat(value); break; case 'label': this._label = decodeURIComponent(value); break; case 'message': this._message = decodeURIComponent(value); break; default: if (!knownParams || knownParams.includes(key)) { this._otherParams[key] = decodeURIComponent(value); } break; } } } } _fromObject(data) { if (data.address) { try { this._address = Address.fromString(data.address); } catch (e) { throw new Error('Invalid Lotus address'); } } if (data.amount !== undefined) { this._amount = data.amount; } if (data.label) { this._label = data.label; } if (data.message) { this._message = data.message; } Object.keys(data).forEach(key => { if (!['address', 'amount', 'label', 'message'].includes(key)) { this._otherParams[key] = String(data[key]); } }); } get address() { return this._address; } get amount() { return this._amount; } get label() { return this._label; } get message() { return this._message; } get otherParams() { return { ...this._otherParams }; } toString(prefix) { if (!this._address) { throw new Error('Cannot convert URI to string without address'); } if (prefix && !URI_PREFIXES.includes(prefix)) { throw new Error('Invalid URI prefix specified'); } let uri = `${prefix ?? DEFAULT_PREFIX}${this._address.toString()}`; const params = []; if (this._amount !== undefined) { params.push(`amount=${this._amount}`); } if (this._label) { params.push(`label=${encodeURIComponent(this._label)}`); } if (this._message) { params.push(`message=${encodeURIComponent(this._message)}`); } Object.keys(this._otherParams).forEach(key => { params.push(`${key}=${encodeURIComponent(this._otherParams[key])}`); }); if (params.length > 0) { uri += '?' + params.join('&'); } return uri; } toObject() { const obj = {}; if (this._address) { obj.address = this._address.toString(); } if (this._amount !== undefined) { obj.amount = this._amount; } if (this._label) { obj.label = this._label; } if (this._message) { obj.message = this._message; } Object.keys(this._otherParams).forEach(key => { obj[key] = this._otherParams[key]; }); return obj; } }