Skip to content

Commit

Permalink
Merge pull request #394 from Adamant-im/stage
Browse files Browse the repository at this point in the history
v2.7.0
  • Loading branch information
adamant-al authored Jul 14, 2020
2 parents 38f63de + b94c624 commit a99b736
Show file tree
Hide file tree
Showing 13 changed files with 409 additions and 22 deletions.
13 changes: 5 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,13 @@

It is a messaging application client for ADAMANT Blockchain. See ADAMANT Project at https://adamant.im.

ADAMANT is the most secure and anonymous messenger, encrypted with Blockchain.
ADAMANT is a decentralized anonymous messenger based on the blockchain system. It’s independent of any governments or corporations, and even developers due to the distributed network infrastructure that contains an open-source code.

Highlights:
The ADAMANT blockchain system belongs to its users. Nobody can control, block, deactivate, restrict or censor accounts. Users take full responsibility for their content, messages, media, and goals and intentions of using the messenger.

- The most secure and anonymous messenger (see comparison table on the Website)
- Trusted. Open-source project.
- Bran new Fair dPoS consensus
- The only one which is Blockchain-powered
- Integrated crypto transfers
- Get welcome amount of ADM tokens for free messaging now
Privacy is the main concept of ADAMANT: neither phone numbers nor emails are required. Apps have no access to the contact list or geotags, IPs are hidden from chatters and paranoids can use [ADAMANT via Tor](http://adamantmsg72ixni.onion/).

All the messages are encrypted with the Diffie-Hellman Curve25519, Salsa20, Poly1305 algorithms and signed by SHA-256 + Ed25519 EdDSA. Private keys are never transferred to the network. The sequence of messages and their authenticity is guaranteed by the blockchain.

This application deployed at [msg.adamant.im](https://msg.adamant.im/). Feel free to run your own messenger using this code and Build Setup.

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "adamant-im",
"version": "2.6.0",
"version": "2.7.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
Expand Down
2 changes: 2 additions & 0 deletions src/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ const path = require('path')
let win

// Standard scheme must be registered before the app is ready
// before (<= v4.x):
protocol.registerStandardSchemes(['app'], { secure: true })

function createWindow () {
// Create the browser window.
win = new BrowserWindow({ width: 800, height: 800, "max-width": 800, icon: path.join(__dirname, '/icon.png') })
Expand Down
20 changes: 14 additions & 6 deletions src/components/Chat/Chat.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<template>
<v-card class="chat">
<free-tokens-dialog v-model="showFreeTokensDialog" />
<a-chat
:messages="messages"
:partners="partners"
Expand Down Expand Up @@ -122,6 +123,7 @@ import transaction from '@/mixins/transaction'
import partnerName from '@/mixins/partnerName'
import dateFilter from '@/filters/date'
import CryptoIcon from '@/components/icons/CryptoIcon'
import FreeTokensDialog from '@/components/FreeTokensDialog'
/**
* Returns user meta by userId.
Expand Down Expand Up @@ -155,9 +157,13 @@ function validateMessage (message) {
}
if (this.$store.state.balance < 0.001) {
this.$store.dispatch('snackbar/show', {
message: this.$t('chats.no_money')
})
if (Object.keys(this.$store.state.adm.transactions).length) {
this.$store.dispatch('snackbar/show', {
message: this.$t('chats.no_money')
})
} else {
this.showFreeTokensDialog = true
}
return false
}
Expand Down Expand Up @@ -248,7 +254,8 @@ export default {
chatFormLabel: '',
loading: false,
isScrolledToBottom: true,
visibilityId: null
visibilityId: null,
showFreeTokensDialog: false
}),
methods: {
onMessage (message) {
Expand Down Expand Up @@ -348,7 +355,7 @@ export default {
})
},
onKeyPress (e) {
if (e.code === 'Enter') this.$refs.chatForm.focus()
if (e.code === 'Enter' && !this.showFreeTokensDialog) this.$refs.chatForm.focus()
}
},
filters: {
Expand All @@ -363,7 +370,8 @@ export default {
ChatToolbar,
ChatAvatar,
ChatMenu,
CryptoIcon
CryptoIcon,
FreeTokensDialog
},
props: {
messageText: {
Expand Down
204 changes: 204 additions & 0 deletions src/components/ExportKeysForm.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
<template>
<v-form @submit.prevent="revealKeys">
<div v-if="keys.length" :class="`${className}__keys`">
<div
v-for="key in keys"
:key="key.crypto"
>
<v-text-field
v-model="key.key"
:readonly="true"
class="a-input"
type="text"
>
<template slot="label">
<span class="font-weight-medium">
{{ key.cryptoName }}
</span>
</template>
<template slot="append">
<v-btn icon ripple :class="`${className}__btn-copy`" @click="copyKey(key.key)">
<v-icon :class="`${className}__icon`" size="20">mdi-content-copy</v-icon>
</v-btn>
</template>
</v-text-field>
</div>

<div class="text-xs-right">
<v-btn
:class="`${className}__copy_all_button`"
@click="copyAll"
class="a-btn-link" flat small
>
{{ $t('options.export_keys.copy_all') }}
</v-btn>
</div>

</div>

<div :class="`${className}__disclaimer a-text-regular-enlarged`">
{{ $t("options.export_keys.disclaimer") }}
</div>

<v-text-field
v-model.trim="passphrase"
class="a-input"
type="text"
>
<template slot="label">
<span class="font-weight-medium">
{{ $t('options.export_keys.passphrase') }}
</span>
</template>
<template slot="append">
<v-menu :offset-overflow="true" :offset-y="false" left>
<v-icon slot="activator">mdi-dots-vertical</v-icon>
<v-list>
<v-list-tile @click="showQrcodeScanner = true">
<v-list-tile-title>{{ $t('transfer.decode_from_camera') }}</v-list-tile-title>
</v-list-tile>
<v-list-tile class="v-list__tile--link">
<v-list-tile-title>
<qrcode-capture @detect="onDetectQrcode" @error="onDetectQrcodeError">
<span>{{ $t('transfer.decode_from_image') }}</span>
</qrcode-capture>
</v-list-tile-title>
</v-list-tile>
</v-list>
</v-menu>
</template>
</v-text-field>

<div class="text-xs-center">
<v-btn
:class="`${className}__export_keys_button`"
@click="revealKeys"
class="a-btn-primary"
>
{{ $t('options.export_keys.button') }}
</v-btn>
</div>

<qrcode-scanner-dialog
@scan="onScanQrcode"
v-if="showQrcodeScanner"
v-model="showQrcodeScanner"
/>
</v-form>
</template>
<script>
import { validateMnemonic } from 'bip39'
import { getAccountFromPassphrase as getEthAccount } from '@/lib/eth-utils'
import { getAccount as getBtcAccount } from '@/lib/bitcoin/btc-base-api'
import { Cryptos, CryptosNames } from '@/lib/constants'
import { copyToClipboard } from '@/lib/textHelpers'
import QrcodeCapture from '@/components/QrcodeCapture'
import QrcodeScannerDialog from '@/components/QrcodeScannerDialog'
function getBtcKey (crypto, passphrase, asWif) {
const keyPair = getBtcAccount(crypto, passphrase).keyPair
const key = asWif
? keyPair.toWIF()
: keyPair.privateKey.toString('hex')
return {
crypto: crypto,
cryptoName: CryptosNames[crypto],
key
}
}
export default {
components: {
QrcodeCapture,
QrcodeScannerDialog
},
data () {
return {
passphrase: '',
showQrcodeScanner: false,
keys: []
}
},
computed: {
className: () => 'export-keys-form'
},
methods: {
onDetectQrcode (passphrase) {
this.onScanQrcode(passphrase)
},
onDetectQrcodeError (error) {
this.cryptoAddress = ''
this.$store.dispatch('snackbar/show', {
message: this.$t('transfer.invalid_qr_code')
})
console.warn(error)
},
onScanQrcode (pass) {
this.passphrase = pass
this.revealKeys()
},
revealKeys () {
this.keys = []
if (!validateMnemonic(this.passphrase)) {
this.$store.dispatch('snackbar/show', {
message: this.$t('login.invalid_passphrase')
})
return
}
// Keys generation will block the UI thread for a couple of seconds, so we'll use setTimeout
// to let the UI changes happen first
setTimeout(() => {
const eth = {
crypto: Cryptos.ETH,
cryptoName: this.$t('options.export_keys.eth'),
key: (getEthAccount(this.passphrase).privateKey || '').substr(2)
}
const bitcoin = getBtcKey(Cryptos.BTC, this.passphrase, true)
const dash = getBtcKey(Cryptos.DASH, this.passphrase, false)
const doge = getBtcKey(Cryptos.DOGE, this.passphrase, true)
this.keys = [bitcoin, eth, doge, dash]
}, 0)
},
copyKey (key) {
copyToClipboard(key)
this.$store.dispatch('snackbar/show', {
message: this.$t('home.copied'),
timeout: 1500
})
},
copyAll () {
const allKeys = this.keys.map(k => `${k.cryptoName}\r\n${k.key}`).join('\r\n\r\n')
this.copyKey(allKeys)
}
}
}
</script>
<style lang="stylus" scoped>
.export-keys-form
&__keys
margin-bottom: 24px
&__disclaimer
margin-top: 12px
margin-bottom: 24px
&__btn-copy
margin-right: 0
margin-bottom: 0
&__export_keys_button
margin-top: 15px
margin-bottom: 24px
&__copy_all_button
padding-right: 0
margin-right: 0
margin-bottom: 12px
</style>
89 changes: 89 additions & 0 deletions src/components/FreeTokensDialog.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<template>
<v-dialog
v-model="show"
width="500"
:class="className"
@keydown.enter="onEnter"
>
<v-card>
<v-card-title class="a-text-header">
{{ $t("chats.free_adm_title") }}
</v-card-title>

<v-divider class="a-divider"></v-divider>

<v-card-text>
<div :class="`${className}__disclaimer a-text-regular-enlarged`">
{{ $t("chats.free_adm_disclaimer") }}
</div>
</v-card-text>

<v-flex xs12 class="text-xs-center">
<v-btn :class="[`${className}__btn-free-tokens`, 'a-btn-primary']"
@click="getFreeTokens()"
>
<v-icon :class="`${className}__btn-icon`">mdi-gift</v-icon>
<div :class="`${className}__btn-text`">{{ $t('home.free_adm_btn') }}</div>
</v-btn>
</v-flex>

<v-flex xs12 :class="`${className}__btn-show-article`">
<a @click="showArticle()" class="a-text-active">
{{ $t('chats.how_to_use_messenger') }}
</a>
</v-flex>

</v-card>
</v-dialog>
</template>

<script>
export default {
computed: {
className: () => 'free-tokens-dialog',
show: {
get () {
return this.value
},
set (value) {
this.$emit('input', value)
}
}
},
methods: {
getFreeTokens () {
const link = 'https://adamant.im/free-adm-tokens/?wallet=' + this.$store.state.address
window.open(link, '_blank', 'resizable,scrollbars,status,noopener')
this.show = false
},
showArticle () {
const link = this.$t('chats.how_to_use_messenger_link')
window.open(link, '_blank', 'resizable,scrollbars,status,noopener')
},
onEnter () {
if (this.show) {
this.getFreeTokens()
}
}
},
props: {
value: {
type: Boolean,
required: true
}
}
}
</script>
<style lang="stylus" scoped>
.free-tokens-dialog
&__disclaimer
margin-top: 10px
&__btn-free-tokens
margin-top: 15px
margin-bottom: 20px
&__btn-icon
margin-right: 8px
&__btn-show-article
padding-bottom: 30px
text-align: center
</style>
Loading

0 comments on commit a99b736

Please sign in to comment.