diff --git a/frontend/client/components/CreateFlow/Payment.tsx b/frontend/client/components/CreateFlow/Payment.tsx index 34659ca0..8c91eed2 100644 --- a/frontend/client/components/CreateFlow/Payment.tsx +++ b/frontend/client/components/CreateFlow/Payment.tsx @@ -29,18 +29,22 @@ export default class CreateFlowPayment extends React.Component { render() { const { payoutAddress, deadlineDuration } = this.state; const errors = getCreateErrors(this.state, true); + const payoutHelp = errors.payoutAddress || ` + This must be a Sapling Z address + `; return (
{ }, { step: CREATE_STEP.PAYMENT, - name: 'Governance', + name: 'Payment', fields: [ { key: 'payoutAddress', diff --git a/frontend/client/components/CreateFlow/example.ts b/frontend/client/components/CreateFlow/example.ts index 31e4a6ae..5c9237a9 100644 --- a/frontend/client/components/CreateFlow/example.ts +++ b/frontend/client/components/CreateFlow/example.ts @@ -14,7 +14,7 @@ const createExampleProposal = (): Partial => { target: '5', // Testnet address, assumes you wouldn't use this in production payoutAddress: - 'ztfFV7AqJqBm1EcWvP3oktZUMnp91ygfduE6ZQqGWENM1CpRKJLMZp2kgChnJVc6CbKSZ4mS37iNaiDwcatxjZcfoi2g7E8', + 'ztestsapling12uyydevkh2gsnnrzuhzz4taw3v544jrpa3v6t7zv4ae45dquau7cfw26u3uzt520m08cs3jxqqs', milestones: [ { title: 'Initial Funding', diff --git a/frontend/client/modules/create/utils.ts b/frontend/client/modules/create/utils.ts index 63938fc6..0c41fddc 100644 --- a/frontend/client/modules/create/utils.ts +++ b/frontend/client/modules/create/utils.ts @@ -6,7 +6,7 @@ import { PROPOSAL_ARBITER_STATUS, } from 'types'; import { User } from 'types'; -import { getAmountError, isValidAddress } from 'utils/validators'; +import { getAmountError, isValidSaplingAddress, isValidTAddress, isValidSproutAddress } from 'utils/validators'; import { Zat, toZat } from 'utils/units'; import { ONE_DAY } from 'utils/time'; import { PROPOSAL_CATEGORY, PROPOSAL_STAGE } from 'api/constants'; @@ -90,8 +90,14 @@ export function getCreateErrors( } // Payout address - if (payoutAddress && !isValidAddress(payoutAddress)) { - errors.payoutAddress = 'That doesn’t look like a valid zcash address'; + if (payoutAddress && !isValidSaplingAddress(payoutAddress)) { + if (isValidSproutAddress(payoutAddress)) { + errors.payoutAddress = 'Must be a Sapling address, not a Sprout address'; + } else if (isValidTAddress(payoutAddress)) { + errors.payoutAddress = 'Must be a Sapling Z address, not a T address'; + } else { + errors.payoutAddress = 'That doesn’t look like a valid Sapling address'; + } } // Milestones diff --git a/frontend/client/utils/constants.ts b/frontend/client/utils/constants.ts index 64316b00..e5271f27 100644 --- a/frontend/client/utils/constants.ts +++ b/frontend/client/utils/constants.ts @@ -1,4 +1,5 @@ export const DONATION = { ZCASH_TRANSPARENT: 't1aib2cbwPVrFfrjGGkhWD67imdBet1xDTr', ZCASH_SPROUT: 'zcWGwZU7FyUgpdrWGkeFqCEnvhLRDAVuf2ZbhW4vzNMTTR6VUgfiBGkiNbkC4e38QaPtS13RKZCriqN9VcyyKNRRQxbgnen', + ZCASH_SAPLING: 'zs15el0hzs4w60ggfy6kq4p3zttjrl00mfq7yxfwsjqpz9d7hptdtkltzlcqar994jg2ju3j9k85zk', }; diff --git a/frontend/client/utils/validators.ts b/frontend/client/utils/validators.ts index d0ebe46e..b7cc434f 100644 --- a/frontend/client/utils/validators.ts +++ b/frontend/client/utils/validators.ts @@ -17,19 +17,29 @@ export function isValidEmail(email: string): boolean { return /\S+@\S+\.\S+/.test(email); } + // Uses simple regex to validate addresses, doesn't check checksum or network -export function isValidAddress(address: string): boolean { - // T address +export function isValidTAddress(address: string): boolean { if (/^t[a-zA-Z0-9]{34}$/.test(address)) { return true; } - // Sprout address + return false; +} + +export function isValidSproutAddress(address: string): boolean { if (/^z[a-zA-Z0-9]{94}$/.test(address)) { return true; } - // Sapling address + return false; +} + +export function isValidSaplingAddress(address: string): boolean { if (/^z(s)?(reg)?(testsapling)?[a-zA-Z0-9]{76}$/.test(address)) { return true; } return false; } + +export function isValidAddress(a: string): boolean { + return isValidTAddress(a) || isValidSproutAddress(a) || isValidSaplingAddress(a); +}