diff --git a/src/app/tabs/registrar/components/RegistrarComponent.js b/src/app/tabs/registrar/components/RegistrarComponent.js index 789b3a7f..006c7f87 100644 --- a/src/app/tabs/registrar/components/RegistrarComponent.js +++ b/src/app/tabs/registrar/components/RegistrarComponent.js @@ -31,7 +31,7 @@ class RegistrarComponent extends Component { render() { const { - strings, domain, owned, blocked, domainStateLoading, + strings, domain, owned, blocked, domainStateLoading, owner, requestingOwner, } = this.props; const { invalid } = this.state; @@ -46,17 +46,31 @@ class RegistrarComponent extends Component { } else if (domainStateLoading) { elementToRender = ; } else if (owned) { - elementToRender = ( - - {strings.owned} -
- {strings.admin_your_domain_title} -
- {strings.search_another_domain} -
- ); + if (requestingOwner) { + elementToRender = ( + + {strings.owned} +
+ +
+ ); + } else { + elementToRender = ( + + {strings.owned} +
+ + {strings.owner} + {': '} + + {owner} +
+ {strings.resolve} +
+ ); + } } else if (blocked) { - elementToRender =

{strings.domain_not_available}

; + elementToRender =

{strings.blocked_domain}

; } else { const domainDisplay = `${domain}.rsk`; @@ -90,21 +104,26 @@ RegistrarComponent.propTypes = { strings: propTypes.shape({ start_registration_for: propTypes.string.isRequired, rental_period: propTypes.string.isRequired, - domain_not_available: propTypes.string.isRequired, + blocked_domain: propTypes.string.isRequired, admin_your_domain_title: propTypes.string.isRequired, owned: propTypes.string.isRequired, search_another_domain: propTypes.string.isRequired, + owner: propTypes.string.isRequired, + resolve: propTypes.string.isRequired, }).isRequired, domain: propTypes.string.isRequired, domainStateLoading: propTypes.bool.isRequired, owned: propTypes.bool, blocked: propTypes.bool, + owner: propTypes.string, + requestingOwner: propTypes.bool.isRequired, getState: propTypes.func.isRequired, }; RegistrarComponent.defaultProps = { owned: false, blocked: false, + owner: '', }; export default multilanguage(RegistrarComponent); diff --git a/src/app/tabs/registrar/containers/RegistrarContainer.js b/src/app/tabs/registrar/containers/RegistrarContainer.js index d7e28076..ce2e910f 100644 --- a/src/app/tabs/registrar/containers/RegistrarContainer.js +++ b/src/app/tabs/registrar/containers/RegistrarContainer.js @@ -8,7 +8,9 @@ const mapStateToProps = state => ({ domain: parse(state.router.location.search).domain, domainStateLoading: state.search.domainStateLoading, owned: state.search.owned, + owner: state.search.owner, blocked: state.search.blocked, + requestingOwner: state.search.requestingOwner, }); const mapDispatchToProps = dispatch => ({ diff --git a/src/app/tabs/registrar/helpers.js b/src/app/tabs/registrar/helpers.js index 748f1ba0..209dd0ae 100644 --- a/src/app/tabs/registrar/helpers.js +++ b/src/app/tabs/registrar/helpers.js @@ -30,11 +30,7 @@ export const getRegisterData = (name, owner, secret, duration) => { const dataOwner = owner.toLowerCase().slice(2); // 32 bytes - let dataSecret = secret.slice(2); - const padding = 64 - dataSecret.length; - for (let i = 0; i < padding; i += 1) { - dataSecret += '0'; - } + const dataSecret = secret.slice(2); // 32 bytes const dataDuration = numberToUint32(duration); diff --git a/src/app/tabs/registrar/operations.js b/src/app/tabs/registrar/operations.js index ede4ff70..c7914a6a 100644 --- a/src/app/tabs/registrar/operations.js +++ b/src/app/tabs/registrar/operations.js @@ -33,7 +33,8 @@ export const commit = domain => async (dispatch) => { dispatch(requestCommitRegistrar()); const randomBytes = window.crypto.getRandomValues(new Uint8Array(32)); - const salt = `0x${Array.from(randomBytes).map(byte => byte.toString(16)).join('')}`; + const strSalt = Array.from(randomBytes).map(byte => byte.toString(16)).join(''); + const salt = `0x${strSalt.padEnd(64, '0')}`; const accounts = await window.ethereum.enable(); const currentAddress = accounts[0]; diff --git a/src/app/tabs/search/abis.json b/src/app/tabs/search/abis.json index 7b6ccf84..4e8e6ec0 100644 --- a/src/app/tabs/search/abis.json +++ b/src/app/tabs/search/abis.json @@ -18,6 +18,27 @@ "payable": false, "stateMutability": "view", "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" } ] } diff --git a/src/app/tabs/search/actions.js b/src/app/tabs/search/actions.js index 7e45c0c5..46d5b992 100644 --- a/src/app/tabs/search/actions.js +++ b/src/app/tabs/search/actions.js @@ -1,4 +1,7 @@ -import { REQUEST_DOMAIN_STATE, RECEIVE_DOMAIN_STATE, BLOCKED_DOMAIN } from './types'; +import { + REQUEST_DOMAIN_STATE, RECEIVE_DOMAIN_STATE, + BLOCKED_DOMAIN, REQUEST_DOMAIN_OWNER, RECEIVE_DOMAIN_OWNER, +} from './types'; export const requestDomainState = () => ({ type: REQUEST_DOMAIN_STATE, @@ -9,6 +12,15 @@ export const receiveDomainState = available => ({ owned: !available, }); +export const requestDomainOwner = () => ({ + type: REQUEST_DOMAIN_OWNER, +}); + +export const receiveDomainOwner = owner => ({ + type: RECEIVE_DOMAIN_OWNER, + owner, +}); + export const blockedDomain = () => ({ type: BLOCKED_DOMAIN, }); diff --git a/src/app/tabs/search/components/DomainStateComponent.js b/src/app/tabs/search/components/DomainStateComponent.js index ceaa616f..62cae3ce 100644 --- a/src/app/tabs/search/components/DomainStateComponent.js +++ b/src/app/tabs/search/components/DomainStateComponent.js @@ -7,16 +7,32 @@ import { import { multilanguage } from 'redux-multilanguage'; import { isValidName } from '../../../validations'; -function getDisplayState(domain, domainStateLoading, owned, blocked, strings) { +// eslint-disable-next-line max-len +function getDisplayState(domain, domainStateLoading, owned, blocked, owner, requestingOwner, strings) { if (!domain) return 'Search for a domain.'; if (domainStateLoading) return ; if (owned) { + if (requestingOwner) { + return ( + + {strings.owned} +
+ +
+ ); + } return ( {strings.owned}
- {strings.admin_your_domain_title} + + {strings.owner} + {': '} + + {owner} +
+ {strings.resolve}
{strings.search_another_domain}
@@ -24,7 +40,7 @@ function getDisplayState(domain, domainStateLoading, owned, blocked, strings) { } if (blocked) { - return strings.domain_not_available; + return strings.blocked_domain; } return ( @@ -90,7 +106,7 @@ class DomainStateComponent extends Component { render() { const { - strings, domain, owned, domainStateLoading, blocked, + strings, domain, owned, domainStateLoading, blocked, owner, requestingOwner, } = this.props; const { searchValue, invalid, showProcess } = this.state; @@ -100,7 +116,9 @@ class DomainStateComponent extends Component { domainDisplay = domain.split('.').length === 1 ? `${domain}.rsk` : domain; } - const displayState = getDisplayState(domain, domainStateLoading, owned, blocked, strings); + const displayState = getDisplayState( + domain, domainStateLoading, owned, blocked, owner, requestingOwner, strings, + ); return ( @@ -171,10 +189,13 @@ DomainStateComponent.propTypes = { process_step_3: propTypes.string.isRequired, learn_more: propTypes.string.isRequired, rskTld: propTypes.string.isRequired, + blocked_domain: propTypes.string.isRequired, }).isRequired, domain: propTypes.string.isRequired, owned: propTypes.bool, + owner: propTypes.string, blocked: propTypes.bool, + requestingOwner: propTypes.bool.isRequired, domainStateLoading: propTypes.bool.isRequired, getState: propTypes.func.isRequired, search: propTypes.func.isRequired, @@ -182,6 +203,7 @@ DomainStateComponent.propTypes = { DomainStateComponent.defaultProps = { owned: false, + owner: '', blocked: false, }; diff --git a/src/app/tabs/search/containers/DomainStateContainer.js b/src/app/tabs/search/containers/DomainStateContainer.js index d99dc3b3..919c4906 100644 --- a/src/app/tabs/search/containers/DomainStateContainer.js +++ b/src/app/tabs/search/containers/DomainStateContainer.js @@ -8,7 +8,9 @@ const mapStateToProps = state => ({ domain: parse(state.router.location.search).domain || '', domainStateLoading: state.search.domainStateLoading, owned: state.search.owned, + owner: state.search.owner, blocked: state.search.blocked, + requestingOwner: state.search.requestingOwner, }); const mapDispatchToProps = dispatch => ({ diff --git a/src/app/tabs/search/operations.js b/src/app/tabs/search/operations.js index ab765214..0c04f275 100644 --- a/src/app/tabs/search/operations.js +++ b/src/app/tabs/search/operations.js @@ -1,6 +1,9 @@ import Web3 from 'web3'; import { keccak_256 as sha3 } from 'js-sha3'; -import { requestDomainState, receiveDomainState, blockedDomain } from './actions'; +import { + requestDomainState, receiveDomainState, blockedDomain, + requestDomainOwner, receiveDomainOwner, +} from './actions'; import { rskOwner as rskOwnerAddress } from '../../../config/contracts.json'; import { notifyError } from '../../notifications'; import { rskMain } from '../../../config/nodes.json'; @@ -26,7 +29,11 @@ export default domain => (dispatch) => { return rskOwner.methods.available(hash).call() .then((available) => { if (!available) { - return dispatch(receiveDomainState(false)); + dispatch(receiveDomainState(false)); + dispatch(requestDomainOwner()); + return rskOwner.methods.ownerOf(hash).call() + .then(owner => dispatch(receiveDomainOwner(owner))) + .catch(error => dispatch(notifyError(error.message))); } return dispatch(receiveDomainState(available)); diff --git a/src/app/tabs/search/reducer.js b/src/app/tabs/search/reducer.js index fa054ab2..88b08c27 100644 --- a/src/app/tabs/search/reducer.js +++ b/src/app/tabs/search/reducer.js @@ -1,10 +1,15 @@ -import { REQUEST_DOMAIN_STATE, RECEIVE_DOMAIN_STATE, BLOCKED_DOMAIN } from './types'; +import { + REQUEST_DOMAIN_STATE, RECEIVE_DOMAIN_STATE, BLOCKED_DOMAIN, + REQUEST_DOMAIN_OWNER, RECEIVE_DOMAIN_OWNER, +} from './types'; // TODO: check initial state const initialState = { owned: undefined, + owner: undefined, domainStateLoading: false, blocked: undefined, + requestingOwner: false, }; const searchReducer = (state = initialState, action) => { @@ -30,6 +35,19 @@ const searchReducer = (state = initialState, action) => { blocked: true, }; } + case REQUEST_DOMAIN_OWNER: { + return { + ...state, + requestingOwner: true, + }; + } + case RECEIVE_DOMAIN_OWNER: { + return { + ...state, + requestingOwner: false, + owner: action.owner, + }; + } default: return state; } }; diff --git a/src/app/tabs/search/reducer.test.js b/src/app/tabs/search/reducer.test.js index a327d1ac..e0d53010 100644 --- a/src/app/tabs/search/reducer.test.js +++ b/src/app/tabs/search/reducer.test.js @@ -1,5 +1,8 @@ import reducer from './reducer'; -import { REQUEST_DOMAIN_STATE, RECEIVE_DOMAIN_STATE, BLOCKED_DOMAIN } from './types'; +import { + REQUEST_DOMAIN_STATE, RECEIVE_DOMAIN_STATE, BLOCKED_DOMAIN, + REQUEST_DOMAIN_OWNER, RECEIVE_DOMAIN_OWNER, +} from './types'; describe('search reducer', () => { it('should return the initial state', () => { @@ -7,8 +10,10 @@ describe('search reducer', () => { .toEqual( { owned: undefined, + owner: undefined, domainStateLoading: false, blocked: undefined, + requestingOwner: false, }, ); }); @@ -35,7 +40,7 @@ describe('search reducer', () => { }); }); - it('should handle RECEIVE_DOMAIN_STATE', () => { + it('should handle RECEIVE_DOMAIN_STATE not available', () => { expect( reducer({}, { type: RECEIVE_DOMAIN_STATE, @@ -48,6 +53,32 @@ describe('search reducer', () => { }); }); + it('should handle RECEIVE_DOMAIN_STATE not available', () => { + expect( + reducer({}, { + type: RECEIVE_DOMAIN_STATE, + owned: true, + }), + ).toEqual({ + owned: true, + domainStateLoading: false, + blocked: false, + }); + }); + + it('should handle RECEIVE_DOMAIN_STATE available', () => { + expect( + reducer({}, { + type: RECEIVE_DOMAIN_STATE, + owned: false, + }), + ).toEqual({ + owned: false, + domainStateLoading: false, + blocked: false, + }); + }); + it('should handle REQUEST_DOMAIN_STATE and RECEIVE_DOMAIN_STATE', () => { expect( reducer({}, { @@ -73,6 +104,108 @@ describe('search reducer', () => { }); }); + it('should handle REQUEST_DOMAIN_OWNER', () => { + expect( + reducer({}, { + type: REQUEST_DOMAIN_OWNER, + }), + ) + .toEqual({ + requestingOwner: true, + }); + }); + + it('should handle RECEIVE_DOMAIN_OWNER', () => { + expect( + reducer({}, { + type: RECEIVE_DOMAIN_OWNER, + owner: 'testing', + }), + ).toEqual({ + requestingOwner: false, + owner: 'testing', + }); + }); + + it('should handle REQUEST_DOMAIN_OWNER and RECEIVE_DOMAIN_OWNER', () => { + expect( + reducer({}, { + type: REQUEST_DOMAIN_OWNER, + }), + ).toEqual({ + requestingOwner: true, + }); + + expect( + reducer({ + requestingOwner: true, + }, { + type: RECEIVE_DOMAIN_OWNER, + owner: 'testing', + }), + ).toEqual({ + requestingOwner: false, + owner: 'testing', + }); + }); + + it('should handle REQUEST_DOMAIN_STATE and RECEIVE_DOMAIN_STATE and REQUEST_DOMAIN_OWNER and RECEIVE_DOMAIN_OWNER', () => { + expect( + reducer({}, { + type: REQUEST_DOMAIN_STATE, + }), + ).toEqual({ + domainStateLoading: true, + }); + + expect( + reducer({ + owned: undefined, + domainStateLoading: true, + }, { + type: RECEIVE_DOMAIN_STATE, + owned: true, + }), + ).toEqual({ + owned: true, + domainStateLoading: false, + blocked: false, + }); + + expect( + reducer({ + owned: true, + domainStateLoading: false, + blocked: false, + }, { + type: REQUEST_DOMAIN_OWNER, + }), + ).toEqual({ + owned: true, + domainStateLoading: false, + blocked: false, + requestingOwner: true, + }); + + expect( + reducer({ + owned: true, + domainStateLoading: false, + blocked: false, + requestingOwner: true, + }, { + type: RECEIVE_DOMAIN_OWNER, + owner: 'testing', + }), + ).toEqual({ + owned: true, + domainStateLoading: false, + blocked: false, + requestingOwner: false, + owner: 'testing', + }); + }); + it('should return the initial state when action is not implemented', () => { expect(reducer(undefined, { type: 'NOT_IMPLEMENTED', @@ -80,8 +213,10 @@ describe('search reducer', () => { .toEqual( { owned: undefined, + owner: undefined, domainStateLoading: false, blocked: undefined, + requestingOwner: false, }, ); }); diff --git a/src/app/tabs/search/types.js b/src/app/tabs/search/types.js index 43a78311..11250c33 100644 --- a/src/app/tabs/search/types.js +++ b/src/app/tabs/search/types.js @@ -1,3 +1,5 @@ export const REQUEST_DOMAIN_STATE = 'REQUEST_DOMAIN_STATE'; export const RECEIVE_DOMAIN_STATE = 'RECEIVE_DOMAIN_STATE'; export const BLOCKED_DOMAIN = 'BLOCKED_DOMAIN'; +export const REQUEST_DOMAIN_OWNER = 'REQUEST_DOMAIN_OWNER'; +export const RECEIVE_DOMAIN_OWNER = 'RECEIVE_DOMAIN_OWNER'; diff --git a/src/languages/en.json b/src/languages/en.json index cfe327d7..2bf7521f 100644 --- a/src/languages/en.json +++ b/src/languages/en.json @@ -197,5 +197,6 @@ "notifications_registrar_committed": "your domain has been requested to be registered", "notifications_registrar_revealed": "your domain has been registered", "login_explanation": "now you can login with your just registered domain", - "rskTld": ".rsk" + "rskTld": ".rsk", + "blocked_domain": "domains with less than 5 characters are blocked. stay tuned, we are going to release them soon" } diff --git a/src/languages/es_uy.json b/src/languages/es_uy.json index 7217f6d8..b1809e84 100755 --- a/src/languages/es_uy.json +++ b/src/languages/es_uy.json @@ -191,5 +191,6 @@ "notifications_registrar_committed": "se ha solicitado el registro de su dominio", "notifications_registrar_revealed": "su dominio ha sido registrado", "login_explanation": "ahora puede iniciar sesión con su dominio recién registrado", - "rskTld": ".rsk" + "rskTld": ".rsk", + "blocked_domain": "los dominios con menos de 5 caracteres están bloqueados. no se vayan, los liberaremos pronto" } diff --git a/src/languages/ja.json b/src/languages/ja.json index b7ff71e9..8e2dc752 100755 --- a/src/languages/ja.json +++ b/src/languages/ja.json @@ -191,5 +191,6 @@ "notifications_registrar_committed": "お客様のドメインを登録する必要があります", "notifications_registrar_revealed": "お客様のドメインが登録されました", "login_explanation": "お客様は登録したばかりのドメインに今すぐログインできます", - "rskTld": ".rsk" + "rskTld": ".rsk", + "blocked_domain": "5文字以下のドメインはブロックされます。チャンネルはそのままで、私たちはそれらをすぐにリリースします" } diff --git a/src/languages/ko.json b/src/languages/ko.json index af44eae5..f7694b97 100755 --- a/src/languages/ko.json +++ b/src/languages/ko.json @@ -191,5 +191,6 @@ "notifications_registrar_committed": "여러분의 도메인 등록이 요청되었습니다", "notifications_registrar_revealed": "여러분의 도메인이 등록되었습니다", "login_explanation": "방금 등록된 도메인으로 이제 로그인할 수 있습니다", - "rskTld": ".rsk" + "rskTld": ".rsk", + "blocked_domain": "5자 이하인 도메인은 차단됩니다. 곧 발표 예정이니 기대해 주세요" } diff --git a/src/languages/pt_br.json b/src/languages/pt_br.json index 01b09e10..f416f974 100755 --- a/src/languages/pt_br.json +++ b/src/languages/pt_br.json @@ -191,5 +191,6 @@ "notifications_registrar_committed": "o registro de seu domínio foi solicitado", "notifications_registrar_revealed": "seu domínio foi registrado", "login_explanation": "agora você pode fazer login com o domínio que acaba de registrar", - "rskTld": ".rsk" + "rskTld": ".rsk", + "blocked_domain": "domínios com menos de 5 caracteres estão bloqueados. fique atento, vamos liberá-los em breve" } diff --git a/src/languages/ru.json b/src/languages/ru.json index 1c4258df..14f4b16f 100755 --- a/src/languages/ru.json +++ b/src/languages/ru.json @@ -191,5 +191,6 @@ "notifications_registrar_committed": "вы запросили домен для регистрации", "notifications_registrar_revealed": "ваш домен зарегистрирован", "login_explanation": "теперь вы можете войти в систему с только что зарегистрированным доменом", - "rskTld": ".rsk" + "rskTld": ".rsk", + "blocked_domain": "домены, содержащие менее 5 символов, блокируются. следите за обновлениями, мы скоро их выпустим" } diff --git a/src/languages/zh_cn.json b/src/languages/zh_cn.json index 5fc5ff38..9765305d 100755 --- a/src/languages/zh_cn.json +++ b/src/languages/zh_cn.json @@ -191,5 +191,6 @@ "notifications_registrar_committed": "您的域名已被要求注册", "notifications_registrar_revealed": "您的域名已注册", "login_explanation": "现在您可使用您刚注册的域登录", - "rskTld": ".rsk" + "rskTld": ".rsk", + "blocked_domain": "少于 5 个字符的域名被拦截了。请继续关注,我们将尽快发布" }