Skip to content

Commit 2026921

Browse files
committed
feat: verify address according to chain type
1 parent a7b463b commit 2026921

9 files changed

Lines changed: 55 additions & 8 deletions

File tree

packages/neuron-ui/src/components/Send/hooks.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,11 +201,17 @@ export const useInitialize = (
201201
clear(dispatch)
202202
}, [walletID, dispatch])
203203

204-
const onGetAddressErrorMessage = useCallback(
205-
(addr: string) => {
204+
const onGetAddressErrorMessage: (isMainnet: boolean) => (addr: string) => string = useCallback(
205+
(isMainnet: boolean) => (addr: string) => {
206206
if (addr === '') {
207207
return t(`messages.codes.${ErrorCode.AddressIsEmpty}`)
208208
}
209+
if (isMainnet && !addr.startsWith('ckb')) {
210+
return t(`messages.mainnet-address-required`)
211+
}
212+
if (!isMainnet && !addr.startsWith('ckt')) {
213+
return t(`messages.testnet-address-required`)
214+
}
209215
if (!verifyAddress(addr)) {
210216
return t(`messages.codes.${ErrorCode.FieldInvalid}`, {
211217
fieldName: 'address',

packages/neuron-ui/src/components/Send/index.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ const Send = ({
3838
loadings: { sending = false },
3939
},
4040
wallet: { id: walletID = '', balance = '' },
41-
chain: { connectionStatus },
41+
chain: { networkID, connectionStatus },
42+
settings: { networks = [] },
4243
dispatch,
4344
}: React.PropsWithoutRef<StateWithDispatch & RouteComponentProps<{ address: string }>>) => {
4445
const { t } = useTranslation()
@@ -66,6 +67,8 @@ const Send = ({
6667
const errorMessageUnderTotal = verifyTotalAmount(totalAmount, fee, balance)
6768
? errorMessage
6869
: t(`messages.codes.${ErrorCode.AmountNotEnough}`)
70+
const network = networks.find(n => n.id === networkID)
71+
const isMainnet = (network && network.chain === 'ckb') || false // TODO: shoudl be replaced after the mainnet tag is introduced
6972

7073
return (
7174
<Stack verticalFill tokens={{ childrenGap: 15, padding: '20px 0 0 0' }}>
@@ -97,7 +100,7 @@ const Send = ({
97100
onChange={onItemChange}
98101
required
99102
validateOnLoad={false}
100-
onGetErrorMessage={onGetAddressErrorMessage}
103+
onGetErrorMessage={onGetAddressErrorMessage(isMainnet)}
101104
/>
102105
</Stack.Item>
103106
<Stack styles={{ root: { width: '48px' } }} verticalAlign="start">

packages/neuron-ui/src/locales/en.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,8 @@
273273
"keystore-password": "Password",
274274
"deposit": "Deposit"
275275
},
276+
"mainnet-address-required": "Please enter a mainnet address",
277+
"testnet-address-required": "Please enter a testnet address",
276278
"codes": {
277279
"-3": "",
278280
"100": "Amount is not enough",

packages/neuron-ui/src/locales/zh.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,8 @@
273273
"keystore-password": "密码",
274274
"deposit": "存入金额"
275275
},
276+
"mainnet-address-required": "请输入主网地址",
277+
"testnet-address-required": "请输出测试网地址",
276278
"codes": {
277279
"-3": "",
278280
"100": "余额不足",

packages/neuron-ui/src/utils/validators.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,16 @@ import {
1010
import { CKBToShannonFormatter } from 'utils/formatters'
1111
import { ckbCore } from 'services/chain'
1212

13-
export const verifyAddress = (address: string): boolean => {
13+
export const verifyAddress = (address: string, isMainnet?: boolean): boolean => {
1414
if (typeof address !== 'string' || address.length !== 46) {
1515
return false
1616
}
17+
if (isMainnet === true && !address.startsWith('ckb')) {
18+
return false
19+
}
20+
if (isMainnet === false && !address.startsWith('ckt')) {
21+
return false
22+
}
1723
try {
1824
return ckbCore.utils.parseAddress(address, 'hex').startsWith('0x0100')
1925
} catch (err) {

packages/neuron-wallet/src/controllers/wallets.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { dialog, SaveDialogReturnValue, BrowserWindow } from 'electron'
44
import WalletsService, { Wallet, WalletProperties, FileKeystoreWallet } from 'services/wallets'
55
import Keystore from 'models/keys/keystore'
66
import Keychain from 'models/keys/keychain'
7+
import ChainInfo from 'models/chain-info'
78
import { validateMnemonic, mnemonicToSeedSync } from 'models/keys/mnemonic'
89
import { AccountExtendedPublicKey, ExtendedPrivateKey } from 'models/keys/key'
910
import { ResponseCode } from 'utils/const'
@@ -22,6 +23,7 @@ import i18n from 'utils/i18n'
2223
import AddressService from 'services/addresses'
2324
import WalletCreatedSubject from 'models/subjects/wallet-created-subject'
2425
import { TransactionWithoutHash, OutPoint } from 'types/cell-types'
26+
import { MainnetAddressRequired, TestnetAddressRequired } from 'exceptions/address'
2527

2628
export default class WalletsController {
2729
public static async getAll(): Promise<Controller.Response<Pick<Wallet, 'id' | 'name'>[]>> {
@@ -339,7 +341,16 @@ export default class WalletsController {
339341
feeRate = '1000'
340342
}
341343

344+
const isMainnet = ChainInfo.getInstance().isMainnet()
342345
params.items.forEach(item => {
346+
if (isMainnet && !item.address.startsWith('ckb')) {
347+
throw new MainnetAddressRequired(item.address)
348+
}
349+
350+
if (!isMainnet && !item.address.startsWith('ckt')) {
351+
throw new TestnetAddressRequired(item.address)
352+
}
353+
343354
if (!this.verifyAddress(item.address)) {
344355
throw new InvalidAddress(item.address)
345356
}

packages/neuron-wallet/src/exceptions/address.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,17 @@ export class InvalidAddress extends Error {
55
super(i18n.t('invalid-address', { address }))
66
}
77
}
8-
export default { InvalidAddress }
8+
9+
export class MainnetAddressRequired extends Error {
10+
constructor(address: string) {
11+
super(i18n.t('mainnet-address-required', { address }))
12+
}
13+
}
14+
15+
export class TestnetAddressRequired extends Error {
16+
constructor(address: string) {
17+
super(i18n.t('testnet-address-required', { address }))
18+
}
19+
}
20+
21+
export default { InvalidAddress, MainnetAddressRequired, TestnetAddressRequired }

packages/neuron-wallet/src/locales/en.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,9 @@ export default {
9393
'invalid-keystore': 'Keystore is invalid',
9494
'invalid-json': 'Invalid JSON file',
9595
'cell-is-not-yet-live': 'Cell is not yet live!',
96-
'transaction-is-not-committed-yet': 'Transaction is not committed yet!'
96+
'transaction-is-not-committed-yet': 'Transaction is not committed yet!',
97+
'mainnet-address-required': '{{address}} is not a mainnet address',
98+
'testnet-address-required': '{{address}} is not a testnet address'
9799
},
98100
contextMenu: {
99101
select: 'Select',

packages/neuron-wallet/src/locales/zh.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,9 @@ export default {
9292
'invalid-keystore': 'Keystore 格式不正确',
9393
'invalid-json': 'JSON 文件格式不正确',
9494
'cell-is-not-yet-live': 'Cell 尚未激活',
95-
'transaction-is-not-committed-yet': '交易未提交'
95+
'transaction-is-not-committed-yet': '交易未提交',
96+
'mainnet-address-required': '{{address}} 不是主网地址',
97+
'testnet-address-required': '{{address}} 不是测试网地址'
9698
},
9799
contextMenu: {
98100
select: '选择',

0 commit comments

Comments
 (0)