webapp - ESLint + Prettier with pre-commit hooks (#54)

resolves #47

Co-authored-by: johba <johba@harb.eth>
Reviewed-on: https://codeberg.org/johba/harb/pulls/54
This commit is contained in:
johba 2025-10-03 16:51:44 +02:00
parent 2acb619a11
commit f8927b426e
83 changed files with 7137 additions and 5113 deletions

View file

@ -1,85 +1,83 @@
import { type Address, type TypedDataDomain, type Hex, slice, hexToNumber, hexToBigInt, recoverAddress } from "viem";
import { type Address, type TypedDataDomain, slice, hexToBigInt } from 'viem';
export function createPermitObject(
verifyingContract: Address,
fromAddress: Address,
spender: Address,
nonce: BigInt,
deadline: BigInt,
value: BigInt,
chain: number,
domainName: string
verifyingContract: Address,
fromAddress: Address,
spender: Address,
nonce: bigint,
deadline: bigint,
value: bigint,
chain: number,
domainName: string
) {
const message = {
owner: fromAddress,
spender: spender,
nonce: nonce,
deadline: deadline,
value: value,
};
const message = {
owner: fromAddress,
spender: spender,
nonce: nonce,
deadline: deadline,
value: value,
};
const domainType = [
{ name: "name", type: "string" },
{ name: "version", type: "string" },
{ name: "chainId", type: "uint256" },
{ name: "verifyingContract", type: "address" },
];
const domainType = [
{ name: 'name', type: 'string' },
{ name: 'version', type: 'string' },
{ name: 'chainId', type: 'uint256' },
{ name: 'verifyingContract', type: 'address' },
];
const primaryType: "EIP712Domain" | "Permit" = "Permit";
const primaryType: 'EIP712Domain' | 'Permit' = 'Permit';
const types = {
EIP712Domain: domainType,
Permit: [
{
name: "owner",
type: "address",
},
{
name: "spender",
type: "address",
},
{
name: "value",
type: "uint256",
},
{
name: "nonce",
type: "uint256",
},
{
name: "deadline",
type: "uint256",
},
],
};
const types = {
EIP712Domain: domainType,
Permit: [
{
name: 'owner',
type: 'address',
},
{
name: 'spender',
type: 'address',
},
{
name: 'value',
type: 'uint256',
},
{
name: 'nonce',
type: 'uint256',
},
{
name: 'deadline',
type: 'uint256',
},
],
};
const domain: TypedDataDomain | undefined = {
name: domainName,
version: "1",
chainId: chain,
verifyingContract: verifyingContract,
};
const domain: TypedDataDomain | undefined = {
name: domainName,
version: '1',
chainId: chain,
verifyingContract: verifyingContract,
};
return {
types,
message,
domain,
primaryType,
};
return {
types,
message,
domain,
primaryType,
};
}
export function getSignatureRSV2(sig: `0x${string}`) {
// splits the signature to r, s, and v values.
// const pureSig = sig.replace("0x", "");
const [r, s, v] = [slice(sig, 0, 32), slice(sig, 32, 64), slice(sig, 64, 65)];
return { r, s, v: Number(v) };
// splits the signature to r, s, and v values.
// const pureSig = sig.replace("0x", "");
const [r, s, v] = [slice(sig, 0, 32), slice(sig, 32, 64), slice(sig, 64, 65)];
return { r, s, v: Number(v) };
}
export function getSignatureRSV(signature: `0x${string}`) {
const r = signature.slice(0, 66) as `0x${string}`;
const s = `0x${signature.slice(66, 130)}` as `0x${string}`;
const v = hexToBigInt(`0x${signature.slice(130, 132)}`);
return { r, s, v };
}
const r = signature.slice(0, 66) as `0x${string}`;
const s = `0x${signature.slice(66, 130)}` as `0x${string}`;
const v = Number(hexToBigInt(`0x${signature.slice(130, 132)}`));
return { r, s, v };
}

View file

