1import * as bip39 from 'bip39';
2import * as ob from 'urbit-ob';
3import { identity, includes } from 'lodash';
5import { isValidAddress, ETH_ZERO_ADDR, ETH_ZERO_ADDR_SHORT } from './wallet';
6import patp2dec from './patp2dec';
7import { patpStringLength } from './lib';
9// NOTE: do not use the /g modifier for these regexes
10// https://stackoverflow.com/a/21373261
11// https://stackoverflow.com/a/1520853
13// via: https://emailregex.com/
14const 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,}))$/;
16// is this 64 hex chars?
17const plain64CharHexValue = /[0-9A-Fa-f]{64}/;
19// is this only hex values with a 0x prefix?
20const isHexString = /0x[0-9A-Fa-f]/;
22// Wraps single validation functions in a controlled and predictable way.
23export const simpleValidatorWrapper = ({
29 // If a previous validation has already failed, skip this validation and
30 // return the prev message to the next stage in the validation function chain.
31 // Failed validations should drop all the way down the chain and drop out of
33 if (!prevMessage.pass) {
37 // Run the validator and return the result.
38 const pass = validator(prevMessage.data);
39 const data = pass ? transform(prevMessage.data) : prevMessage.data;
41 return newMessage(data, pass, !pass && error);
50// Creates a new validation message in a uniform way.
51const newMessage = (data, pass, error) => ({
54 // Has the data passed validation?
56 // If data has failed a validator, the error message goes here.
60// A validator that always passes.
61export const kDefaultValidator = data => newMessage(data, true, null);
63// Validates a bip39 mnemonic
64export const validateMnemonic = m =>
65 simpleValidatorWrapper({
67 validator: d => bip39.validateMnemonic(d),
68 error: 'This is not a valid mnemonic.',
71// Checks an empty field
72export const validateNotEmpty = m =>
73 simpleValidatorWrapper({
82 error: 'This field is required.',
85// Checks if a patp is a valid galaxy
86export const validateGalaxy = m =>
87 simpleValidatorWrapper({
93 return point >= 0 && point < 256;
98 error: 'This is not a valid galaxy',
101export const validatePoint = m =>
102 simpleValidatorWrapper({
106 return ob.isValidPatp(d);
111 error: 'This is not a valid point',
114export const validateTicket = m =>
115 simpleValidatorWrapper({
119 return ob.isValidPatq(d);
124 error: 'This is not a valid ticket',
127export const validateShard = m =>
128 simpleValidatorWrapper({
132 return ob.isValidPatq(d);
137 error: 'This is not a valid shard',
140export const validateOneOf = (options = []) => m =>
141 simpleValidatorWrapper({
143 validator: d => includes(options, d),
144 error: `Is not a valid option.`,
147export const validateHexString = m =>
148 simpleValidatorWrapper({
150 validator: d => isHexString.test(d),
151 error: 'This is not a valid hex string',
155export const validateNetworkKey = m =>
156 simpleValidatorWrapper({
158 validator: d => plain64CharHexValue.test(d),
159 error: 'This is not a valid network key',
163export const validateNetworkSeed = m =>
164 simpleValidatorWrapper({
166 validator: d => plain64CharHexValue.test(d),
167 error: 'This is not a valid network seed',
170// Checks if a string is a valid ethereum address
171export const validateEthereumAddress = m =>
172 simpleValidatorWrapper({
174 validator: d => isValidAddress(d),
175 error: 'This is not a valid Ethereum address',
178export const validateEmail = m =>
179 simpleValidatorWrapper({
181 validator: d => emailRegExp.test(d),
182 error: 'This is not a valid email address',
185export const validateInt = m =>
186 simpleValidatorWrapper({
188 transform: d => parseInt(d, 10),
197 error: 'This is not a valid number',
200export const validateExactly = (value, error) => m =>
201 simpleValidatorWrapper({
203 validator: d => d === value,
207export const validateNotEqual = (values = []) => m =>
208 simpleValidatorWrapper({
210 validator: d => !values.includes(d),
211 error: `Cannot be ${m.data}`,
214export const validateLength = l => m =>
215 simpleValidatorWrapper({
219 return d.length === l;
224 error: `Must be exactly ${l} characters`,
227export const validateMaximumLength = l => m =>
228 simpleValidatorWrapper({
232 return d.length <= l;
237 error: `Must be ${l} characters or fewer.`,
240export const validatePatpByteLength = byteLength => {
241 return validateLength(patpStringLength(byteLength));
244export const validateMaximumPatpByteLength = byteLength => {
245 return validateMaximumLength(patpStringLength(byteLength));
248export const validateNotNullAddress = validateNotEqual(
249 [ETH_ZERO_ADDR, ETH_ZERO_ADDR_SHORT],
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