on ded612b help sign in
bridge/src/lib/validators.ts
148 lines 4.2 kB history raw
1import * as bip39 from 'bip39';
2import * as bitcoin from 'bitcoinjs-lib';
3import ob from 'urbit-ob';
4import { includes } from 'lodash';
6import { isValidAddress } from './utils/address';
7import { patp2dec } from './patp2dec';
8import { patpStringLength } from './lib';
9import {
10 ETH_ZERO_ADDR,
11 ETH_ZERO_ADDR_SHORT,
12 MIN_GALAXY,
13 MAX_GALAXY,
14} from './constants';
16// NOTE: do not use the /g modifier for these regexes
17// https://stackoverflow.com/a/21373261
18// https://stackoverflow.com/a/1520853
20// via: https://emailregex.com/
21const emailRegExp = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
23// validate only strings that use hex characters
24const isHexString = /[0-9A-Fa-f]/;
26// validate only strings that are prefixed with 0x
27const isHexPrefixed = /^0x/;
29// Validates a bip39 mnemonic
30export const validateMnemonic = v =>
31 !bip39.validateMnemonic(v) && 'This is not a valid mnemonic.';
33const isHdPath = /^m(\/[0-9]+'?)*$/;
34export const validateHdPath = v =>
35 !isHdPath.test(v) && 'Invalid HD derivation path.';
37// Checks an empty field
38export const validateNotEmpty = v =>
39 (v === undefined || v.length === 0) && 'This field is required.';
41// Checks if a patp is a valid galaxy
42export const validateGalaxy = v => {
43 try {
44 const point = patp2dec(v);
45 const isValidGalaxy = point >= MIN_GALAXY && point <= MAX_GALAXY;
46 if (!isValidGalaxy) {
47 throw new Error();
48 }
49 } catch {
50 return 'This is not a valid galaxy.';
51 }
52};
54export const validatePoint = v => {
55 try {
56 if (!ob.isValidPatp(v)) {
57 throw new Error();
58 }
59 } catch {
60 return 'This is not a valid point.';
61 }
62};
64export const validatePatq = v => {
65 try {
66 if (!ob.isValidPatq(v)) {
67 throw new Error();
68 }
69 } catch {
70 return 'This is not a valid ticket.';
71 }
72};
74export const validateShard = v => {
75 try {
76 if (v !== undefined && v !== '' && !ob.isValidPatq(v)) {
77 throw new Error();
78 }
79 } catch {
80 return 'This is not a valid shard.';
81 }
82};
84export const validateOneOf = (options = []) => v =>
85 !includes(options, v) && 'Is not a valid option.';
87export const validateHexString = v =>
88 !isHexString.test(v) && 'This is not a valid hex string.';
90export const validateHexPrefix = v =>
91 !isHexPrefixed.test(v) && 'Must include 0x prefix.';
93export const validateEthereumAddress = v =>
94 !isValidAddress(v) && 'This is not a valid Ethereum address.';
96export const validateEmail = v =>
97 !emailRegExp.test(v) && 'This is not a valid email address.';
99export const validateExactly = (value, error) => v => v !== value && error;
101export const validateNotAny = (values = []) => v =>
102 values.includes(v) && `Cannot be ${v}.`;
104export const validateLength = l => v =>
105 v.length !== l && `Must be exactly ${l} characters.`;
107export const validateHexLength = l => v =>
108 v.length !== l + 2 && `Must be exactly ${l} hex characters.`;
110export const validateMaximumLength = l => v =>
111 v.length > l && `Must be ${l} characters or fewer.`;
113export const validateMinimumLength = l => v =>
114 v.length < l && `Must be ${l} characters or more.`;
116export const validateGreaterThan = l => v =>
117 !(v > l) && `Must be greater than ${l}.`;
119export const validateLessThan = l => v => !(v < l) && `Must be less than ${l}`;
121export const validateInSet = (set, error) => v => !set.has(v) && error;
123export const validateMaximumPatpByteLength = byteLength =>
124 validateMaximumLength(patpStringLength(byteLength));
126export const validateMinimumPatpByteLength = byteLength =>
127 validateMinimumLength(patpStringLength(byteLength));
129export const validateNotNullAddress = validateNotAny([
130 ETH_ZERO_ADDR,
131 ETH_ZERO_ADDR_SHORT,
132]);
134export const validateUnique = arr => {
135 const res = [...new Set(arr)].length !== arr.length && 'Must be unique';
136 return res;
137};
139export const validateChild = ourShip => ship =>
140 ourShip !== ob.sein(ship) && `This point is not a child of ${ourShip}.`;
142export const validatePsbt = base64 => {
143 try {
144 bitcoin.Psbt.fromBase64(base64);
145 } catch (e) {
146 return 'Invalid Partially Signed Bitcoin Transaction';
147 }
148};