mirror of
https://github.com/Discreetly/interfaces.git
synced 2026-01-07 20:13:56 -05:00
init
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
dist/
|
||||
node_modules/
|
||||
7362
package-lock.json
generated
Normal file
7362
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
74
package.json
Normal file
74
package.json
Normal file
@@ -0,0 +1,74 @@
|
||||
{
|
||||
"name": "discreetly-interfaces",
|
||||
"version": "0.1.0",
|
||||
"description": "",
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"scripts": {
|
||||
"build": "rollup --config rollup.config.mjs",
|
||||
"test": "jest",
|
||||
"test:debug": "jest --silent=false",
|
||||
"test:benchmark": "jest --silent=false ./tests/circuit-wrapper.test.ts",
|
||||
"test:ci": "jest --silent=false --runInBand",
|
||||
"lint": "eslint --ext .ts,.tsx,.js,.jsx src/ -c .eslintrc.js",
|
||||
"format": "eslint --ext .ts,.tsx,.js,.jsx src/ -c .eslintrc.js --fix"
|
||||
},
|
||||
"keywords": [
|
||||
"rln",
|
||||
"rate-limiting-nullifier",
|
||||
"ethereum",
|
||||
"circom",
|
||||
"zk",
|
||||
"zero-knowledge",
|
||||
"zk-snarks",
|
||||
"zero-knowledge-proofs"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"main": "./dist/index.node.js",
|
||||
"module": "./dist/index.mjs",
|
||||
"browser": {
|
||||
"./dist/index.node.js": "./dist/index.mjs"
|
||||
},
|
||||
"types": "./dist/types/index.d.ts",
|
||||
"directories": {
|
||||
"dist": "./dist",
|
||||
"src": "./src",
|
||||
"test": "./tests"
|
||||
},
|
||||
"files": [
|
||||
"dist/",
|
||||
"src/",
|
||||
"LICENSE",
|
||||
"README.md"
|
||||
],
|
||||
"dependencies": {
|
||||
"poseidon-lite": "^0.2.0",
|
||||
"rlnjs": "^3.1.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^25.0.2",
|
||||
"@rollup/plugin-json": "^6.0.0",
|
||||
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||
"@rollup/plugin-replace": "^5.0.2",
|
||||
"@types/jest": "^29.2.4",
|
||||
"@typescript-eslint/eslint-plugin": "^5.50.0",
|
||||
"@typescript-eslint/parser": "^5.51.0",
|
||||
"eslint": "^8.33.0",
|
||||
"eslint-config-airbnb-base": "^15.0.0",
|
||||
"eslint-config-airbnb-typescript": "^17.0.0",
|
||||
"eslint-import-resolver-typescript": "^3.5.3",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"jest": "^29.5.0",
|
||||
"prettier": "^3.0.0",
|
||||
"rollup": "^3.14.0",
|
||||
"rollup-plugin-cleaner": "^1.0.0",
|
||||
"rollup-plugin-polyfill-node": "^0.12.0",
|
||||
"rollup-plugin-typescript2": "^0.35.0",
|
||||
"rollup-plugin-visualizer": "^5.9.0",
|
||||
"ts-jest": "^29.0.3",
|
||||
"tslib": "^2.5.0",
|
||||
"typescript": "^5.1.6"
|
||||
}
|
||||
}
|
||||
93
rollup.config.mjs
Normal file
93
rollup.config.mjs
Normal file
@@ -0,0 +1,93 @@
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
import typescript from 'rollup-plugin-typescript2'
|
||||
import { nodeResolve } from '@rollup/plugin-node-resolve'
|
||||
import commonjs from '@rollup/plugin-commonjs'
|
||||
import json from '@rollup/plugin-json'
|
||||
import nodePolyfills from 'rollup-plugin-polyfill-node'
|
||||
import replace from '@rollup/plugin-replace'
|
||||
import { visualizer } from 'rollup-plugin-visualizer'
|
||||
import cleaner from 'rollup-plugin-cleaner'
|
||||
import * as fs from 'fs'
|
||||
|
||||
|
||||
const input = 'src/index.ts'
|
||||
const pkg = JSON.parse(fs.readFileSync('./package.json', 'utf-8'))
|
||||
const banner = `/**
|
||||
* @module ${pkg.name}
|
||||
* @version ${pkg.version}
|
||||
* @file ${pkg.description}
|
||||
* @copyright Ethereum Foundation 2022
|
||||
* @license ${pkg.license}
|
||||
* @see [Github]{@link ${pkg.homepage}}
|
||||
*/`
|
||||
|
||||
|
||||
const typescriptPlugin = typescript({
|
||||
tsconfig: 'tsconfig.build.json',
|
||||
useTsconfigDeclarationDir: true,
|
||||
})
|
||||
|
||||
const visualizerPlugin = visualizer({
|
||||
emitFile: true,
|
||||
filename: 'stats.html',
|
||||
template: 'sunburst',
|
||||
})
|
||||
|
||||
const nodePlugins = [
|
||||
typescriptPlugin,
|
||||
// `browser: false` is required for `fs` and other Node.js core modules to be resolved correctly
|
||||
nodeResolve({ browser: false }),
|
||||
// To accept commonjs modules and convert them to ES module, since rollup only bundle ES modules by default
|
||||
commonjs(),
|
||||
// Parse JSON files and make them ES modules. Required when bundling circomlib
|
||||
json(),
|
||||
]
|
||||
|
||||
const browserPlugins = [
|
||||
typescriptPlugin,
|
||||
replace({
|
||||
// Replace `process.browser` with `true` to avoid `process is not defined` error
|
||||
// This is because ffjavascript and snarkjs use `process.browser` to check if it's running in the browser,
|
||||
// but process is undefined in the browser and referencing `process.browser` causes an error.
|
||||
// Ref: https://github.com/iden3/ffjavascript/blob/e670bfeb17e80b961eab77e15a6b9eca8e31a0be/src/threadman.js#L43
|
||||
'process.browser': JSON.stringify(true),
|
||||
// To avoid unexpected behavior that the warning suggests.
|
||||
'preventAssignment': true,
|
||||
}),
|
||||
// Resolve the import from node_modules.
|
||||
// `browser: true` is required for `window` not to be undefined
|
||||
// Ref: https://github.com/iden3/snarkjs/blob/782894ab72b09cfad4dd8b517599d5e7b2340468/src/taskmanager.js#L20-L24
|
||||
nodeResolve({ browser: true }),
|
||||
commonjs(),
|
||||
json(),
|
||||
// Replace node built-in modules with polyfills
|
||||
nodePolyfills(),
|
||||
]
|
||||
|
||||
|
||||
export default [
|
||||
// Node.js build
|
||||
{
|
||||
input,
|
||||
output: { file: pkg.main, format: 'cjs', banner },
|
||||
external: Object.keys(pkg.dependencies),
|
||||
plugins: [
|
||||
cleaner({
|
||||
targets: [
|
||||
'./dist/',
|
||||
],
|
||||
}),
|
||||
...nodePlugins,
|
||||
visualizerPlugin,
|
||||
],
|
||||
},
|
||||
// Browser build
|
||||
{
|
||||
input,
|
||||
output: { file: pkg.module, format: 'es', banner },
|
||||
plugins: [
|
||||
...browserPlugins,
|
||||
visualizerPlugin,
|
||||
],
|
||||
},
|
||||
]
|
||||
115
src/index.ts
Normal file
115
src/index.ts
Normal file
@@ -0,0 +1,115 @@
|
||||
import type { RLNFullProof } from 'rlnjs';
|
||||
export { str2BigInt, genId, randomBigInt } from './utils';
|
||||
export type IdentityCommitmentT = bigint;
|
||||
|
||||
export enum RoomType {
|
||||
PUBLIC = 'public',
|
||||
GATED = 'gated',
|
||||
PRIVATE = 'private',
|
||||
SECURE = 'secure'
|
||||
}
|
||||
|
||||
export interface MembershipI {
|
||||
identityCommitments?: IdentityCommitmentT[];
|
||||
rlnContract?: RLNContractI;
|
||||
}
|
||||
|
||||
export interface RLNContractI {
|
||||
address: string;
|
||||
chainId: number;
|
||||
}
|
||||
|
||||
export interface MessageI {
|
||||
id?: string; // internal nullifier as string
|
||||
room?: RLNFullProof['rlnIdentifier'];
|
||||
message: string;
|
||||
proof?: RLNFullProof;
|
||||
}
|
||||
|
||||
export interface SystemMessageI {
|
||||
timestamp: string; // unix epoch time in ms as string
|
||||
message: string; // plain text message
|
||||
room?: RLNFullProof['rlnIdentifier']; // optionally send it to one room or all rooms
|
||||
}
|
||||
|
||||
export interface RoomI {
|
||||
id: RLNFullProof['rlnIdentifier'] | string; // RLN Identifier
|
||||
name: string; // Readable name
|
||||
rateLimit?: number; // Milliseconds between messages
|
||||
membership?: MembershipI; // List of Identity Commitments, or a contract address for an RLN contract
|
||||
type?: RoomType; // Public or private, if undefinied, assume public
|
||||
messageHandlerSocket?: string; // Port for websocket connections
|
||||
}
|
||||
|
||||
export interface RoomGroupI {
|
||||
name: string;
|
||||
rooms: RoomI[];
|
||||
}
|
||||
|
||||
export interface ServerI {
|
||||
id: bigint;
|
||||
name: string;
|
||||
version?: string;
|
||||
serverInfoEndpoint: string;
|
||||
messageHandlerSocket?: string; // Default port for websocket connections
|
||||
publicMembership?: MembershipI;
|
||||
roomGroups: RoomGroupI[];
|
||||
selectedRoom?: RoomI['id'];
|
||||
}
|
||||
|
||||
export class Server {
|
||||
name: string;
|
||||
version: string | undefined;
|
||||
serverInfoEndpoint: string;
|
||||
messageHandlerSocket: string | undefined;
|
||||
publicMembership: MembershipI | undefined;
|
||||
roomGroups: RoomGroupI[];
|
||||
selectedRoom: string | bigint;
|
||||
constructor(public server: ServerI) {
|
||||
this.name = server.name;
|
||||
this.version = server.version;
|
||||
this.serverInfoEndpoint = server.serverInfoEndpoint;
|
||||
this.messageHandlerSocket = server.messageHandlerSocket;
|
||||
this.publicMembership = server.publicMembership;
|
||||
this.roomGroups = server.roomGroups;
|
||||
this.selectedRoom = server.selectedRoom
|
||||
? server.selectedRoom
|
||||
: server.roomGroups[0].rooms[0].id;
|
||||
}
|
||||
|
||||
getRoomById(id: string | bigint): RoomI | undefined {
|
||||
return this.roomGroups
|
||||
.map((group) => group.rooms)
|
||||
.flat()
|
||||
.find((room) => room.id === id);
|
||||
}
|
||||
|
||||
getRoomByName(name: string): RoomI | undefined {
|
||||
return this.roomGroups
|
||||
.map((group) => group.rooms)
|
||||
.flat()
|
||||
.find((room) => room.name === name);
|
||||
}
|
||||
|
||||
getRoomGroupByName(name: string): RoomGroupI | undefined {
|
||||
return this.roomGroups.find((group) => group.name === name);
|
||||
}
|
||||
|
||||
setRoomById(id: string | bigint) {
|
||||
if (this.getRoomById(id)) {
|
||||
this.selectedRoom = id;
|
||||
return id;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
getRoomHandlerSocket(id: string | bigint): string | undefined {
|
||||
const room = this.getRoomById(id);
|
||||
if (room) {
|
||||
return room.messageHandlerSocket;
|
||||
} else {
|
||||
return this.messageHandlerSocket;
|
||||
}
|
||||
}
|
||||
}
|
||||
25
src/utils.ts
Normal file
25
src/utils.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { poseidon2 } from 'poseidon-lite/poseidon2';
|
||||
|
||||
export function str2BigInt(str: string) {
|
||||
let num = '';
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
num += str.charCodeAt(i).toString();
|
||||
}
|
||||
return BigInt(num);
|
||||
}
|
||||
|
||||
export function genId(serverID: bigint, roomName: string | bigint | number) {
|
||||
if (typeof roomName === 'string') {
|
||||
return poseidon2([serverID, str2BigInt(roomName)]);
|
||||
}
|
||||
return poseidon2([serverID, BigInt(roomName)]);
|
||||
}
|
||||
|
||||
export function randomBigInt(bits: number = 253) {
|
||||
let hexBits = bits / 4;
|
||||
let hexString = '';
|
||||
for (let i = 0; i < hexBits; i++) {
|
||||
hexString += Math.floor(Math.random() * 16).toString(16);
|
||||
}
|
||||
return BigInt('0x' + hexString);
|
||||
}
|
||||
8
tsconfig.build.json
Normal file
8
tsconfig.build.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"rootDir": "./src",
|
||||
"outDir": "./dist",
|
||||
"files": [
|
||||
"src/index.ts",
|
||||
]
|
||||
}
|
||||
21
tsconfig.json
Normal file
21
tsconfig.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist",
|
||||
"target": "ES5",
|
||||
"module": "ES6",
|
||||
"moduleResolution": "node",
|
||||
"allowJs": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"noUnusedParameters": true,
|
||||
"noImplicitAny": false,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noEmitOnError": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"sourceMap": true,
|
||||
"esModuleInterop": true,
|
||||
},
|
||||
"files": [
|
||||
"./src/index.ts"
|
||||
]
|
||||
}
|
||||
12
tsconfig.test.json
Normal file
12
tsconfig.test.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
"noImplicitAny": false,
|
||||
"noImplicitReturns": false,
|
||||
"noEmitOnError": false,
|
||||
"include": [
|
||||
"tests"
|
||||
],
|
||||
"exclude": []
|
||||
}
|
||||
Reference in New Issue
Block a user