Skip to content

Commit

Permalink
Merge branch 'feat/ae-voting' into 'master'
Browse files Browse the repository at this point in the history
feat(ae): add voting

See merge request papers/airgap/airgap-wallet!134
  • Loading branch information
AndreasGassmann committed May 5, 2019
2 parents 3ab0507 + f625a4f commit cfe6160
Show file tree
Hide file tree
Showing 12 changed files with 248 additions and 13 deletions.
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
"@sentry/browser": "^4.2.4",
"@types/node": "8.0.31",
"@zxing/ngx-scanner": "^1.3.0",
"airgap-coin-lib": "0.3.10",
"airgap-coin-lib": "0.3.13",
"angular2-template-loader": "0.6.2",
"angularx-qrcode": "1.5.3",
"bignumber.js": "^8.0.0",
Expand Down
7 changes: 5 additions & 2 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ import { ProtocolSelectPage } from '../pages/protocol-select/protocol-select'
import { IntroductionPushPage } from '../pages/introduction-push/introduction-push'
import { PushProvider } from '../providers/push/push'
import { PushBackendProvider } from '../providers/push-backend/push-backend'
import { VotingPage } from '../pages/voting/voting'

export function createTranslateLoader(http: HttpClient) {
return new TranslateHttpLoader(http, './assets/i18n/', '.json')
Expand Down Expand Up @@ -106,7 +107,8 @@ export function createTranslateLoader(http: HttpClient) {
DelegationBakerDetailPage,
DisclaimerWebExtensionPage,
ProtocolSelectPage,
IntroductionPushPage
IntroductionPushPage,
VotingPage
],
imports: [
BrowserModule,
Expand Down Expand Up @@ -167,7 +169,8 @@ export function createTranslateLoader(http: HttpClient) {
SubAccountSelectPage,
DisclaimerWebExtensionPage,
ProtocolSelectPage,
IntroductionPushPage
IntroductionPushPage,
VotingPage
],
providers: [
StatusBar,
Expand Down
15 changes: 15 additions & 0 deletions src/assets/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"import-accounts_label": "Import Accounts",
"delegate_label": "Delegate",
"undelegate_label": "Undelegate",
"vote_label": "Voting",
"delegation-status_label": "Delegation",
"pending-transactions": {
"label": "Pending Transactions",
Expand Down Expand Up @@ -219,6 +220,7 @@
"amount_label": "Amount",
"fee_label": "Fee",
"time_label": "Time",
"data_label": "Data",
"from_label": "From",
"to_label": "To"
},
Expand Down Expand Up @@ -361,5 +363,18 @@
"heading": "You can receive push notifications if your accounts receive transactions.",
"description": "First you have to grant AirGap Wallet the push notification permission.",
"grant-permission_label": "Grant Permission"
},
"voting": {
"title": "Voting",
"heading": "Block Reward Initiative (BRI)",
"text": "To transform aeternity into a self-sustaining platform, we propose the Block Reward Initiative (BRI), through which ~0-20% of miner rewards will be allocated to development.",
"your-vote_label": "Your vote: {{ votePercentage }}%",
"further-information": {
"heading": "Further Information",
"blog-post_label": "Detailed Explanation in Blog Post",
"forum_label": "Community Discussion in Forum",
"result_label": "To check your vote, please visit <a href=\"https://aeternity.com\"> the official voting page</a>"
},
"vote_label": "Vote"
}
}
1 change: 1 addition & 0 deletions src/assets/img/vote.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions src/components/from-to/from-to.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@
{{ transaction.timestamp | amFromUnix | amCalendar: { sameDay: '[Today at] HH:mm', sameElse: 'HH:mm [on] LL' } }}
</div>
</ng-container>

<ng-container *ngIf="transaction.data">
<ion-label stacked class="typography--uppercase">{{ 'from-to.data_label' | translate }}</ion-label>
<div item-content>
{{ transaction.data }}
</div>
</ng-container>
</ion-col>
</ion-row>

Expand Down
22 changes: 22 additions & 0 deletions src/pages/account-transaction-list/account-transaction-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { OperationsProvider, ActionType } from '../../providers/operations/opera
import { SubAccountAddPage } from '../sub-account-add/sub-account-add'
import { SubProtocolType } from 'airgap-coin-lib/dist/protocols/ICoinSubProtocol'
import { ProtocolSymbols } from '../../providers/protocols/protocols'
import { VotingPage } from '../voting/voting'

interface CoinAction {
type: ActionType
Expand Down Expand Up @@ -103,6 +104,8 @@ export class AccountTransactionListPage {
this.actions.push(this.getAddTokenAction())
} else if (action === ActionType.DELEGATE) {
this.actions.push(this.getDelegateAction())
} else if (action === ActionType.VOTE) {
this.actions.push(this.getVoteAction())
} else {
const assertNever = (x: never) => undefined
assertNever(action)
Expand Down Expand Up @@ -170,6 +173,17 @@ export class AccountTransactionListPage {
}
}

private getVoteAction(): CoinAction {
return {
type: ActionType.VOTE,
name: 'account-transaction-list.vote_label',
icon: 'archive',
action: async () => {
this.openVotePage()
}
}
}

private getStatusAction(ktAddresses?: string[]): CoinAction {
return {
type: ActionType.DELEGATE,
Expand Down Expand Up @@ -399,6 +413,14 @@ export class AccountTransactionListPage {
.catch(handleErrorSentry(ErrorCategory.NAVIGATION))
}

openVotePage() {
this.navCtrl
.push(VotingPage, {
wallet: this.wallet
})
.catch(handleErrorSentry(ErrorCategory.NAVIGATION))
}

openAccountAddPage(subProtocolType: SubProtocolType, wallet: AirGapMarketWallet) {
this.navCtrl
.push(SubAccountAddPage, { subProtocolType: subProtocolType, wallet: wallet })
Expand Down
66 changes: 66 additions & 0 deletions src/pages/voting/voting.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<ion-header no-border no-shadow>
<ion-navbar color="whiteSecondaryContrast">
<ion-title>{{ 'voting.title' | translate }}</ion-title>
</ion-navbar>
</ion-header>

<ion-content padding>
<h3 no-margin>{{ 'voting.heading' | translate }}</h3>

<p *ngIf="config" no-margin padding-bottom>
Vote from
<strong>
{{ config?.startDate | amFromUnix | date: 'longDate' }}
</strong>
to
<strong>
{{ config?.endDate | amFromUnix | date: 'longDate' }}
</strong>
</p>

<ion-row justify-content-center>
<img src="../assets/img/vote.svg" />
</ion-row>
<p>
{{ 'voting.text' | translate }}
</p>

<p *ngIf="config?.showSelfVoted && oldVotePercentage && oldVoteTimestamp">
<strong>Your last vote: {{ oldVotePercentage }}% on {{ oldVoteTimestamp | amFromUnix | date: 'longDate' }}</strong>
</p>

<ion-range [disabled]="!config?.enabled" min="0" max="20" [(ngModel)]="votePercentage" [snaps]="true" [pin]="true" no-padding>
<ion-label range-left>0%</ion-label>
<ion-label range-right>20%</ion-label>
</ion-range>
<p>
<strong
*ngIf="config?.enabled && votePercentage > 0"
[innerHTML]="'voting.your-vote_label' | translate: { votePercentage: votePercentage }"
></strong>
<strong *ngIf="config?.enabled && votePercentage === 0">I am NOT supporting the BRI</strong>
<strong *ngIf="!config?.enabled">Voting is currently disabled</strong>
</p>

<h6 padding-top margin-bottom>{{ 'voting.further-information.heading' | translate }}</h6>
<p>
<a href="#" (click)="openUrl('https://blog.aeternity.com/aeternity-first-on-chain-governance-vote-decentralization-2-0-5e0c8a01891a')">
{{ 'voting.further-information.blog-post_label' | translate }}
<ion-icon md-name="open_in_new"></ion-icon>
</a>
<br />
<a
href="#"
(click)="openUrl('https://forum.aeternity.com/t/discussion-block-reward-initiative-and-first-on-chain-governance-vote/3278')"
>
{{ 'voting.further-information.forum_label' | translate }}
<ion-icon md-name="open_in_new"></ion-icon>
</a>
</p>

<ion-fab right bottom>
<button round ion-button color="primary" [disabled]="!config?.enabled" (click)="vote()">
{{ 'voting.vote_label' | translate }}
</button>
</ion-fab>
</ion-content>
8 changes: 8 additions & 0 deletions src/pages/voting/voting.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
page-voting {
img {
height: 40vh;
}
ion-icon {
vertical-align: middle;
}
}
87 changes: 87 additions & 0 deletions src/pages/voting/voting.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { Component } from '@angular/core'
import { NavController, NavParams, Platform } from 'ionic-angular'
import BigNumber from 'bignumber.js'
import { InteractionSelectionPage } from '../interaction-selection/interaction-selection'
import { AirGapMarketWallet, IAirGapTransaction } from 'airgap-coin-lib'
import { handleErrorSentry, ErrorCategory } from '../../providers/sentry-error-handler/sentry-error-handler'
import { OperationsProvider } from '../../providers/operations/operations'
import { RemoteConfigProvider, AeFirstVote } from '../../providers/remote-config/remote-config'

declare let cordova

@Component({
selector: 'page-voting',
templateUrl: 'voting.html'
})
export class VotingPage {
public oldVotePercentage: number
public oldVoteTimestamp: number
public config: AeFirstVote
public wallet: AirGapMarketWallet

public votePercentage: number = 10
public votingAddress: string = 'ak_11111111111111111111111111111111273Yts'

constructor(
public navCtrl: NavController,
public navParams: NavParams,
private operationsProvider: OperationsProvider,
private remoteConfigProvider: RemoteConfigProvider,
private platform: Platform
) {
this.wallet = this.navParams.get('wallet')
}

ngOnInit() {
this.remoteConfigProvider.aeFirstVote().then(config => (this.config = config))

this.wallet
.fetchTransactions(1000, 0)
.then(txs => {
const oldVote = txs.find(tx => !!tx.data)
console.log(oldVote)
if (oldVote) {
try {
console.log(JSON.parse(oldVote.data))
this.oldVotePercentage = JSON.parse(oldVote.data).vote.option
this.oldVoteTimestamp = oldVote.timestamp
} catch (error) {
console.log(error)
}
}
})
.catch(console.log)
}

public openUrl(url: string) {
if (this.platform.is('ios') || this.platform.is('android')) {
cordova.InAppBrowser.open(url, '_system', 'location=true')
} else {
window.open(url, '_blank')
}
}

public async vote() {
try {
const { airGapTx, serializedTx } = await this.operationsProvider.prepareTransaction(
this.wallet,
this.votingAddress,
new BigNumber(0),
new BigNumber(17240000000000),
JSON.stringify({
vote: { id: 1, option: Math.round(this.votePercentage) }
})
)

this.navCtrl
.push(InteractionSelectionPage, {
wallet: this.wallet,
airGapTx: airGapTx,
data: 'airgap-vault://?d=' + serializedTx
})
.catch(handleErrorSentry(ErrorCategory.NAVIGATION))
} catch (error) {
//
}
}
}
10 changes: 7 additions & 3 deletions src/providers/operations/operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ import { ProtocolSymbols } from '../protocols/protocols'
export enum ActionType {
IMPORT_ACCOUNT,
ADD_TOKEN,
DELEGATE
DELEGATE,
VOTE
}

@Injectable()
Expand Down Expand Up @@ -117,13 +118,14 @@ export class OperationsProvider {
wallet: AirGapMarketWallet,
address: string,
amount: BigNumber,
fee: BigNumber
fee: BigNumber,
data?: any
): Promise<{ airGapTx: IAirGapTransaction; serializedTx: string }> {
const loader = await this.getAndShowLoader()

try {
// TODO: This is an UnsignedTransaction, not an IAirGapTransaction
const rawUnsignedTx: any = await wallet.prepareTransaction([address], [amount], fee)
const rawUnsignedTx: any = await wallet.prepareTransaction([address], [amount], fee, data)

const airGapTx = await wallet.coinProtocol.getTransactionDetails({
publicKey: wallet.publicKey,
Expand Down Expand Up @@ -218,6 +220,8 @@ export class OperationsProvider {
return [ActionType.IMPORT_ACCOUNT, ActionType.DELEGATE]
} else if (identifier === ProtocolSymbols.XTZ_KT) {
return [ActionType.DELEGATE]
} else if (identifier === ProtocolSymbols.AE) {
return [ActionType.VOTE]
} else {
return []
}
Expand Down
Loading

0 comments on commit cfe6160

Please sign in to comment.