forked from nimiq/hub
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAddAddressLedger.vue
More file actions
134 lines (119 loc) · 4.98 KB
/
Copy pathAddAddressLedger.vue
File metadata and controls
134 lines (119 loc) · 4.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
<template>
<div class="container">
<SmallPage>
<transition name="transition-fade">
<LedgerUi v-if="state === constructor.State.LEDGER_INTERACTION"/>
</transition>
<transition name="transition-fade">
<IdenticonSelector v-if="state === constructor.State.IDENTICON_SELECTION
|| state === constructor.State.FINISHED"
:accounts="addressesToSelectFrom"
confirmButtonText="Add to Ledger"
@identicon-selected="_onAddressSelected">
<PageHeader slot="header">Choose a new Address</PageHeader>
</IdenticonSelector>
</transition>
<StatusScreen v-if="state === constructor.State.FINISHED" state="success" title="Address Added"
class="grow-from-bottom-button">
</StatusScreen>
</SmallPage>
<button class="global-close nq-button-s" @click="close">
<ArrowLeftSmallIcon/>
Back to {{request.appName}}
</button>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import { PageBody, SmallPage, PageHeader, ArrowLeftSmallIcon } from '@nimiq/vue-components';
import LedgerUi from '../components/LedgerUi.vue';
import StatusScreen from '../components/StatusScreen.vue';
import IdenticonSelector from '../components/IdenticonSelector.vue';
import { Static } from '../lib/StaticStore';
import { ParsedSimpleRequest } from '../lib/RequestTypes';
import { Address } from '../lib/PublicRequestTypes';
import { WalletInfo } from '../lib/WalletInfo';
import { AccountInfo } from '../lib/AccountInfo';
import LedgerApi from '../lib/LedgerApi';
import { WalletStore } from '../lib/WalletStore';
import { ACCOUNT_MAX_ALLOWED_ADDRESS_GAP, ERROR_CANCELED } from '../lib/Constants';
import LabelingMachine from '../lib/LabelingMachine';
@Component({components: {
PageBody,
SmallPage,
PageHeader,
LedgerUi,
StatusScreen,
IdenticonSelector,
ArrowLeftSmallIcon,
}})
export default class AddAddressLedger extends Vue {
private static readonly State = {
LEDGER_INTERACTION: 'ledger-interaction', // can be instructions to connect or also display of an error
IDENTICON_SELECTION: 'identicon-selection',
FINISHED: 'finished',
};
@Static private request!: ParsedSimpleRequest;
private state: string = AddAddressLedger.State.LEDGER_INTERACTION;
private account!: WalletInfo;
private addressesToSelectFrom: AccountInfo[] = [];
private async created() {
// called every time the router shows this page
const account = (await WalletStore.Instance.get(this.request.walletId))!;
this.account = account;
let startIndex = 0;
const newestAddress = Array.from(account.accounts.values()).pop();
if (newestAddress) {
const newestIndex = LedgerApi.getKeyIdForBip32Path(newestAddress.path);
startIndex = (newestIndex !== null ? newestIndex : -1) + 1;
}
const pathsToDerive = [];
for (let keyId = startIndex; keyId < startIndex + ACCOUNT_MAX_ALLOWED_ADDRESS_GAP; ++keyId) {
pathsToDerive.push(LedgerApi.getBip32PathForKeyId(keyId));
}
const derivedAddressInfos = await LedgerApi.deriveAccounts(pathsToDerive, this.account.keyId);
this.addressesToSelectFrom = derivedAddressInfos.map((addressInfo) => new AccountInfo(
addressInfo.keyPath,
LabelingMachine.labelAddress(addressInfo.address),
Nimiq.Address.fromUserFriendlyAddress(addressInfo.address),
0, // balance 0 because user selects from unused addresses
));
this.state = AddAddressLedger.State.IDENTICON_SELECTION;
}
private destroyed() {
const currentRequest = LedgerApi.currentRequest;
if (currentRequest && currentRequest.type === LedgerApi.RequestType.DERIVE_ACCOUNTS) {
currentRequest.cancel();
}
}
private async _onAddressSelected(selectedAccount: AccountInfo) {
const userFriendlyAddress = selectedAccount.userFriendlyAddress;
this.account.accounts.set(userFriendlyAddress, selectedAccount);
await WalletStore.Instance.put(this.account);
this.state = AddAddressLedger.State.FINISHED;
await new Promise((resolve) => setTimeout(resolve, StatusScreen.SUCCESS_REDIRECT_DELAY));
const result: Address = {
address: userFriendlyAddress,
label: selectedAccount.label,
};
this.$rpc.resolve(result);
}
private close() {
this.$rpc.reject(new Error(ERROR_CANCELED));
}
}
</script>
<style scoped>
.small-page {
overflow: hidden;
position: relative;
}
.small-page > * {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 100%;
transition: opacity .4s;
}
</style>