on 2fe8586 help sign in
bridge/src/lib/validators.js
143 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, ETH_ZERO_ADDR, ETH_ZERO_ADDR_SHORT } from './wallet';
7import patp2dec from './patp2dec';
8import { patpStringLength } from './lib';
9import { MIN_GALAXY, MAX_GALAXY } from './constants';
11// NOTE: do not use the /g modifier for these regexes
12// https://stackoverflow.com/a/21373261
13// https://stackoverflow.com/a/1520853
15// via: https://emailregex.com/
16const 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,}))$/;
18// validate only strings that use hex characters
19const isHexString = /[0-9A-Fa-f]/;
21// validate only strings that are prefixed with 0x
22const isHexPrefixed = /^0x/;
24// Validates a bip39 mnemonic
25export const validateMnemonic = v =>
26 !bip39.validateMnemonic(v) && 'This is not a valid mnemonic.';
28const isHdPath = /^m(\/[0-9]+'?)*$/;
29export const validateHdPath = v =>
30 !isHdPath.test(v) && 'Invalid HD derivation path.';
32// Checks an empty field
33export const validateNotEmpty = v =>
34 (v === undefined || v.length === 0) && 'This field is required.';
36// Checks if a patp is a valid galaxy
37export const validateGalaxy = v => {
38 try {
39 const point = patp2dec(v);
40 const isValidGalaxy = point >= MIN_GALAXY && point <= MAX_GALAXY;
41 if (!isValidGalaxy) {
42 throw new Error();
43 }
44 } catch {
45 return 'This is not a valid galaxy.';
46 }
47};
49export const validatePoint = v => {
50 try {
51 if (!ob.isValidPatp(v)) {
52 throw new Error();
53 }
54 } catch {
55 return 'This is not a valid point.';
56 }
57};
59export const validatePatq = v => {
60 try {
61 if (!ob.isValidPatq(v)) {
62 throw new Error();
63 }
64 } catch {
65 return 'This is not a valid ticket.';
66 }
67};
69export const validateShard = v => {
70 try {
71 if (v !== undefined && v !== '' && !ob.isValidPatq(v)) {
72 throw new Error();
73 }
74 } catch {
75 return 'This is not a valid shard.';
76 }
77};
79export const validateOneOf = (options = []) => v =>
80 !includes(options, v) && 'Is not a valid option.';
82export const validateHexString = v =>
83 !isHexString.test(v) && 'This is not a valid hex string.';
85export const validateHexPrefix = v =>
86 !isHexPrefixed.test(v) && 'Must include 0x prefix.';
88export const validateEthereumAddress = v =>
89 !isValidAddress(v) && 'This is not a valid Ethereum address.';
91export const validateEmail = v =>
92 !emailRegExp.test(v) && 'This is not a valid email address.';
94export const validateExactly = (value, error) => v => v !== value && error;
96export const validateNotAny = (values = []) => v =>
97 values.includes(v) && `Cannot be ${v}.`;
99export const validateLength = l => v =>
100 v.length !== l && `Must be exactly ${l} characters.`;
102export const validateHexLength = l => v =>
103 v.length !== l + 2 && `Must be exactly ${l} hex characters.`;
105export const validateMaximumLength = l => v =>
106 v.length > l && `Must be ${l} characters or fewer.`;
108export const validateMinimumLength = l => v =>
109 v.length < l && `Must be ${l} characters or more.`;
111export const validateGreaterThan = l => v =>
112 !(v > l) && `Must be greater than ${l}.`;
114export const validateLessThan = l => v => !(v < l) && `Must be less than ${l}`;
116export const validateInSet = (set, error) => v => !set.has(v) && error;
118export const validateMaximumPatpByteLength = byteLength =>
119 validateMaximumLength(patpStringLength(byteLength));
121export const validateMinimumPatpByteLength = byteLength =>
122 validateMinimumLength(patpStringLength(byteLength));
124export const validateNotNullAddress = validateNotAny([
125 ETH_ZERO_ADDR,
126 ETH_ZERO_ADDR_SHORT,
127]);
129export const validateUnique = arr => {
130 const res = [...new Set(arr)].length !== arr.length && 'Must be unique';
131 return res;
132};
134export const validateChild = ourShip => ship =>
135 ourShip !== ob.sein(ship) && `This point is not a child of ${ourShip}.`;
137export const validatePsbt = base64 => {
138 try {
139 bitcoin.Psbt.fromBase64(base64);
140 } catch (e) {
141 return 'Invalid Partially Signed Bitcoin Transaction';
142 }
143};