NEM является ориентированной на общественность цифровой валютой второго поколения, основывающейся на принципах децентрализации, наличия равных возможностей, а также полной финансовой свободы.

Для обеспечения максимальной безопасности при хранении монет этой децентрализованной виртуальной валюты, имеющих название XEM, рекомендуется использовать следующие виртуальные кошельки:

  1. NCC Standalone;
  2. Nano Wallet;
  3. Android NEM Wallet.

Первый виртуальный кошелек представляет собой клиент, работающий автономно. Специалисты рекомендуют применять кошелек NCC Standalone в тех случаях, когда пользователь желает поднять полноценный узел или «суперноду». Для того чтобы установить кошелек и совершить его запуск, пользователь должен обладать минимальным набором знаний и навыками по применению терминала.

Вторая разновидность кошелька представляет собой небольшой клиент, занимающий сравнительно немного дискового пространства. При его установке пользователю не потребуется дополнительная инсталляция вспомогательного ПО или скачивание Blockchain. Все запросы в виртуальном кошельке Nano Wallet обрабатываются при помощи удаленных узлов. Этот виртуальный кошелек создан при помощи Angular JS.

Последний виртуальный кошелек предназначен для использования на гаджетах с операционной системой Android.

Отличительной особенностью кошелька NCC Standalone является наличие «Адресной книги», которую нельзя встретить в других видах виртуальных кошельков.

В этой статье мы рассмотрим способ создания модуля «Адресная книга» в виртуальном кошельке под названием Nano Wallet, обладающего такими функциями как: создание, удаление и внесение изменений в контакты, их сортировка, а также импорт и экспорт вышеуказанного модуля.

Первые действия

Наиболее часто задаваемым вопросом, с которым всегда встречается начинающий разработчик, ранее не занимавшийся написанием модулей для Nano Wallet, является вопрос, касающийся того, как следует начинать процесс написания.

В первую очередь разработчик должен проверить, имеется ли на его устройстве установленная платформа Node.js. В случае отсутствия таковой в системе, ее потребуется скачать и установить. Данная платформа будет необходима для сборки проекта.

Следующим шагом будет скачивание репозитория виртуального кошелька c официального сайта.

Для создания проекта разработчику потребуется открыть терминал и выполнить переход в главную папку проекта, после чего выполнить следующие команды:

<pre>

> npm install

> npm gulp

</pre>

После выполнения этих команд разработчик сможет приступить к процессу создания модуля.

Создание модуля «Адресной книги»

Модули Nano Wallet расположены по следующему адресу:

<pre>

NanoWallet/

src/

app/

modules/

</pre>

После перехода в этот каталог можно создать модуль. Для этого необходимо дать ему название. Наиболее простым и понятным будет название addressBook. Все модули Nano Wallet обладают следующей структурой:

<pre>

modules/

addressBook/

addressBook.config.js

addressBook.controller.js

index.js

addressBook.html

</pre>

В файле с настройками модуля под названием addressBook.config.js разработчик должен указать конфигурации «Адресной книги». Здесь он должен указать:

  • url – указывающий на url-адрес, предоставляющий доступ к модулю;
  • controller – название контроллера, использующегося для обслуживания «Адресной книги»;
  • controllerAs – альтернативное название контроллера;
  • templateUrl – адрес файла, внутри которого имеется представление модуля;
  • title – имя.

<pre>

AddressBookConfig($stateProvider) {

‘ngInject’;

$stateProvider

.state(‘app.addressBook’, {

url: ‘/address-book’,

controller: ‘AddressBookCtrl’,

controllerAs: ‘$ctrl’,

templateUrl: ‘modules/addressBook/addressBook.html’,

title: ‘Address book’

});

};

export default AddressBookConfig;

</pre>

В файле addressBook.controller.js разработчик программирует логику «Адресной книги».

Контроллер создаваемого модуля будет обладать рядом методов и основных функций, к числу которых относятся:

  • добавление контакта, осуществляемое при помощи команду addContact() или add();
  • внесение изменений в контакт, для которых используются команды editContact() или edit();
  • удаление из контакта из модуля при помощи команд removeContact() или remove();
  • сортировка списка контактов, осуществляемая при помощи команды sortBy();
  • импорт модуля, выполняемый при помощи команды importAddressBook();
  • экспорт модуля, осуществляемый за счет использования команды exportAddressBook().

<pre>

import helpers from ‘../../utils/helpers’;

import CryptoHelpers from ‘../../utils/CryptoHelpers’;

