raiden-ts
Version:
Raiden Light Client Typescript/Javascript SDK
149 lines • 5.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.peerIsOnlineLC = exports.getPresencesByAddress = exports.getPresencesByUserId = exports.getSortedAddresses = exports.getCap = exports.parseCaps = exports.stringifyCaps = exports.getAddressFromUserId = void 0;
const address_1 = require("@ethersproject/address");
const rxjs_1 = require("rxjs");
const operators_1 = require("rxjs/operators");
const constants_1 = require("../constants");
const actions_1 = require("../utils/actions");
const data_1 = require("../utils/data");
const actions_2 = require("./actions");
const userRe = /^@(0x[0-9a-f]{40})[.:]/i;
/**
* Extract the address in a matrix userId and returns it, or undefined it none
*
* @param userId - matrix user identifier
* @returns address contained in userId
*/
function getAddressFromUserId(userId) {
let address;
try {
const match = userRe.exec(userId);
if (match)
address = (0, address_1.getAddress)(match[1]);
}
catch (e) { }
return address;
}
exports.getAddressFromUserId = getAddressFromUserId;
/**
* Stringify a caps mapping to a caps url
* E.g.'mxc://raiden.network/cap?k1=true&k2=v2&k2=v3&k4=null&k5=123'
*
* @param caps - Capabilities object/mapping
* @returns stringified version of caps
*/
function stringifyCaps(caps) {
const url = new URL('mxc://raiden.network/cap');
// URLSearchParams.append can handle all primitives
const appendParam = (key, value) => url.searchParams.append(key, value);
for (const [key, value] of Object.entries(caps)) {
if (Array.isArray(value))
value.forEach(appendParam.bind(null, key));
else
appendParam(key, value);
}
return url.href;
}
exports.stringifyCaps = stringifyCaps;
/**
* Parse a caps string in the format 'mxc://raiden.network/cap?k1=true&k2=v2&k2=v3&k4=null&k5=123'
* to a { k1: true, k2: ['v2','v3'], k4: null, k5: 123 } object
*
* @param caps - caps string
* @returns Caps mapping object
*/
function parseCaps(caps) {
if (!caps)
return;
const result = {};
try {
const url = new URL(caps);
url.searchParams.forEach((value, key) => {
let resValue = value;
// interpret *some* types of values
if (/^\d+$/.test(value))
resValue = (0, data_1.jsonParse)(value);
else {
const lowValue = value.toLowerCase();
if (lowValue === 'none' || lowValue === 'null')
resValue = null;
else if (lowValue === 'false')
resValue = false;
else if (lowValue === 'true')
resValue = true;
}
let val = result[key];
if (val === undefined) {
result[key] = resValue;
}
else {
if (!Array.isArray(val))
result[key] = val = [val];
val.push(resValue);
}
});
return result;
}
catch (err) { }
}
exports.parseCaps = parseCaps;
/**
* @param caps - Our or partner caps object (possibly empty/undefined)
* @param cap - Cap to fetch from
* @returns Specified capability, with proper fallback
*/
function getCap(caps, cap) {
return caps?.[cap] ?? constants_1.CapsFallback[cap];
}
exports.getCap = getCap;
/**
* Return addresses sorted in lexical order
*
* @param addresses - Addresses to sort
* @returns Addresses sorted in lexical order
*/
function getSortedAddresses(...addresses) {
return addresses.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
}
exports.getSortedAddresses = getSortedAddresses;
/**
* Aggregates seen presence updates by userId
*
* @returns custom operator mapping from stream of RaidenActions to userId-presences dict
*/
function getPresencesByUserId() {
const emptyDict = {};
return (0, rxjs_1.pipe)((0, operators_1.filter)(actions_2.matrixPresence.success.is), (0, operators_1.scan)((acc, action) => ({ ...acc, [action.payload.userId]: action }), emptyDict), (0, operators_1.startWith)(emptyDict));
}
exports.getPresencesByUserId = getPresencesByUserId;
/**
* Aggregates seen presence updates by online addresses (afawk)
*
* @returns custom operator mapping from stream of RaidenActions to address-presence dict
*/
function getPresencesByAddress() {
const emptyDict = {};
return (0, rxjs_1.pipe)((0, operators_1.filter)((0, actions_1.isActionOf)([actions_2.matrixPresence.success, actions_2.matrixPresence.failure])), (0, operators_1.scan)((acc, action) => {
if (actions_2.matrixPresence.success.is(action) && action.payload.available) {
acc[action.meta.address] = action;
}
else if (action.meta.address in acc) {
delete acc[action.meta.address];
}
return acc;
}, emptyDict), (0, operators_1.startWith)(emptyDict));
}
exports.getPresencesByAddress = getPresencesByAddress;
/**
* Check if given presence is from an online partner which is another Light Client
* For now, this checks peer is online (known presence) and has Capabilities.DELIVERY set to 0
*
* @param presence - optional presence update
* @returns true if partner is online and is another light-client
*/
function peerIsOnlineLC(presence) {
return !!presence && !getCap(presence.payload.caps, constants_1.Capabilities.DELIVERY);
}
exports.peerIsOnlineLC = peerIsOnlineLC;
//# sourceMappingURL=utils.js.map