on 0ad03e1 help sign in
bridge/src/lib/validators.js
141 lines 3.6 kB history raw
1import * as bip39 from 'bip39';
2import * as ob from 'urbit-ob';
4import { isValidAddress } from './wallet';
6const hexRegExp = /[0-9A-Fa-f]{64}/g;
8// Wraps single validation functions in a controlled and predictable way.
9export const simpleValidatorWrapper = config => {
10 // If a previous validation has already failed, skip this validation and
11 // return the prev message to the next stage in the validation function chain.
12 // Failed validations should drop all the way down the chain and drop out of
13 // the output.
14 if (!config.prevMessage.pass) {
15 return config.prevMessage;
16 }
18 // Run the validator and return the result.
19 return config.validator(config.prevMessage.data)
20 ? newMessage(config.prevMessage.data, true, null)
21 : newMessage(config.prevMessage.data, false, config.errorMessage);
22};
24// Validation message
25// {
26// data: ...
27// pass: ...
28// error: ...
29// }
30// Creates a new validation message in a uniform way.
31const newMessage = (data, pass, error) => ({
32 // The input data
33 data,
34 // Has the data passed validation?
35 pass,
36 // If data has failed a validator, the error message goes here.
37 error,
38});
40// A validator that always passes.
41export const kDefaultValidator = data => newMessage(data, true, null);
43// Validates a bip39 mnemonic
44export const validateMnemonic = m =>
45 simpleValidatorWrapper({
46 prevMessage: m,
47 validator: d => bip39.validateMnemonic(d),
48 errorMessage: 'This is not a valid mnemonic.',
49 });
51// Checks an empty field
52export const validateNotEmpty = m =>
53 simpleValidatorWrapper({
54 prevMessage: m,
55 validator: d => d.length > 1,
56 errorMessage: 'This field is required.',
57 });
59// Checks if a patp is a valid galaxy
60export const validateGalaxy = m =>
61 simpleValidatorWrapper({
62 prevMessage: m,
63 validator: d => {
64 let point;
65 try {
66 point = parseInt(ob.patp2dec(d), 10);
67 return point >= 0 && point < 256;
68 } catch (e) {
69 return false;
70 }
71 },
72 errorMessage: 'This is not a valid galaxy',
73 });
75export const validatePoint = m =>
76 simpleValidatorWrapper({
77 prevMessage: m,
78 validator: d => {
79 try {
80 return ob.isValidPatp(d);
81 } catch (e) {
82 return false;
83 }
84 },
85 errorMessage: 'This is not a valid point',
86 });
88export const validateTicket = m =>
89 simpleValidatorWrapper({
90 prevMessage: m,
91 validator: d => {
92 try {
93 return ob.isValidPatq(d);
94 } catch (e) {
95 return false;
96 }
97 },
98 errorMessage: 'This is not a valid ticket',
99 });
101export const validateShard = m =>
102 simpleValidatorWrapper({
103 prevMessage: m,
104 validator: d => {
105 try {
106 return ob.isValidPatq(d);
107 } catch (e) {
108 return false;
109 }
110 },
111 errorMessage: 'This is not a valid shard',
112 });
114export const validateLength = (m, l) =>
115 simpleValidatorWrapper({
116 prevMessage: m,
117 validator: d => d.length === l,
118 errorMessage: 'This is of an invalid length',
119 });
121export const validateNetworkKey = m =>
122 simpleValidatorWrapper({
123 prevMessage: m,
124 validator: d => hexRegExp.test(d),
125 errorMessage: 'This is not a valid network key',
126 });
128export const validateNetworkSeed = m =>
129 simpleValidatorWrapper({
130 prevMessage: m,
131 validator: d => hexRegExp.test(d),
132 errorMessage: 'This is not a valid network seed',
133 });
135// Checks if a string is a valid ethereum address
136export const validateEthereumAddress = m =>
137 simpleValidatorWrapper({
138 prevMessage: m,
139 validator: d => isValidAddress(d),
140 errorMessage: 'This is not a valid Ethereum address',
141 });