1import * as bip39 from 'bip39';
2import * as ob from 'urbit-ob';
3import { identity } from 'lodash';
5import { isValidAddress } from './wallet';
6import patp2dec from './patp2dec';
8// NOTE: do not use the /g modifier for these regexes
9// https://stackoverflow.com/a/21373261
10// https://stackoverflow.com/a/1520853
12// via: https://emailregex.com/
13const 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,}))$/;
15// is this 64 hex chars?
16const plain64CharHexValue = /[0-9A-Fa-f]{64}/;
18// is this only hex values with a 0x prefix?
19const isHexString = /0x[0-9A-Fa-f]/;
21// Wraps single validation functions in a controlled and predictable way.
22export const simpleValidatorWrapper = ({
28 // If a previous validation has already failed, skip this validation and
29 // return the prev message to the next stage in the validation function chain.
30 // Failed validations should drop all the way down the chain and drop out of
32 if (!prevMessage.pass) {
36 // Run the validator and return the result.
37 const pass = validator(prevMessage.data);
38 const data = pass ? transform(prevMessage.data) : prevMessage.data;
40 return newMessage(data, pass, !pass && error);
49// Creates a new validation message in a uniform way.
50const newMessage = (data, pass, error) => ({
53 // Has the data passed validation?
55 // If data has failed a validator, the error message goes here.
59// A validator that always passes.
60export const kDefaultValidator = data => newMessage(data, true, null);
62// Validates a bip39 mnemonic
63export const validateMnemonic = m =>
64 simpleValidatorWrapper({
66 validator: d => bip39.validateMnemonic(d),
67 error: 'This is not a valid mnemonic.',
70// Checks an empty field
71export const validateNotEmpty = m =>
72 simpleValidatorWrapper({
81 error: 'This field is required.',
84// Checks if a patp is a valid galaxy
85export const validateGalaxy = m =>
86 simpleValidatorWrapper({
92 return point >= 0 && point < 256;
97 error: 'This is not a valid galaxy',
100export const validatePoint = m =>
101 simpleValidatorWrapper({
105 return ob.isValidPatp(d);
110 error: 'This is not a valid point',
113export const validateTicket = m =>
114 simpleValidatorWrapper({
118 return ob.isValidPatq(d);
123 error: 'This is not a valid ticket',
126export const validateShard = m =>
127 simpleValidatorWrapper({
131 return ob.isValidPatq(d);
136 error: 'This is not a valid shard',
139export const validateLength = l => m =>
140 simpleValidatorWrapper({
144 return d.length === l;
149 error: `Must be exactly ${l} characters`,
152export const validateHexString = m =>
153 simpleValidatorWrapper({
155 validator: d => isHexString.test(d),
156 error: 'This is not a valid hex string',
160export const validateNetworkKey = m =>
161 simpleValidatorWrapper({
163 validator: d => plain64CharHexValue.test(d),
164 error: 'This is not a valid network key',
168export const validateNetworkSeed = m =>
169 simpleValidatorWrapper({
171 validator: d => plain64CharHexValue.test(d),
172 error: 'This is not a valid network seed',
175// Checks if a string is a valid ethereum address
176export const validateEthereumAddress = m =>
177 simpleValidatorWrapper({
179 validator: d => isValidAddress(d),
180 error: 'This is not a valid Ethereum address',
183export const validateEmail = m =>
184 simpleValidatorWrapper({
186 validator: d => emailRegExp.test(d),
187 error: 'This is not a valid email address',
190export const validateInt = m =>
191 simpleValidatorWrapper({
193 transform: d => parseInt(d, 10),
202 error: 'This is not a valid number',
205export const validateExactly = (value, error) => m =>
206 simpleValidatorWrapper({
208 validator: d => d === value,
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list