Skip to content

Instantly share code, notes, and snippets.

View morloy's full-sized avatar

Timo Horstschaefer morloy

View GitHub Profile
@morloy
morloy / cap-table.md
Last active January 31, 2019 15:41
Frontend Challenge: Cap Table

Frontend Challenge: Cap Table

Every company is divided into shares. Shares are issued to shareholders. Founders usually get them for free, whereas investors need to pay for each share. Aggregating all shares of a shareholder, we get the cap table: a list of all shareholders and the percentage they own in the company.

The goal of this challenge is to build a simple cap table management app.

First, we need to define a shareholder. For this, we use Flow to define a basic JavaScript object:

type Shareholder = {|
 _id: string
@morloy
morloy / ledgy-web-dev.md
Last active December 28, 2018 17:35 — forked from bbinoy/ledgy-web-dev.md
Web Developer Wanted

Web Developer Wanted!

We are Ledgy, an 18-month-old SaaS startup from Zurich, looking for a Web Developer to grow our team.

Ledgy is a SaaS tool to manage the equity of private companies. It helps to democratize ownership in startups by assisting founders to grant equity to their employees. We’ve also developed a first concept to bring shares of startups on the Ethereum blockchain.

Our customers are successful companies from Switzerland and other European countries, like VIU, Farmy, or the Crypto Finance AG.

As a full-stack Web Developer at Ledgy, you can

  • Crunch financial data in isomorphic JavaScript (Browser & Node.js)
@morloy
morloy / helpers.js
Last active September 12, 2018 17:45
const hexToBytes = (hex: string): Array<number> => {
const bytes = [];
for (let c = 0; c < hex.length; c += 2) {
bytes.push(parseInt(hex.substr(c, 2), 16));
}
return bytes;
};
export const SHA256 = async (doc: ArrayBuffer): Promise<string> => (
crypto ?
import OTS from 'javascript-opentimestamps';
import { SHA256, getOtsFromCertificate, decodeOts } from './helpers.js';
const publicKey = Buffer.from('fTrOd0HG8opCEgb+dXvNUXQmzPQqyMGC/IQinDJof1g=', 'base64');
const verifyDocumentOnBlockchain = async (certificate: string, ots: string, docUrl: string) => {
const verifiedCertificate = sign.open(Buffer.from(certificate, 'base64'), publickKey);
if (!verifiedCertificate) {
throw new Error('WARNING: Certificate is invalid');
}
import OTS from 'javascript-opentimestamps';
import { getOtsFromCertificate, encodeOts } from './helpers.js';
export const stampCertificate = async (certificate: string): Promise<string> => {
const ots = getOtsFromCertificate(certificate);
await OTS.stamp(ots);
return encodeOts(ots);
};
import { sign } from 'tweetnacl';
import { Buffer } from 'buffer';
const secretKey = Buffer.from('…', 'base64');
const generateCertificateForDocument =
(filename: string, sha256: string, user: string, email: string, userId: string, companyId: string, createdByLedgy: boolean): string => {
const certificate = JSON.stringify({
filename, sha256, user, email, company, createdByLedgy, userId, companyId, version: '1.0.0',
});
import { Accounts } from 'meteor/accounts-base';
class LoginForm extends React.Component {
state = {
email: '',
password: '',
token: '',
requiresTwoFactor: false,
loading: false,
};
// /imports/api/methods/twoFactorAuth.js
import SimpleSchema from 'simpl-schema';
export const TwoFactorToken = {
type: SimpleSchema.Integer, min: 0, max: 999999, optional: true,
};
export const tokenIsValid = (token: string, secret: string) => {
if (!otplib.authenticator.check(token, secret)) {
// /imports/api/methods/twoFactorAuth.js
import { Meteor } from 'meteor/meteor';
import { ValidatedMethod } from 'meteor/mdg:validated-method';
import otplib from 'otplib';
const userIsLoggedIn = (userId: string) => {
if (!userId) {
throw new Meteor.Error('users.not-authorized');
}
// /imports/startup/server/twoFactorAuthServer.js
import { Meteor } from 'meteor/meteor';
import { Accounts } from 'meteor/accounts-base';
import SimpleSchema from 'simpl-schema';
import otplib from 'otplib';
import { TwoFactorToken } from '/imports/api/methods/twoFactorAuth';
// Invalidate password login attempt, if 2FA is enabled