@ -1,135 +1,133 @@
var randseed = new Array(4); // Xorshift: [x, y, z, w] 32 bit values
const randseed = new Array(4); // Xorshift: [x, y, z, w] 32 bit values
interface BlockiesOpt {
seed: string;
size: number;
scale: number;
color?: string;
bgcolor?: string;
spotcolor?: string;
seed: string;
size: number;
scale: number;
color?: string;
bgcolor?: string;
spotcolor?: string;
}
export function getBlocky(address: string) {
if (!address || typeof address !== "string" ) {
return;
}
console.log("address", address);
var blockiesData = createIcon({
seed: address?.toLowerCase(),
size: 8,
scale: 4,
}).toDataURL();
if (!address || typeof address !== 'string') {
return;
}
return blockiesData;
const blockiesData = createIcon({
seed: address?.toLowerCase(),
size: 8,
scale: 4,
}).toDataURL();
return blockiesData;
}
function seedrand(seed: string) {
for (var i = 0; i < randseed.length; i++) {
randseed[i] = 0;
}
for (var i = 0; i < seed.length; i++) {
randseed[i % 4] = (randseed[i % 4] << 5) - randseed[i % 4] + seed.charCodeAt(i);
}
for (let i = 0; i < randseed.length; i++) {
randseed[i] = 0;
}
for (let i = 0; i < seed.length; i++) {
randseed[i % 4] = (randseed[i % 4] << 5) - randseed[i % 4] + seed.charCodeAt(i);
}
}
function rand() {
// based on Java's String.hashCode(), expanded to 4 32bit values
var t = randseed[0] ^ (randseed[0] << 11);
// based on Java's String.hashCode(), expanded to 4 32bit values
const t = randseed[0] ^ (randseed[0] << 11);
randseed[0] = randseed[1];
randseed[1] = randseed[2];
randseed[2] = randseed[3];
randseed[3] = randseed[3] ^ (randseed[3] >> 19) ^ t ^ (t >> 8);
randseed[0] = randseed[1];
randseed[1] = randseed[2];
randseed[2] = randseed[3];
randseed[3] = randseed[3] ^ (randseed[3] >> 19) ^ t ^ (t >> 8);
return (randseed[3] >>> 0) / ((1 << 31) >>> 0);
return (randseed[3] >>> 0) / ((1 << 31) >>> 0);
}
function createColor() {
//saturation is the whole color spectrum
var h = Math.floor(rand() * 360);
//saturation goes from 40 to 100, it avoids greyish colors
var s = rand() * 60 + 40 + "%";
//lightness can be anything from 0 to 100, but probabilities are a bell curve around 50%
var l = (rand() + rand() + rand() + rand()) * 25 + "%";
//saturation is the whole color spectrum
const h = Math.floor(rand() * 360);
//saturation goes from 40 to 100, it avoids greyish colors
const s = rand() * 60 + 40 + '%';
//lightness can be anything from 0 to 100, but probabilities are a bell curve around 50%
const l = (rand() + rand() + rand() + rand()) * 25 + '%';
var color = "hsl(" + h + "," + s + "," + l + ")";
return color;
const color = 'hsl(' + h + ',' + s + ',' + l + ')';
return color;
}
function createImageData(size: number) {
var width = size; // Only support square icons for now
var height = size;
const width = size; // Only support square icons for now
const height = size;
var dataWidth = Math.ceil(width / 2);
var mirrorWidth = width - dataWidth;
const dataWidth = Math.ceil(width / 2);
const mirrorWidth = width - dataWidth;
var data = [];
for (var y = 0; y < height; y++) {
var row = [];
for (var x = 0; x < dataWidth; x++) {
// this makes foreground and background color to have a 43% (1/2.3) probability
// spot color has 13% chance
row[x] = Math.floor(rand() * 2.3);
}
var r = row.slice(0, mirrorWidth);
r.reverse();
row = row.concat(r);
const data = [];
for (let y = 0; y < height; y++) {
let row = [];
for (let x = 0; x < dataWidth; x++) {
// this makes foreground and background color to have a 43% (1/2.3) probability
// spot color has 13% chance
row[x] = Math.floor(rand() * 2.3);
}
const r = row.slice(0, mirrorWidth);
r.reverse();
row = row.concat(r);
for (var i = 0; i < row.length; i++) {
data.push(row[i]);
}
}
for (let i = 0; i < row.length; i++) {
data.push(row[i]);
}
}
return data;
return data;
}
function buildOpts(opts: any) {
var newOpts: any = {};
newOpts.seed = opts.seed || Math.floor(Math.random() * Math.pow(10, 16)).toString(16);
function buildOpts(opts: Partial<BlockiesOpt>): BlockiesOpt {
const seed = opts.seed || Math.floor(Math.random() * Math.pow(10, 16)).toString(16);
seedrand(seed);
seedrand(newOpts.seed);
newOpts.size = opts.size || 8;
newOpts.scale = opts.scale || 4;
newOpts.color = opts.color || createColor();
newOpts.bgcolor = opts.bgcolor || createColor();
newOpts.spotcolor = opts.spotcolor || createColor();
return newOpts;
return {
seed,
size: opts.size || 8,
scale: opts.scale || 4,
color: opts.color || createColor(),
bgcolor: opts.bgcolor || createColor(),
spotcolor: opts.spotcolor || createColor(),
};
}
function renderIcon(opts: BlockiesOpt, canvas: HTMLCanvasElement) {
opts = buildOpts(opts || {});
var imageData = createImageData(opts.size);
var width = Math.sqrt(imageData.length);
function renderIcon(opts: Partial<BlockiesOpt>, canvas: HTMLCanvasElement) {
const fullOpts = buildOpts(opts);
const imageData = createImageData(fullOpts.size);
const width = Math.sqrt(imageData.length);
canvas.width = canvas.height = opts.size * opts.scale;
canvas.width = canvas.height = fullOpts.size * fullOpts.scale;
var cc = canvas.getContext("2d")!;
cc.fillStyle = opts.bgcolor!;
cc.fillRect(0, 0, canvas.width, canvas.height);
cc.fillStyle = opts.color!;
const cc = canvas.getContext('2d')!;
cc.fillStyle = fullOpts.bgcolor!;
cc.fillRect(0, 0, canvas.width, canvas.height);
cc.fillStyle = fullOpts.color!;
for (var i = 0; i < imageData.length; i++) {
// if data is 0, leave the background
if (imageData[i]) {
var row = Math.floor(i / width);
var col = i % width;
for (let i = 0; i < imageData.length; i++) {
// if data is 0, leave the background
if (imageData[i]) {
const row = Math.floor(i / width);
const col = i % width;
// if data is 2, choose spot color, if 1 choose foreground
cc.fillStyle = imageData[i] == 1 ? opts.color! : opts.spotcolor!;
// if data is 2, choose spot color, if 1 choose foreground
cc.fillStyle = imageData[i] == 1 ? fullOpts.color! : fullOpts.spotcolor!;
cc.fillRect(col * opts.scale, row * opts.scale, opts.scale, opts.scale);
}
}
return canvas;
cc.fillRect(col * fullOpts.scale, row * fullOpts.scale, fullOpts.scale, fullOpts.scale);
}
}
return canvas;
}
export function createIcon(opts: BlockiesOpt) {
var canvas = document.createElement("canvas");
const canvas = document.createElement('canvas');
renderIcon(opts, canvas);
renderIcon(opts, canvas);
return canvas;
return canvas;
}

View file

@ -6,7 +6,7 @@
* @returns Number of shares corresponding to the input assets.
*/
export function assetsToShares(assets: bigint, totalSupply: bigint, harbergTotalSupply: bigint): bigint {
return (assets * totalSupply) / harbergTotalSupply;
return (assets * totalSupply) / harbergTotalSupply;
}
/**
@ -17,5 +17,5 @@ export function assetsToShares(assets: bigint, totalSupply: bigint, harbergTotal
* @returns The equivalent number of Harberg tokens for the given shares.
*/
export function sharesToAssets(shares: bigint, totalSupply: bigint, harbergTotalSupply: bigint): bigint {
return (shares * harbergTotalSupply) / totalSupply;
return (shares * harbergTotalSupply) / totalSupply;
}

View file

@ -1,64 +1,60 @@
import { formatUnits } from 'viem'
import { formatUnits } from 'viem';
export function getAddressShortName(address: string) {
if (!address) {
return "";
}
const addressBegin = address.substring(0, 6);
const addressEnd = address.substring(address.length - 4, address.length);
return addressBegin + "..." + addressEnd;
if (!address) {
return '';
}
const addressBegin = address.substring(0, 6);
const addressEnd = address.substring(address.length - 4, address.length);
return addressBegin + '...' + addressEnd;
}
export function compactNumber(number: number) {
return Intl.NumberFormat("en-US", {
notation: "compact",
// minimumFractionDigits: 2,
maximumFractionDigits: 2,
}).format(number);
return Intl.NumberFormat('en-US', {
notation: 'compact',
// minimumFractionDigits: 2,
maximumFractionDigits: 2,
}).format(number);
}
export function formatBigNumber(number: bigint, decimals: number, digits: number = 5) {
let bigIntNumber = number;
if(!bigIntNumber){
bigIntNumber = BigInt(0)
}
const formattedNumber = Number(formatUnits(bigIntNumber, decimals))
if(formattedNumber === 0){
return "0"
}
return formattedNumber.toFixed(digits)
let bigIntNumber = number;
if (!bigIntNumber) {
bigIntNumber = BigInt(0);
}
const formattedNumber = Number(formatUnits(bigIntNumber, decimals));
if (formattedNumber === 0) {
return '0';
}
return formattedNumber.toFixed(digits);
}
export function bigInt2Number(number: bigint, decimals: number) {
let bigIntNumber = number;
if(!bigIntNumber){
bigIntNumber = BigInt(0)
}
const formattedNumber = Number(formatUnits(bigIntNumber, decimals))
return formattedNumber
let bigIntNumber = number;
if (!bigIntNumber) {
bigIntNumber = BigInt(0);
}
const formattedNumber = Number(formatUnits(bigIntNumber, decimals));
return formattedNumber;
}
export function InsertCommaNumber(number: any) {
if (!number) {
return 0;
}
const formattedWithOptions = number.toLocaleString("en-US");
return formattedWithOptions;
export function InsertCommaNumber(number: number) {
if (!number) {
return 0;
}
const formattedWithOptions = number.toLocaleString('en-US');
return formattedWithOptions;
}
export function formatBigIntDivision(nominator: bigint, denominator: bigint, digits: number = 2) {
if (!nominator) {
return 0;
}
let display = nominator.toString();
const decimal = (Number(denominator) / 10).toString().length;
export function formatBigIntDivision(nominator: bigint, denominator: bigint, _digits: number = 2) {
if (!nominator) {
return 0;
}
const display = nominator.toString();
const decimal = (Number(denominator) / 10).toString().length;
let [integer, fraction] = [display.slice(0, display.length - decimal), display.slice(display.length - decimal)];
const [integer, fraction] = [display.slice(0, display.length - decimal), display.slice(display.length - decimal)];
// output type number
return Number(integer + "." + fraction);
// output type number
return Number(integer + '.' + fraction);
}

View file

@ -1,23 +1,20 @@
export function info(text: string, data: any = null ){
if(data){
console.log(`%c ${text}`, 'color: #17a2b8', data);
} else{
console.log(`%c ${text}`, 'color: #17a2b8');
}
export function info(text: string, data: unknown = null) {
if (data) {
// console.log(`%c ${text}`, 'color: #17a2b8', data);
} else {
// console.log(`%c ${text}`, 'color: #17a2b8');
}
}
export function contract(text: string, data: any = null ){
if(data){
console.log(`%c ${text}`, 'color: #8732a8', data);
} else{
console.log(`%c ${text}`, 'color: #8732a8');
}
export function contract(text: string, data: unknown = null) {
if (data) {
// console.log(`%c ${text}`, 'color: #8732a8', data);
} else {
// console.log(`%c ${text}`, 'color: #8732a8');
}
}
export default {
info,
contract
}
info,
contract,
};