@citizenwallet/sdk
Version:
An sdk to easily work with citizen wallet.
157 lines (121 loc) • 4.1 kB
text/typescript
import { CommunityConfig } from "../config";
import { compress, decompress } from "../utils/gzip";
export const generateLegacyReceiveLink = (
baseUrl: string,
config: CommunityConfig,
account: string,
amount?: string,
description?: string
): string => {
const alias = config.community.alias;
let receiveParams = `?address=${account}&alias=${alias}`;
if (amount) {
receiveParams += `&amount=${amount}`;
}
if (description) {
receiveParams += `&message=${description}`;
}
const compressedParams = compress(receiveParams);
return `${baseUrl}/#/?alias=${alias}&receiveParams=${compressedParams}`;
};
// enum that represents the different qr code formats
export enum QRFormat {
address,
voucher,
eip681,
eip681Transfer,
receiveUrl,
unsupported,
walletConnectPairing,
}
const isWalletConnectURI = (uri: string): boolean => {
// WalletConnect URI format pattern
const wcPattern =
/^wc:[a-f0-9]{64}@\d+\?((?!&)[^&]*&)*relay-protocol=irn(&(?!&)[^&]*)*&symKey=[a-f0-9]{64}(&(?!&)[^&]*)*$/;
return wcPattern.test(uri);
}
export const parseQRFormat = (raw: string): QRFormat => {
if (raw.startsWith("ethereum:") && !raw.includes("/")) {
return QRFormat.eip681;
} else if (raw.startsWith("ethereum:") && raw.includes("/transfer")) {
return QRFormat.eip681Transfer;
} else if (raw.startsWith("0x")) {
return QRFormat.address;
} else if (raw.includes("receiveParams=")) {
return QRFormat.receiveUrl;
} else if (raw.includes("voucher=")) {
return QRFormat.voucher;
} else if (isWalletConnectURI(raw)) {
return QRFormat.walletConnectPairing;
} else {
return QRFormat.unsupported;
}
};
function parseEIP681(raw: string): [string, string | null] {
const url = new URL(raw);
let address = url.pathname.split("/")[1];
if (address.includes("@")) {
// includes chain id, remove
address = address.split("@")[0];
}
const value = url.searchParams.get("value");
return [address, value];
}
function parseEIP681Transfer(raw: string): [string, string | null] {
const url = new URL(raw);
const address = url.searchParams.get("address");
const value = url.searchParams.get("uint256");
return [address || "", value];
}
function parseReceiveLink(raw: string): [string, string | null] {
const receiveUrl = new URL(raw.replace("#/", ""));
const encodedParams = receiveUrl.searchParams.get("receiveParams");
if (encodedParams === null) {
return ["", null];
}
const decodedParams = decompress(encodedParams);
const params = new URLSearchParams(decodedParams);
const address = params.get("address");
const amount = params.get("amount");
return [address || "", amount];
}
export const parseQRCode = (raw: string): [string, string | null] => {
const format = parseQRFormat(raw);
switch (format) {
case QRFormat.address:
return [raw, null];
case QRFormat.eip681:
return parseEIP681(raw);
case QRFormat.eip681Transfer:
return parseEIP681Transfer(raw);
case QRFormat.receiveUrl:
return parseReceiveLink(raw);
case QRFormat.voucher:
// vouchers are invalid for a transfer
default:
return ["", null];
}
};
export const parseAliasFromReceiveLink = (raw: string): string | null => {
console.log('raw.replace("#/", "")', raw.replace("#/", ""));
const receiveUrl = new URL(raw.replace("#/", ""));
const encodedParams = receiveUrl.searchParams.get("receiveParams");
if (encodedParams === null) {
return null;
}
const decodedParams = decompress(encodedParams);
const params = new URLSearchParams(decodedParams);
const alias = params.get("alias");
return alias;
};
export const parseMessageFromReceiveLink = (raw: string): string | null => {
const receiveUrl = new URL(raw.replace("#/", ""));
const encodedParams = receiveUrl.searchParams.get("receiveParams");
if (encodedParams === null) {
return null;
}
const decodedParams = decompress(encodedParams);
const params = new URLSearchParams(decodedParams);
const message = params.get("message");
return message;
};