class AddressBookCtrl {

constructor($localStorage, DataBridge, Wallet, Alert, $location, $filter, $q, $rootScope) {

‘ngInject’;

this.contacts = this._storage.contacts;

}

sortBy(propertyName) { // code };

addContact() { // code }

add() { // code }

editContact(elem) { // code }

edit() { // code }

removeContact(elem) { // code }

remove() { // code }

saveAddressBook() { // code }

exportAddressBook() { // code }

uploadAddressBook() { // code }

importAddressBook($fileContent) { // code }

transferTransaction(address) { // code }

}

export default AddressBookCtrl;

</pre>

В файле под названием index.js разработчик модуля должен разработать модуль с заранее установленными настройками и контроллером.

<pre>

import angular from ‘angular’;

// Create the module where our functionality can attach to

let addressBookModule = angular.module(‘app.addressBook’, []);

// Include our UI-Router config settings

import AddressBookConfig from ‘./addressBook.config’;

addressBookModule.config(AddressBookConfig);

// Controllers

import AddressBookCtrl from ‘./addressBook.controller’;

addressBookModule.controller(‘AddressBookCtrl’, AddressBookCtrl);

export default addressBookModule;

</pre>

В файле adressBook.html выполняется html-разметка «Адресной книги». В первую очередь разработчик должен выполнить разметку меню, расположенного сбоку:

<pre>

<div class=»col-sm-3 sidebar» style=»margin-top: 10px;»>

<div class=»panel panel-default»>

<div class=»panel-heading» style=»background-color: rgb(68, 68, 68); color: white;border-radius: 0px;»>

<i class=»fa fa-chevron-right»></i>

<span>{{ ‘ADDRESS_BOOK_NAVIGATION’ | translate }}</span>

</div>

<div class=»panel-body»>

<ul class=»nav nav-pills nav-stacked»>

<li>

<button type=»button» class=»btn btn-operations» ng-click=»$ctrl.addContact()»>{{ ‘ADDRESS_BOOK_NEW’ | translate }}</button>

</li>

<li>

<button type=»button» ng-disabled=»!$ctrl.contacts.items.length» class=»btn btn-operations» ng-click=»$ctrl.exportAddressBook()»>{{ ‘ADDRESS_BOOK_EXPORT_BTN’ | translate }}</button>

<a id=»exportAddressBook» class=»hidden» target=»_blank»></a>

</li>

<li>

<button type=»button» class=»btn btn-operations» ng-click=»$ctrl.uploadAddressBook()»>{{ ‘ADDRESS_BOOK_IMPORT_BTN’ | translate }}</button>

<input id=»uploadAddressBook» accept=».adb» style=»visibility:hidden;position:absolute;» import-address-book-file=»$ctrl.importAddressBook($fileContent)» type=»file»>

</li>

</ul>

</div>

</div>

</div>

</pre>

Затем устанавливается разметка, необходимая для вывода списка контактов, а также для размещений кнопок, позволяющих управлять контактами:

<pre>

<div class=»col-sm-9 noPaddingLeft» style=»margin-top: 10px;»>

<div class=»panel panel-default»>

<div class=»panel-heading» style=»background-color: rgb(68, 68, 68); color: white;border-radius: 0px;»>

<i class=»fa fa-group»></i> {{ ‘ADDRESS_BOOK_LIST’ | translate }}

<div style=»float: right; position: relative; display: block;» ng-show=»$ctrl.contacts.items.length > $ctrl.pageSize»><button class=»buttonStyle» ng-disabled=»$ctrl.currentPage == 0″ ng-click=»$ctrl.currentPage = $ctrl.currentPage-1″ style=»background-color: transparent; border: medium none;»><span class=»fa fa-chevron-left» aria-hidden=»true»></span></button><b>{{$ctrl.currentPage+1}}/{{$ctrl.numberOfPages()}}</b><button class=»buttonStyle» ng-disabled=»$ctrl.currentPage+1 >= $ctrl.numberOfPages()» ng-click=»$ctrl.currentPage = $ctrl.currentPage+1″ style=»background-color: transparent; border: medium none;»> <span class=»fa fa-chevron-right» aria-hidden=»true»></span></button></div>

</div>

<table class=»table table-bordered table-hover table-striped table-condensed» style=»border:1px solid #444;table-layout:fixed;word-break:break-all;»>

<thead style=»color:white;»>

<tr>

<th style=»width: 20%;»>

<a href=»javascript:;» ng-click=»$ctrl.sortBy(‘label’)»>

<i class=»fa» ng-show=»$ctrl.propertyName === ‘label'» ng-class=»{‘fa-caret-down’: $ctrl.revers, ‘fa-caret-up’: !$ctrl.revers}»></i> {{ ‘ADDRESS_BOOK_CONTACT_LABEL’ | translate }}

</a>

</th>

<th>

<a href=»javascript:;» ng-click=»$ctrl.sortBy(‘address’)»>

<i class=»fa» ng-show=»$ctrl.propertyName === ‘address'» ng-class=»{‘fa-caret-down’: $ctrl.revers, ‘fa-caret-up’: !$ctrl.revers}»></i> {{ ‘ADDRESS_BOOK_ACCOUNT_ADDRESS’ | translate }}

</a>

</th>

<th style=»width: 200px;»>{{ ‘ADDRESS_BOOK_ACTIONS’ | translate }}</th>

</tr>

</thead>

<tbody style=»background-color:white;text-align:center»>

<tr ng-repeat=»contact in $ctrl.contacts.items | orderBy:$ctrl.propertyName:$ctrl.revers | startFrom:$ctrl.currentPage*$ctrl.pageSize | limitTo:$ctrl.pageSize»>

<td style=»vertical-align: middle;border-bottom: 1px solid #444″>{{contact.label}}</td>

<td style=»vertical-align: middle;border-bottom: 1px solid #444″>{{contact.address}}</td>

<td class=»actions» style=»vertical-align: middle;border-bottom: 1px solid #444;white-space:nowrap;»>

<button type=»button» class=»btn btn-xs» ng-click=»$ctrl.transferTransaction(contact.address)»>Send XEM</button>

<button type=»button» class=»btn btn-xs» ng-click=»$ctrl.editContact(contact)»>Edit</button>

<button type=»button» class=»btn btn-xs» ng-click=»$ctrl.removeContact(contact)»>Remove</button>

</td>

</tr>

</tbody>

</table>

<div class=»panel-body» ng-show=»!$ctrl.contacts.items.length» style=»border: 1px solid #444;»>

<p style=»margin:0;»>{{ ‘GENERAL_NO_RESULTS’ | translate }}</p>

</div>

<div class=»panel-footer text-center» style=»background-color: #e3e0cf; color: #444;padding:0;»>

<small><b><i>{{ ‘ADDRESS_BOOK_MAX_NUMBER’ | translate }} {{ $ctrl.pageSize }}</i></b></small>

</div>

</div>

</div>

</pre>

После этого разработчик модуля должен добавить специальные модальные окна, которые предоставляют возможность изменять, удалять и добавлять контакты:

<pre>

<!— Add new account modal —>

<div id=»contactModal» class=»modal fade» role=»dialog»>

<div class=»modal-dialog»>

<!— Modal content—>

<div class=»modal-content»>

<div class=»modal-header»>

<button type=»button» class=»close» data-dismiss=»modal»>×</button>

<h4 class=»modal-title» ng-show=»!$ctrl.is_edit»>{{ ‘ADDRESS_BOOK_NEW’ | translate }}</h4>

<h4 class=»modal-title» ng-show=»$ctrl.is_edit»>{{ ‘ADDRESS_BOOK_EDIT’ | translate }}</h4>

</div>

<div class=»modal-body»>

<fieldset class=»form-group»>

<input class=»form-control form-control-lg»

type=»password»

placeholder=»{{ ‘FORM_PASSWORD_FIELD_PLACEHOLDER’ | translate }}»

ng-model=»$ctrl.common.password»/>

</fieldset>

<fieldset class=»form-group»>

<input class=»form-control form-control-lg»

type=»text»

placeholder=»{{ ‘ADDRESS_BOOK_CONTACT_LABEL’ | translate }}»

ng-model=»$ctrl.formData.label»/>

</fieldset>

<fieldset class=»form-group»>

<input class=»form-control form-control-lg»

type=»text»

placeholder=»{{ ‘FORM_ADDRESS_FIELD_PLACEHOLDER’ | translate }}»

ng-model=»$ctrl.formData.address»/>

</fieldset>

<button class=»btn btn-success» style=»border-radius:0px;»

type=»submit» ng-show=»!$ctrl.is_edit» ng-disabled=»$ctrl.okPressed || !$ctrl.common.password.length || !$ctrl.formData.label || !$ctrl.formData.address» ng-click=»$ctrl.add()»>

<i class=»fa fa-plus»></i> {{ ‘ADDRESS_BOOK_NEW_BTN’ | translate }}

</button>

<button class=»btn btn-success» style=»border-radius:0px;»

type=»submit» ng-show=»$ctrl.is_edit» ng-disabled=»$ctrl.okPressed || !$ctrl.common.password.length || !$ctrl.formData.label || !$ctrl.formData.address» ng-click=»$ctrl.edit()»>

<i class=»fa fa-edit»></i> {{ ‘ADDRESS_BOOK_EDIT_BTN’ | translate }}

</button>

</div>

<div class=»modal-footer»>

<button type=»button» class=»btn btn-default» data-dismiss=»modal»>{{ ‘GENERAL_CLOSE’ | translate }}</button>

</div>

</div>

</div>

</div>

<!— Add new account modal —>

<div id=»removeContactModal» class=»modal fade» role=»dialog»>

<div class=»modal-dialog»>

<!— Modal content—>

<div class=»modal-content»>

<div class=»modal-header»>

<button type=»button» class=»close» data-dismiss=»modal»>×</button>

<h4 class=»modal-title»>{{ ‘ADDRESS_BOOK_REMOVE’ | translate }}</h4>

</div>

<div class=»modal-body»>

<fieldset class=»form-group»>

<input class=»form-control form-control-lg»

type=»password»

placeholder=»{{ ‘FORM_PASSWORD_FIELD_PLACEHOLDER’ | translate }}»

ng-model=»$ctrl.common.password»/>

</fieldset>

<button class=»btn btn-danger» style=»border-radius:0px;» type=»submit» ng-disabled=»$ctrl.okPressed || !$ctrl.common.password.length» ng-click=»$ctrl.remove()»>

<i class=»fa fa-remove»></i> {{ ‘ADDRESS_BOOK_REMOVE_BTN’ | translate }}

</button>

</div>

<div class=»modal-footer»>

<button type=»button» class=»btn btn-default» data-dismiss=»modal»>{{ ‘GENERAL_CLOSE’ | translate }}</button>

</div>

</div>

</div>

</div>

</pre>

После завершения написания этого кода потребуется написать стили для «Адресной книги». Главный css-код для виртуального кошелька расположен по следующему адресу:

<pre>

NanoWallet/

src/

css/

nano.css

</pre>

Стили для «Адресной книги»:

<pre>

.address-book-page .panel-default .panel-heading {

border-bottom: 3px solid #dfa82f;

}

.address-book-page .sidebar .nav li .btn-operations {

width: 100%;

border-top: 1px solid #444;

border-bottom: 1px solid #444;

border-radius: 0;

margin-top: 7px;

color: #444;

background-color: #e3e0cf;

}

.address-book-page .sidebar .nav li:first-child .btn-operations { margin-top: 0; }

.address-book-page .sidebar .nav li .btn-operations:hover { background-color: #dad6bf; }

.address-book-page .sidebar .nav li .btn-operations:focus { outline: none; }

.address-book-page .sidebar .panel-body { padding: 10px 0; }

.address-book-page table th a { color: #FFF; }

.address-book-page table th a:hover,

.address-book-page table th a:focus,

.address-book-page table th a:active { color: #FFF; text-decoration: none; }

.address-book-page table .actions .btn { border: 1px solid rgba(153, 153, 153, 0.52); background: #E3E0CF; }

.address-book-page table .actions .btn:hover,

.address-book-page table .actions .btn:focus,

#addressBookModal table .btn:hover,

#addressBookModal table .btn:focus {

background-color: #dad6bf !important;

text-decoration: none;

}

#addressBookModal .modal-body { padding: 0; }

#addressBookModal .modal-footer { background: #444; }

#addressBookModal .modal-footer .btn {

border-radius: 3px;

background-color: #FFF;

color: #333;

border: none;

}

#addressBookModal .modal-footer .custom-pagination { color: #FFF; margin-top: 5px; }

#addressBookModal .modal-footer .custom-pagination button { opacity: 1; transition: .3s ease opacity; }

#addressBookModal .modal-footer .custom-pagination button[disabled=»disabled»] { opacity: 0.3; }

#addressBookModal table th,

#addressBookModal table td { padding-left: 15px; padding-right: 15px; }

#addressBookModal table th:first-child,

#addressBookModal table td:first-child { border-right: 1px solid #DDDDDD; }

#addressBookModal table tr:first-child td { padding-top: 10px; }

#addressBookModal table tr:last-child td { padding-bottom: 15px; }

#addressBookModal table th { border-bottom: none; }

</pre>

Выполнив все вышеуказанные действия, разработчик завершил процесс создания модуля.

Следующим шагом будет импорт разработанного модуля непосредственно в приложение. Для этого необходимо открыть файл, расположенный по адресу:

<pre>

NanoWallet/

src/

app/

app.js

</pre>

Затем в этом файле необходимо написать следующее:

<pre>

<// Import our app modules

import ‘./modules/addressBook’;

// Create and bootstrap application

const requires = [

‘app.addressBook’

];

</pre>

На этом процесс создания модуля для Nano Wallet под названием «Адресная книга» можно считать завершенным.

ОСТАВЬТЕ ОТЗЫВ

Please enter your comment!
Please enter your name here