diff --git a/.eslintignore b/.eslintignore index b54509b61..d2e8e4bba 100644 --- a/.eslintignore +++ b/.eslintignore @@ -28,6 +28,7 @@ app/js/components/* app/js/store/* app/js/utils/* !app/js/utils/account-utils* +!app/js/utils/api-utils* app/js/profiles/store/* app/js/profiles/tabs/* diff --git a/app/js/account/StorageProvidersPage.js b/app/js/account/StorageProvidersPage.js index f6f5380da..7df9d9dec 100644 --- a/app/js/account/StorageProvidersPage.js +++ b/app/js/account/StorageProvidersPage.js @@ -4,9 +4,7 @@ import { connect } from 'react-redux' import { AccountActions } from '../account/store/account' import { SettingsActions } from '../account/store/settings' -import { DROPBOX, BLOCKSTACK_INC } from './utils/index' -import { getDropboxAccessTokenFromHash, - redirectToConnectToDropbox } from './utils/dropbox' +import { BLOCKSTACK_INC } from './utils/index' import { connectToGaiaHub } from './utils/blockstack-inc' @@ -15,7 +13,6 @@ import log4js from 'log4js' const logger = log4js.getLogger('storage/StorageProvidersPage.js') -const Dropbox = require('dropbox') function mapStateToProps(state) { return { @@ -51,47 +48,18 @@ class StorageProvidersPage extends Component { this.state = { hide: true } - this.connectDropbox = this.connectDropbox.bind(this) - this.disconnectDropbox = this.disconnectDropbox.bind(this) this.updateApi = this.updateApi.bind(this) } componentWillMount() { - const api = this.props.api - const dropboxAccessToken = getDropboxAccessTokenFromHash(window.location.hash) const needToConnectGaiaHub = window.location.hash === '#gaiahub' - const needToConnectDropbox = dropboxAccessToken != null - if (needToConnectDropbox) { - const newApi = Object.assign({}, api, { dropboxAccessToken }) - this.props.updateApi(newApi) - const identityIndex = 0 - const identity = this.props.localIdentities[identityIndex] - const identityAddress = identity.ownerAddress - const profileSigningKeypair = this.props.identityKeypairs[identityIndex] - const profile = identity.profile - - // This is okay selecting storage right now is only done during on-boarding - const firstDropboxUpload = true - - setCoreStorageConfig(newApi, identityIndex, identityAddress, - profile, profileSigningKeypair, firstDropboxUpload) - .then((indexUrl) => { - logger.debug(`componentDidMount: indexUrl: ${indexUrl}`) - // TODO add index URL to token file - logger.debug('componentDidMount: storage initialized') - const newApi2 = Object.assign({}, newApi, { storageConnected: true }) - this.props.updateApi(newApi2) - this.props.storageIsConnected() - logger.debug('componentDidMount: storage configured') - }) - } if (needToConnectGaiaHub) { logger.debug('componentDidMount: trying to connect gaia hub...') this.connectSharedService() } // We can show the page contents since there's not going to be a redirect - if (!(needToConnectGaiaHub || needToConnectDropbox)) { + if (!(needToConnectGaiaHub)) { this.setState({ hide: false }) } } @@ -109,17 +77,6 @@ class StorageProvidersPage extends Component { } } - connectDropbox() { - redirectToConnectToDropbox() - } - - disconnectDropbox() { - const api = this.props.api - const dbx = new Dropbox({ accessToken: api.dropboxAccessToken }) - dbx.authTokenRevoke() - this.props.updateApi(Object.assign({}, api, { dropboxAccessToken: null })) - } - connectSharedService() { const storageProvider = this.props.api.gaiaHubUrl const signer = this.props.identityKeypairs[0].key @@ -135,7 +92,7 @@ class StorageProvidersPage extends Component { const profileSigningKeypair = this.props.identityKeypairs[identityIndex] const profile = identity.profile setCoreStorageConfig(newApi, identityIndex, identityAddress, - profile, profileSigningKeypair) + profile, profileSigningKeypair, identity) .then((indexUrl) => { logger.debug(`componentDidMount: indexUrl: ${indexUrl}`) // TODO add index URL to token file @@ -204,89 +161,6 @@ class StorageProvidersPage extends Component { Run your own Gaia storage hub

-

- {api.hostedDataLocation !== DROPBOX ? - - : - - } -

-

- -

-

- -

-

- -

-

- -

-

- -

-

- -

-

- -

} diff --git a/app/js/account/store/settings/actions.js b/app/js/account/store/settings/actions.js index dd32d8edc..af5d49f18 100644 --- a/app/js/account/store/settings/actions.js +++ b/app/js/account/store/settings/actions.js @@ -33,7 +33,6 @@ function refreshBtcPrice(btcPriceUrl) { function resetApi(api) { logger.trace('resetApi') - let dropboxAccessToken = api.dropboxAccessToken let coreAPIPassword = api.coreAPIPassword let gaiaHubConfig = api.gaiaHubConfig @@ -41,17 +40,12 @@ function resetApi(api) { gaiaHubConfig = null } - if (dropboxAccessToken === undefined) { - dropboxAccessToken = null - } - if (coreAPIPassword === undefined) { coreAPIPassword = null } return dispatch => { dispatch(updateApi(Object.assign({}, DEFAULT_API, { gaiaHubConfig, - dropboxAccessToken, coreAPIPassword }))) } diff --git a/app/js/account/store/settings/default.js b/app/js/account/store/settings/default.js index 2999b83a5..0a68298c8 100644 --- a/app/js/account/store/settings/default.js +++ b/app/js/account/store/settings/default.js @@ -1,4 +1,4 @@ -import { DROPBOX } from '../../../account/utils/index' +import { BLOCKSTACK_INC } from '../../../account/utils/index' import { isCoreEndpointDisabled } from '../../../utils/window-utils' export const REGTEST_CORE_API_PASSWORD = 'blockstack_integration_test_api_password' @@ -42,15 +42,11 @@ const DEFAULT_API = { } }, browserServerUrl: 'https://blockstack-browser-server.appartisan.com', - hostedDataLocation: DROPBOX, + hostedDataLocation: BLOCKSTACK_INC, coreHost: 'localhost', corePort: 6270, coreAPIPassword: null, logServerPort: '', - s3ApiKey: '', - s3ApiSecret: '', - s3Bucket: '', - dropboxAccessToken: null, storageConnected: false, gaiaHubConfig: null, gaiaHubUrl: 'https://hub.blockstack.org', diff --git a/app/js/account/utils/blockstack-inc.js b/app/js/account/utils/blockstack-inc.js index 7684ffbc4..31ebaba66 100644 --- a/app/js/account/utils/blockstack-inc.js +++ b/app/js/account/utils/blockstack-inc.js @@ -1,25 +1,9 @@ // @flow import log4js from 'log4js' -import { uploadToGaiaHub, connectToGaiaHub, GaiaHubConfig } from 'blockstack' +import { connectToGaiaHub, GaiaHubConfig } from 'blockstack' const logger = log4js.getLogger('account/utils/blockstack-inc.js') -export function uploadPhotoToGaiaHub(api: {gaiaHubConfig: GaiaHubConfig }, - identityIndex: number, identityAddress: string, photoFile: any, photoIndex: number) { - logger.trace('uploadPhotoToGaiaHub') - const hubConfig = api.gaiaHubConfig - const filename = `${identityIndex}/avatar-${photoIndex}` - return uploadToGaiaHub(filename, photoFile, hubConfig) -} - -export function uploadProfileToGaiaHub(api: {gaiaHubConfig: GaiaHubConfig}, - identityIndex: number, identityAddress: string, signedProfileTokenData: string) { - logger.trace('uploadProfileToGaiaHub') - const hubConfig = api.gaiaHubConfig - const filename = `${identityIndex}/profile.json` - return uploadToGaiaHub(filename, signedProfileTokenData, hubConfig, 'application/json') -} - export function redirectToConnectToGaiaHub() { logger.trace('redirectToConnectToGaiaHub') const port = location.port === '' ? 80 : location.port diff --git a/app/js/account/utils/dropbox.js b/app/js/account/utils/dropbox.js deleted file mode 100644 index 33f31947f..000000000 --- a/app/js/account/utils/dropbox.js +++ /dev/null @@ -1,142 +0,0 @@ -// @flow -import Dropbox from 'dropbox' -import log4js from 'log4js' - -const logger = log4js.getLogger('account/utils/dropbox.js') - -export const DROPBOX_APP_ID = 'f3l2g7ge4bs68o4' - -export function redirectToConnectToDropbox() { - const dbx = new Dropbox({ clientId: DROPBOX_APP_ID }) - const port = location.port === '' ? 80 : location.port - console.log(port) - window.location = dbx.getAuthenticationUrl( - `http://localhost:${port}/account/storage`) -} - -function getAvatarPath(identityIndex: number, - identityAddress: string, photoIndex: number): string { - const path = `/${identityAddress}/${identityIndex}/avatar-${photoIndex}` - return path -} - -function getProfilePath(identityIndex: number, - identityAddress: string): string { - const path = `/${identityAddress}/${identityIndex}/profile.json` - return path -} - -function deleteProfile(api: {dropboxAccessToken: string}, identityIndex: number, - identityAddress: string): Promise<*> { - const dbx = new Dropbox({ accessToken: api.dropboxAccessToken }) - const path = getProfilePath(identityIndex, identityAddress) - return dbx.filesDelete({ path }) -} - -function uploadProfile(api: {dropboxAccessToken: string}, identityIndex: number, - identityAddress: string, signedProfileTokenData: string, firstUpload: boolean): Promise<*> { - return new Promise((resolve, reject) => { - const dbx = new Dropbox({ accessToken: api.dropboxAccessToken }) - const path = getProfilePath(identityIndex, identityAddress) - return dbx.filesUpload({ path, contents: signedProfileTokenData, mode: 'overwrite' }) - .then((response) => { - if (firstUpload === true) { // we can only create shared link once - logger.debug('uploadProfile: first upload: creating shared link') - return dbx.sharingCreateSharedLinkWithSettings({ path: response.path_lower, settings: {} }) - .then((shareLinkResponse) => { - logger.debug(`uploadProfile: shared link: ${shareLinkResponse}`) - /* Appending dropbox share url with ?dl=1 returns the actual file - instead of dropbox sign up page */ - const profileUrl = `${shareLinkResponse.url.split('=')[0]}=1` - resolve(profileUrl) - }) - .catch((error) => { - logger.error('uploadProfile: error creating shared link', error) - reject(error) - return Promise.reject() - }) - } else { - logger.debug('uploadProfile: not first upload - we won\'t create shared link') - resolve(null) - return Promise.reject() - } - }) - .catch((error) => { - reject(error) - }) - }) -} - - -export function uploadProfileToDropbox(api: {dropboxAccessToken: string}, - identityIndex: number, identityAddress: string, signedProfileTokenData: string, - firstUpload: boolean = false): Promise<*> { - if (firstUpload === true) { // We try to delete any existing profile file - return deleteProfile(api, identityIndex, identityAddress) - .then(() => uploadProfile(api, identityIndex, identityAddress, - signedProfileTokenData, firstUpload)) - // the profile didn't exist - .catch(() => uploadProfile(api, identityIndex, identityAddress, - signedProfileTokenData, firstUpload)) - } else { - return uploadProfile(api, identityIndex, identityAddress, - signedProfileTokenData, firstUpload) - } -} - -function deletePhoto(api: {dropboxAccessToken: string}, identityIndex: number, - identityAddress: string, photoIndex: number): Promise<*> { - const dbx = new Dropbox({ accessToken: api.dropboxAccessToken }) - const path = getAvatarPath(identityIndex, identityAddress, photoIndex) - return dbx.filesDelete({ path }) -} - -function uploadPhoto(api: {dropboxAccessToken: string}, identityIndex: number, - identityAddress: string, photoFile: any, photoIndex: number): Promise<*> { - const dbx = new Dropbox({ accessToken: api.dropboxAccessToken }) - const path = getAvatarPath(identityIndex, identityAddress, photoIndex) - return new Promise((resolve, reject) => dbx.filesUpload({ path, contents: photoFile }) - .then((response) => { - dbx.sharingCreateSharedLinkWithSettings({ path: response.path_lower, settings: {} }) - .then((shareLinkResponse) => { - /* Appending dropbox share url with ?dl=1 returns the actual file - instead of dropbox sign up page */ - const avatarUrl = `${shareLinkResponse.url.split('=')[0]}=1` - - resolve(avatarUrl) - }) - .catch((error) => { - reject(error) - }) - }) - .catch((error) => { - reject(error) - })) -} - -export function uploadPhotoToDropbox(api: {dropboxAccessToken: string}, - identityIndex: number, identityAddress: string, photoFile: any, - photoIndex: number): Promise<*> { - logger.debug(`uploadPhotoToDropbox: id index: ${identityIndex} id address ${identityAddress}`) - // We try to delete any existing photo - return deletePhoto(api, identityIndex, identityAddress, photoIndex).then(() => - uploadPhoto(api, identityIndex, identityAddress, photoFile, photoIndex)) - // the file didn't exist - .catch(() => uploadPhoto(api, identityIndex, identityAddress, photoFile, photoIndex)) -} - - -export function getDropboxAccessTokenFromHash(hash: string) { - let tokens = hash.split('access_token=') - if (tokens.length !== 2) { - return null - } - - tokens = tokens[1].split('&') - - if (tokens[0] === '') { - return null - } - - return tokens[0] -} diff --git a/app/js/account/utils/index.js b/app/js/account/utils/index.js index 43ab8599c..408eb1e90 100644 --- a/app/js/account/utils/index.js +++ b/app/js/account/utils/index.js @@ -1,62 +1,95 @@ // @flow -import { uploadPhotoToDropbox, uploadProfileToDropbox } from './dropbox' -import { uploadPhotoToGaiaHub, uploadProfileToGaiaHub } from './blockstack-inc' -import type { GaiaHubConfig } from './blockstack-inc' -import log4js from 'log4js' +import { parseZoneFile } from 'zone-file' -const logger = log4js.getLogger('account/utils/index.js') +import type { GaiaHubConfig } from 'blockstack' +import { connectToGaiaHub, uploadToGaiaHub } from 'blockstack' + +import { getTokenFileUrlFromZoneFile } from '../../utils/zone-utils' export const BLOCKSTACK_INC = 'gaia-hub' -export const DROPBOX = 'dropbox' -function getStorageMethod(api: {dropboxAccessToken: string}) { - if (api.hostedDataLocation === DROPBOX && - api.dropboxAccessToken.length > 0) { - return DROPBOX +function getProfileUploadLocation(identity: any, hubConfig: GaiaHubConfig) { + if (identity.zoneFile) { + const zoneFileJson = parseZoneFile(identity.zoneFile) + return getTokenFileUrlFromZoneFile(zoneFileJson) + } else { + // aaron-debt: this should call a function in blockstack.js to get + // the read url + return `${hubConfig.url_prefix}${hubConfig.address}/profile.json` } - return BLOCKSTACK_INC } -function checkIdentityInputs(identityIndex: number, identityAddress: string) { - if (!identityIndex && identityIndex !== 0) { - const message = 'checkIdentityInputs: No identity index provided' - logger.error(message) - throw new Error(message) +// aaron-debt: this should be moved into blockstack.js +function canWriteUrl(url: string, + hubConfig: GaiaHubConfig): ?string { + const readPrefix = `${hubConfig.url_prefix}${hubConfig.address}/` + if (url.startsWith(readPrefix)) { + return url.substring(readPrefix.length) + } else { + return null } +} - if (!identityAddress) { - const message = 'checkIdentityInputs: No identity address provided' - logger.error(message) - throw new Error(message) +function tryUpload(urlToWrite: string, data: string, + hubConfig: GaiaHubConfig, mimeType: ?string = undefined) { + const filenameWrite = canWriteUrl(urlToWrite, hubConfig) + if (filenameWrite === null) { + return null } + return uploadToGaiaHub(filenameWrite, data, hubConfig, mimeType) } -export function uploadPhoto(api: {dropboxAccessToken: string, gaiaHubConfig: GaiaHubConfig}, - identityIndex: number, identityAddress: string, photoFile: string, photoIndex: number) { - const storageMethod = getStorageMethod(api) - logger.debug(`uploadPhoto: id index: ${identityIndex} id address ${identityAddress}`) - switch (storageMethod) { - case DROPBOX: - return uploadPhotoToDropbox(api, identityIndex, identityAddress, photoFile, photoIndex) - default: - return uploadPhotoToGaiaHub(api, identityIndex, identityAddress, photoFile, photoIndex) - } +export function uploadPhoto( + api: {gaiaHubConfig: GaiaHubConfig, gaiaHubUrl: string}, + identity: any, identityKeyPair: {key: string}, + photoFile: string, photoIndex: number) { + return connectToGaiaHub(api.gaiaHubUrl, identityKeyPair.key) + .then((identityHubConfig) => { + const globalHubConfig = api.gaiaHubConfig + + let uploadPrefix = getProfileUploadLocation(identity, identityHubConfig) + if (uploadPrefix.endsWith('profile.json')) { + uploadPrefix = uploadPrefix.substring(0, uploadPrefix.length - 'profile.json'.length) + } else { + throw new Error(`Cannot determine photo location based on profile location ${uploadPrefix}`) + } + const urlToWrite = `${uploadPrefix}/avatar-${photoIndex}` + let uploadAttempt = tryUpload(urlToWrite, photoFile, identityHubConfig, undefined) + if (uploadAttempt === null) { + uploadAttempt = tryUpload(urlToWrite, photoFile, globalHubConfig, undefined) + } + + // if still null, we don't know the write gaia-hub-config to write the file. + if (uploadAttempt === null) { + throw new Error(`Wanted to write to ${urlToWrite} but I don't know how.`) + } + + return uploadAttempt + }) } -export function uploadProfile(api: {dropboxAccessToken: string, gaiaHubConfig: GaiaHubConfig }, - identityIndex: number, identityAddress: string, signedProfileTokenData: string, - firstUpload: boolean = false) { - checkIdentityInputs(identityIndex, identityAddress) +export function uploadProfile( + api: {gaiaHubConfig: GaiaHubConfig, gaiaHubUrl: string}, + identity: any, identityKeyPair: {key: string}, + signedProfileTokenData: string) { + return connectToGaiaHub(api.gaiaHubUrl, identityKeyPair.key) + .then((identityHubConfig) => { + const globalHubConfig = api.gaiaHubConfig - const storageMethod = getStorageMethod(api) + const urlToWrite = getProfileUploadLocation(identity, identityHubConfig) - switch (storageMethod) { - case DROPBOX: - return uploadProfileToDropbox(api, identityIndex, identityAddress, - signedProfileTokenData, firstUpload) + let uploadAttempt = tryUpload(urlToWrite, signedProfileTokenData, + identityHubConfig, 'application/json') + if (uploadAttempt === null) { + uploadAttempt = tryUpload(urlToWrite, signedProfileTokenData, + globalHubConfig, 'application/json') + } - default: - return uploadProfileToGaiaHub(api, identityIndex, identityAddress, - signedProfileTokenData) - } + // if still null, we don't know the write gaia-hub-config to write the file. + if (uploadAttempt === null) { + throw new Error(`Wanted to write to ${urlToWrite} but I don't know how.`) + } + + return uploadAttempt + }) } diff --git a/app/js/auth/components/AuthModal.js b/app/js/auth/components/AuthModal.js index b4f06fb55..27d8483b4 100644 --- a/app/js/auth/components/AuthModal.js +++ b/app/js/auth/components/AuthModal.js @@ -64,7 +64,7 @@ class AuthModal extends Component { static propTypes = { defaultIdentity: PropTypes.number.isRequired, localIdentities: PropTypes.array.isRequired, - loadAppManifest: PropTypes.func.isRequired, + verifyAuthRequestAndLoadManifest: PropTypes.func.isRequired, clearSessionToken: PropTypes.func.isRequired, getCoreSessionToken: PropTypes.func.isRequired, coreAPIPassword: PropTypes.string.isRequired, @@ -142,7 +142,7 @@ class AuthModal extends Component { invalidScopes }) - this.props.loadAppManifest(authRequest) + this.props.verifyAuthRequestAndLoadManifest(authRequest) } componentWillReceiveProps(nextProps) { @@ -221,12 +221,15 @@ class AuthModal extends Component { if (storageConnected) { getAppBucketUrl('https://hub.blockstack.org', appPrivateKey) .then((appBucketUrl) => { - const identityAddress = identity.ownerAddress - const signedProfileTokenData = signProfileForUpload(profile, - nextProps.identityKeypairs[identityIndex]) + logger.debug(`componentWillReceiveProps: appBucketUrl ${appBucketUrl}`) apps[appDomain] = appBucketUrl + logger.debug(`componentWillReceiveProps: new apps array ${JSON.stringify(apps)}`) profile.apps = apps - return uploadProfile(this.props.api, identityIndex, identityAddress, + const signedProfileTokenData = signProfileForUpload(profile, + nextProps.identityKeypairs[identityIndex]) + logger.debug('componentWillReceiveProps: uploading updated profile with new apps array') + return uploadProfile(this.props.api, identity, + nextProps.identityKeypairs[identityIndex], signedProfileTokenData) }) .then(() => { @@ -380,7 +383,7 @@ class AuthModal extends Component { if (requestingStoreWrite && needsCoreStorage) { logger.trace('login(): Calling setCoreStorageConfig()...') setCoreStorageConfig(this.props.api, identityIndex, identity.ownerAddress, - identity.profile, profileSigningKeypair) + identity.profile, profileSigningKeypair, identity) .then(() => { logger.trace('login(): Core storage successfully configured.') logger.trace('login(): Calling getCoreSessionToken()...') @@ -513,7 +516,9 @@ class AuthModal extends Component {

: null} -

The app "{appManifest.name}" wants to

+

The app "{appManifest.name}" located at
+ {decodedToken.payload.domain_name}
+ wants to:

Read your basic info diff --git a/app/js/auth/store/auth.js b/app/js/auth/store/auth.js index 18bafc63d..9bb9fce0c 100644 --- a/app/js/auth/store/auth.js +++ b/app/js/auth/store/auth.js @@ -1,4 +1,5 @@ -import { getCoreSession, fetchAppManifest } from 'blockstack' +import { getCoreSession, + verifyAuthRequestAndLoadManifest as bskVerifyAuthRequestAndLoadManifest } from 'blockstack' import log4js from 'log4js' const logger = log4js.getLogger('auth/store/auth.js') @@ -78,13 +79,17 @@ function noCoreSessionToken(appDomain) { } } -function loadAppManifest(authRequest) { +function verifyAuthRequestAndLoadManifest(authRequest) { return dispatch => { dispatch(appManifestLoading()) - fetchAppManifest(authRequest).then(appManifest => { + bskVerifyAuthRequestAndLoadManifest(authRequest) + .then(appManifest => { dispatch(appManifestLoaded(appManifest)) + }, () => { + logger.error('verifyAuthRequestAndLoadManifest: invalid authentication request') + dispatch(appManifestLoadingError('Invalid authentication request.')) }).catch((e) => { - logger.error('loadAppManifest: error', e) + logger.error('verifyAuthRequestAndLoadManifest: error', e) dispatch(appManifestLoadingError(e)) }) } @@ -136,6 +141,6 @@ export const AuthActions = { clearSessionToken, getCoreSessionToken, noCoreSessionToken, - loadAppManifest, + verifyAuthRequestAndLoadManifest, loginToApp } diff --git a/app/js/data/apps.js b/app/js/data/apps.js index 4548c8b77..a70848b21 100644 --- a/app/js/data/apps.js +++ b/app/js/data/apps.js @@ -227,20 +227,6 @@ const apps = { developer: 'Satraj Bambra', status: 'user_ready_token', storageRequired: true - }, { - name: 'Cryptagon', - displayName: 'Cryptagon', - description: '', - version: '1.0.0', - appIcon: { - small: 'app-icon-cryptagon-256x256.png', - large: 'app-icon-cryptagon-512x512.png' - }, - website: 'http://app.cryptagon.io/', - launchLink: 'http://app.cryptagon.io/', - developer: 'Bernat Fortet Unanue', - status: 'user_ready_token', - storageRequired: true }, { name: 'CoinStack', displayName: 'CoinStack', diff --git a/app/js/profiles/AllProfilesPage.js b/app/js/profiles/AllProfilesPage.js index 178e300bc..6b7d40406 100644 --- a/app/js/profiles/AllProfilesPage.js +++ b/app/js/profiles/AllProfilesPage.js @@ -110,14 +110,17 @@ class AllProfilesPage extends Component { processing: true }) event.preventDefault() - const encryptedBackupPhrase = this.props.encryptedBackupPhrase - const password = this.state.password - const nextUnusedAddressIndex = this.props.nextUnusedAddressIndex - this.props.createNewProfile( - encryptedBackupPhrase, - password, nextUnusedAddressIndex - ) + if (!this.state.processing) { + const encryptedBackupPhrase = this.props.encryptedBackupPhrase + const password = this.state.password + const nextUnusedAddressIndex = this.props.nextUnusedAddressIndex + + this.props.createNewProfile( + encryptedBackupPhrase, + password, nextUnusedAddressIndex + ) + } } openPasswordPrompt(event) { @@ -181,6 +184,7 @@ class AllProfilesPage extends Component { - -