From 98eec9d1d6e5f656daf4df62891469dbdfda8f41 Mon Sep 17 00:00:00 2001 From: Devin Alexander Torres Date: Sun, 31 Dec 2017 00:43:16 -0600 Subject: [PATCH] feat(setup): Start setup routes --- app/components/wallet-import/component.js | 10 ++++++ app/components/wallet-import/template.hbs | 3 ++ app/router.js | 4 +++ app/rpc/service.js | 4 +-- app/setup/import/route.js | 31 +++++++++++++++++++ app/setup/import/template.hbs | 12 +++++++ app/setup/index/route.js | 16 ++++++++++ app/setup/index/template.hbs | 1 + app/setup/route.js | 16 ++++++++++ app/setup/template.hbs | 12 +++++++ app/validations/import-wallet.js | 5 +++ app/validators/seed.js | 5 +++ public/Cairn.svg | 16 +++++----- .../wallet-import/component-test.js | 25 +++++++++++++++ tests/unit/setup/import/route-test.js | 16 ++++++++++ tests/unit/setup/index/route-test.js | 16 ++++++++++ tests/unit/setup/route-test.js | 16 ++++++++++ tests/unit/validators/seed-test.js | 8 +++++ 18 files changed, 206 insertions(+), 10 deletions(-) create mode 100644 app/components/wallet-import/component.js create mode 100644 app/components/wallet-import/template.hbs create mode 100644 app/setup/import/route.js create mode 100644 app/setup/import/template.hbs create mode 100644 app/setup/index/route.js create mode 100644 app/setup/index/template.hbs create mode 100644 app/setup/route.js create mode 100644 app/setup/template.hbs create mode 100644 app/validations/import-wallet.js create mode 100644 app/validators/seed.js create mode 100644 tests/integration/components/wallet-import/component-test.js create mode 100644 tests/unit/setup/import/route-test.js create mode 100644 tests/unit/setup/index/route-test.js create mode 100644 tests/unit/setup/route-test.js create mode 100644 tests/unit/validators/seed-test.js diff --git a/app/components/wallet-import/component.js b/app/components/wallet-import/component.js new file mode 100644 index 00000000..a693a5d4 --- /dev/null +++ b/app/components/wallet-import/component.js @@ -0,0 +1,10 @@ +import Component from '@ember/component'; + +import ImportWalletValidations from '../../validations/import-wallet'; + +export default Component.extend({ + ImportWalletValidations, + + wallet: null, + seed: null, +}); diff --git a/app/components/wallet-import/template.hbs b/app/components/wallet-import/template.hbs new file mode 100644 index 00000000..be3cc8c3 --- /dev/null +++ b/app/components/wallet-import/template.hbs @@ -0,0 +1,3 @@ +{{#bs-form model=(changeset (hash seed=seed) ImportWalletValidations) onSubmit=(action onSubmit wallet) as |form|}} + {{form.element class="form-control-lg" controlType="text" label="Seed" property="seed" autocomplete='off' minlength=64 maxlength=64 required=true pattern="^[a-fA-F0-9]{64}$"}} +{{/bs-form}} diff --git a/app/router.js b/app/router.js index 7e21ccfb..c53a7142 100644 --- a/app/router.js +++ b/app/router.js @@ -7,6 +7,10 @@ const Router = EmberRouter.extend({ }); Router.map(function routerMap() { + this.route('setup', function setupRoute() { + this.route('import'); + }); + return this.route('wallets', { path: '/:wallet_id' }, function walletsRoute() { this.route('overview'); this.route('send'); diff --git a/app/rpc/service.js b/app/rpc/service.js index 600d178e..3b8128ad 100644 --- a/app/rpc/service.js +++ b/app/rpc/service.js @@ -33,8 +33,8 @@ export default Service.extend({ return this.call(actions.WALLET_BALANCE_TOTAL, { wallet }); }, - async walletChangeSeed() { - const { success } = this.call(actions.WALLET_CHANGE_SEED); + async walletChangeSeed(wallet, seed) { + const { success } = await this.call(actions.WALLET_CHANGE_SEED, { wallet, seed }); return success === ''; }, diff --git a/app/setup/import/route.js b/app/setup/import/route.js new file mode 100644 index 00000000..bfad415a --- /dev/null +++ b/app/setup/import/route.js @@ -0,0 +1,31 @@ +import Route from '@ember/routing/route'; +import { get } from '@ember/object'; + +import { service } from 'ember-decorators/service'; +import { action } from 'ember-decorators/object'; + +export default Route.extend({ + @service rpc: null, + + model() { + return this.store.createRecord('wallet'); + }, + + @action + saveWallet(wallet) { + return wallet.save(); + }, + + @action + changeSeed(wallet, changeset) { + const rpc = this.get('rpc'); + const seed = get(changeset, 'seed'); + const model = rpc.walletChangeSeed(get(wallet, 'id'), seed).then(() => wallet); + return this.transitionTo('wallets', model); + }, + + @action + cancel() { + return this.transitionTo('setup'); + }, +}); diff --git a/app/setup/import/template.hbs b/app/setup/import/template.hbs new file mode 100644 index 00000000..fc11fc07 --- /dev/null +++ b/app/setup/import/template.hbs @@ -0,0 +1,12 @@ +{{#bs-modal onHide=(route-action 'cancel') as |modal|}} + {{#modal.header}} + + {{/modal.header}} + {{#modal.body}} + {{wallet-import wallet=model onSubmit=(action (queue (route-action 'saveWallet') (route-action 'changeSeed')))}} + {{/modal.body}} + {{#modal.footer as |footer|}} + {{#bs-button onClick=(action modal.close) type="danger"}}Cancel{{/bs-button}} + {{#bs-button onClick=(action modal.submit) type="success"}}Import{{/bs-button}} + {{/modal.footer}} +{{/bs-modal}} diff --git a/app/setup/index/route.js b/app/setup/index/route.js new file mode 100644 index 00000000..7c1495c4 --- /dev/null +++ b/app/setup/index/route.js @@ -0,0 +1,16 @@ +import Route from '@ember/routing/route'; + +import { action } from 'ember-decorators/object'; + +export default Route.extend({ + @action + createWallet() { + const wallet = this.store.createRecord('wallet'); + return this.transitionTo('wallets', wallet.save()); + }, + + @action + importWallet() { + return this.transitionTo('setup.import'); + }, +}); diff --git a/app/setup/index/template.hbs b/app/setup/index/template.hbs new file mode 100644 index 00000000..e2147cab --- /dev/null +++ b/app/setup/index/template.hbs @@ -0,0 +1 @@ +{{outlet}} \ No newline at end of file diff --git a/app/setup/route.js b/app/setup/route.js new file mode 100644 index 00000000..7c1495c4 --- /dev/null +++ b/app/setup/route.js @@ -0,0 +1,16 @@ +import Route from '@ember/routing/route'; + +import { action } from 'ember-decorators/object'; + +export default Route.extend({ + @action + createWallet() { + const wallet = this.store.createRecord('wallet'); + return this.transitionTo('wallets', wallet.save()); + }, + + @action + importWallet() { + return this.transitionTo('setup.import'); + }, +}); diff --git a/app/setup/template.hbs b/app/setup/template.hbs new file mode 100644 index 00000000..6fd970ac --- /dev/null +++ b/app/setup/template.hbs @@ -0,0 +1,12 @@ +{{outlet}} + +
+

Welcome!

+

Let's get your wallet setup for use with Cairn.

+
+

To begin using Cairn, you must first create a new RaiBlocks wallet or import a wallet that already exists from a seed.

+

+ Create New Wallet + Import from Seed +

+
diff --git a/app/validations/import-wallet.js b/app/validations/import-wallet.js new file mode 100644 index 00000000..cfc4a575 --- /dev/null +++ b/app/validations/import-wallet.js @@ -0,0 +1,5 @@ +import validateSeed from '../validators/seed'; + +export default { + seed: validateSeed(), +}; diff --git a/app/validators/seed.js b/app/validators/seed.js new file mode 100644 index 00000000..e0c23629 --- /dev/null +++ b/app/validators/seed.js @@ -0,0 +1,5 @@ +import { validateFormat } from 'ember-changeset-validations/validators'; + +export default function validateSeed() { + return validateFormat({ regex: /^[a-fA-F0-9]{64}$/ }); +} diff --git a/public/Cairn.svg b/public/Cairn.svg index c53d5bd2..5a852a23 100644 --- a/public/Cairn.svg +++ b/public/Cairn.svg @@ -1,19 +1,19 @@ - + Cairn-white Created with Sketch. - + - - - - - - + + + + + + diff --git a/tests/integration/components/wallet-import/component-test.js b/tests/integration/components/wallet-import/component-test.js new file mode 100644 index 00000000..8c917ac1 --- /dev/null +++ b/tests/integration/components/wallet-import/component-test.js @@ -0,0 +1,25 @@ +import { expect } from 'chai'; +import { describeComponent, it } from 'ember-mocha'; +import hbs from 'htmlbars-inline-precompile'; + +describeComponent( + 'wallet-import', 'Integration | Component | wallet import', + { + integration: true, + }, + () => { + it('renders', function () { + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... }); + // Template block usage: + // this.render(hbs` + // {{#wallet-import}} + // template content + // {{/wallet-import}} + // `); + + this.render(hbs`{{wallet-import}}`); + expect(this.$()).to.have.length(1); + }); + }, +); diff --git a/tests/unit/setup/import/route-test.js b/tests/unit/setup/import/route-test.js new file mode 100644 index 00000000..c0dc308a --- /dev/null +++ b/tests/unit/setup/import/route-test.js @@ -0,0 +1,16 @@ +import { expect } from 'chai'; +import { describeModule, it } from 'ember-mocha'; + +describeModule( + 'route:setup/import', 'Unit | Route | setup/import', + { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] + }, + () => { + it('exists', function () { + const route = this.subject(); + expect(route).to.be.ok; + }); + }, +); diff --git a/tests/unit/setup/index/route-test.js b/tests/unit/setup/index/route-test.js new file mode 100644 index 00000000..ead4bf36 --- /dev/null +++ b/tests/unit/setup/index/route-test.js @@ -0,0 +1,16 @@ +import { expect } from 'chai'; +import { describeModule, it } from 'ember-mocha'; + +describeModule( + 'route:setup/index', 'Unit | Route | setup/index', + { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] + }, + () => { + it('exists', function () { + const route = this.subject(); + expect(route).to.be.ok; + }); + }, +); diff --git a/tests/unit/setup/route-test.js b/tests/unit/setup/route-test.js new file mode 100644 index 00000000..30b1e7ba --- /dev/null +++ b/tests/unit/setup/route-test.js @@ -0,0 +1,16 @@ +import { expect } from 'chai'; +import { describeModule, it } from 'ember-mocha'; + +describeModule( + 'route:setup', 'Unit | Route | setup', + { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] + }, + () => { + it('exists', function () { + const route = this.subject(); + expect(route).to.be.ok; + }); + }, +); diff --git a/tests/unit/validators/seed-test.js b/tests/unit/validators/seed-test.js new file mode 100644 index 00000000..4974ca50 --- /dev/null +++ b/tests/unit/validators/seed-test.js @@ -0,0 +1,8 @@ +import { module, test } from 'qunit'; +import validateSeed from 'cairn/validators/seed'; + +module('Unit | Validator | seed'); + +test('it exists', (assert) => { + assert.ok(validateSeed()); +});