@towns-protocol/sdk
Version:
For more details, visit the following resources:
125 lines • 4.09 kB
JavaScript
import { utils } from 'ethers';
import { keccak256 } from 'ethereum-cryptography/keccak';
import { bin_toHexString, isTestEnv, isNodeEnv, isBrowser, bin_fromHexString, } from '@towns-protocol/dlog';
export function unsafeProp(prop) {
return prop === '__proto__' || prop === 'prototype' || prop === 'constructor';
}
export function safeSet(obj, prop, value) {
if (unsafeProp(prop)) {
throw new Error('Trying to modify prototype or constructor');
}
obj[prop] = value;
}
// In string form an ethereum address is 42 characters long, should start with 0x and TODO: have ERC-55 checksum.
// In binary form it is 20 bytes long.
export const isEthereumAddress = (address) => {
if (address instanceof Uint8Array) {
return address.length === 20;
}
else if (typeof address === 'string') {
return utils.isAddress(address);
}
return false;
};
export const ethereumAddressToBytes = (address) => bin_fromHexString(address);
export const ethereumAddressFromBytes = (bytes) => bin_toHexString(bytes);
export const ethereumAddressAsString = (address) => typeof address === 'string' ? address : ethereumAddressFromBytes(address);
export const ethereumAddressAsBytes = (address) => typeof address === 'string' ? ethereumAddressToBytes(address) : address;
export function stripUndefinedMetadata(obj) {
const result = {};
for (const key in obj) {
const val = obj[key];
if (val !== undefined) {
result[key] = val;
}
}
return Object.keys(result).length > 0 ? result : undefined;
}
export function promiseTry(fn) {
return Promise.resolve(fn());
}
export function hashString(string) {
const encoded = new TextEncoder().encode(string);
const buffer = keccak256(encoded);
return bin_toHexString(buffer);
}
export function usernameChecksum(username, streamId) {
return hashString(`${username.toLowerCase()}:${streamId}`);
}
export function isIConnectError(obj) {
return obj !== null && typeof obj === 'object' && 'code' in obj && typeof obj.code === 'number';
}
export class MockEntitlementsDelegate {
async isEntitled(_spaceId, _channelId, _user, _permission) {
await new Promise((resolve) => setTimeout(resolve, 10));
return true;
}
}
export function removeCommon(x, y) {
const result = [];
let i = 0;
let j = 0;
while (i < x.length && j < y.length) {
if (x[i] < y[j]) {
result.push(x[i]);
i++;
}
else if (x[i] > y[j]) {
j++;
}
else {
i++;
j++;
}
}
// Append remaining elements from x
if (i < x.length) {
result.push(...x.slice(i));
}
return result;
}
export function getEnvVar(key, defaultValue = '') {
if (isNodeEnv || isTestEnv()) {
return process.env[key] ?? defaultValue;
}
if (isBrowser) {
if (localStorage != undefined) {
return localStorage.getItem(key) ?? defaultValue;
}
}
return defaultValue;
}
export function isMobileSafari() {
if (isNodeEnv) {
return false;
}
if (!navigator || !navigator.userAgent) {
return false;
}
return /iPad|iPhone|iPod/.test(navigator.userAgent);
}
export function isBaseUrlIncluded(baseUrls, fullUrl) {
const urlObj = new URL(fullUrl);
const fullUrlBase = `${urlObj.protocol}//${urlObj.host}`;
return baseUrls.some((baseUrl) => fullUrlBase === baseUrl.trim());
}
export const randomUrlSelector = (urls) => {
const u = urls.split(',');
if (u.length === 0) {
throw new Error('No urls for backend provided');
}
else if (u.length === 1) {
return u[0];
}
else {
return u[Math.floor(Math.random() * u.length)];
}
};
export async function getTime(fn) {
const start = performance.now();
const result = await fn();
const end = performance.now();
return { result, time: end - start };
}
export const randomBytes = (len) => crypto.getRandomValues(new Uint8Array(len));
//# sourceMappingURL=utils.js.map