Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

create CamBadge component and add pending transaction badge to KeyRow component #436

Open
wants to merge 4 commits into
base: suite
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ export default {
mounted() {
let { updateSuiteStore } = this.globalHelper()
updateSuiteStore(this.$store.state)
this.$store.dispatch('Signavault/updateImportedMultiSigTransaction')
},

watch: {
'$store.state.isAuth': [
{
Expand All @@ -58,6 +60,13 @@ export default {
deep: false,
},
],
'$store.state.Signavault.importedTransactions': [
{
handler: 'updatePendingTX',
immediate: false,
deep: false,
},
],
},
methods: {
onAuthChanged(val, _) {
Expand All @@ -67,6 +76,9 @@ export default {
this.$router.push('/login')
}
},
updatePendingTX() {
this.globalHelper()?.updateStore('updatePendingTxState', true)
},
},
metaInfo: {
meta: [
Expand Down
2 changes: 1 addition & 1 deletion src/bootloader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const mount = (el: string, appSuiteStore: any) => {
install(Vue) {
Vue.prototype.globalHelper = () => {
return {
updateStore: (params) => appSuiteStore.updateStore(params),
updateStore: (type, params) => appSuiteStore.updateStore(type, params),
updateSuiteStore: (s) => setUpdateStore(s),
updateShowAlias: () => updateShowAlias(),
logout: () => setLogOut(true),
Expand Down
112 changes: 112 additions & 0 deletions src/components/CamBadge.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<template>
<div :class="badgeClass" :style="style">
<label :class="size">{{ label }}</label>
</div>
</template>

<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator'
import { CSSProperties } from 'vue'

enum BadgeVariant {
Default = 'default',
Primary = 'primary',
Positive = 'positive',
Warning = 'warning',
Negative = 'negative',
Verified = 'verified',
}

@Component
export default class CamBadge extends Vue {
@Prop({ default: 'default' }) readonly variant?: BadgeVariant
@Prop() label!: string
@Prop({ default: 'medium' }) size?: 'small' | 'medium'
@Prop() style?: CSSProperties

get badgeClass() {
return `camino__badge camino__${this.variant}--badge`
}
}
</script>

<style lang="scss" scoped>
.camino__badge {
width: fit-content;
display: flex;
align-items: center;
padding: 1px 8px;
border-radius: 4px;
}
.camino__default--badge {
background: var(--tailwind-slate-slate-800);
color: var(--tailwind-slate-slate-300);
}

.camino__primary--badge {
background: rgba(0, 133, 255, 0.2);
color: var(--camino-brand-too-blue-to-be-true);
}

.camino__positive--badge {
background: rgba(9, 222, 107, 0.2);
color: var(--camino-success-light);
}

.camino__warning--badge {
background: rgba(229, 162, 31, 0.2);
color: var(--camino-warning-light);
}

.camino__negative--badge {
background: rgba(229, 67, 31, 0.2);
color: var(--camino-error-light);
}

.camino__verified--badge {
background: var(--camino-aphrodite-aqua);
color: var(--tailwind-slate-slate-800);
}

.small,
.medium {
font-family: Inter;
letter-spacing: 1.6px;
text-align: center;
text-transform: uppercase;
font-weight: 600;
line-height: 18px;
font-variant-numeric: lining-nums tabular-nums slashed-zero;
font-feature-settings: 'ss01' on;
font-size: 10px;
}

.small {
font-size: 10px;
}

.medium {
font-size: 12px;
}

[data-theme='light'] {
.camino__primary--badge {
background: #0085ff33;
}

.camino__positive--badge {
background: var(--camino-success-light);
color: #ffff;
}

.camino__warning--badge {
background: var(--camino-warning-light);
color: #ffff;
}

.camino__negative--badge {
background: var(--camino-error-light);
color: #ffff;
}
}
</style>
15 changes: 14 additions & 1 deletion src/components/wallet/manage/KeyRow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@
>
{{ $t('keys.view_priv_key') }}
</button>
<CamBadge
v-if="walletType === 'multisig' && hasPending()"
label="pending tx"
variant="warning"
/>
<button
v-if="walletType === 'multisig'"
@click="showMultisigOwnerModal"
Expand Down Expand Up @@ -141,7 +146,7 @@
</template>
<script lang="ts">
import 'reflect-metadata'
import { Component, Prop, Vue } from 'vue-property-decorator'
import { Component, Prop, Vue, Watch } from 'vue-property-decorator'

import Spinner from '@/components/misc/Spinner.vue'
import Tooltip from '@/components/misc/Tooltip.vue'
Expand All @@ -157,6 +162,7 @@ import { MultisigWallet } from '@/js/wallets/MultisigWallet'
import { SingletonWallet } from '@/js/wallets/SingletonWallet'
import { WalletNameType, WalletType } from '@/js/wallets/types'
import { privateToPublic } from '@ethereumjs/util'
import CamBadge from '@/components/CamBadge.vue'

@Component({
components: {
Expand All @@ -167,6 +173,7 @@ import { privateToPublic } from '@ethereumjs/util'
Tooltip,
ExportKeys,
PrivateKey,
CamBadge,
},
})
export default class KeyRow extends Vue {
Expand Down Expand Up @@ -213,6 +220,11 @@ export default class KeyRow extends Vue {
return ['mnemonic', 'ledger'].includes(this.walletType)
}

hasPending(): boolean {
if (this.wallet.pendingTx) return true
return false
}

get mnemonicPhrase(): MnemonicPhrase | null {
if (this.walletType !== 'mnemonic') return null
let wallet = this.wallet as MnemonicWallet
Expand Down Expand Up @@ -278,6 +290,7 @@ export default class KeyRow extends Vue {
get wallets(): WalletType[] {
return this.$store.state.wallets
}

canRemove(): boolean {
if (this.wallet instanceof MultisigWallet) return true
else {
Expand Down
34 changes: 31 additions & 3 deletions src/components/wallet/manage/MyKeys.vue
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,12 @@ export default class MyKeys extends Vue {
return this.$store.getters['Accounts/account']
}

get getPendingTransaction() {
return this.$store.getters['Signavault/importedTransactions']
}

get inactiveWallets(): WalletType[] {
return this.wallets.filter((wallet) => wallet !== this.activeWallet)
return this.checkInactivePendingWallet()
}

get wallets(): WalletType[] {
Expand Down Expand Up @@ -154,17 +158,17 @@ export default class MyKeys extends Vue {
addAlias() {
this.isLoading = true
this.error = ''

setTimeout(async () => {
try {
const multisigAliases = this.multiSigAliases.map((alias) => 'P-' + alias)
const multisigWallets = await this.$store.dispatch('addWalletsMultisig', {
keys: multisigAliases,
})

await this.$store.dispatch('Signavault/updateImportedMultiSigTransaction')
if (!multisigWallets || multisigWallets.length === 0) {
this.error = 'No address intersection with signing wallets found!'
} else {
this.globalHelper().updateStore('updatePendingTxState', true)
this.globalHelper().dispatchNotification({
message: `Added ${multisigWallets.length} multisig ${multisigWallets.length > 1 ? 'wallets' : 'wallet'} from ${multisigAliases.length} multisig ${multisigAliases.length > 1 ? 'aliases' : 'alias'}`,
type: 'success',
Expand All @@ -182,6 +186,30 @@ export default class MyKeys extends Vue {
}
}, 200)
}

checkInactivePendingWallet() {
const pendingTxs = this.getPendingTransaction
const wallets = this.wallets.filter((wallet) => wallet !== this.activeWallet)

const assignPendingTx = (wallet: WalletType) => {
if (wallet.type === 'multisig') {
delete wallet.pendingTx
const matchingTx = pendingTxs.find(
(tx) => tx.tx.alias === wallet.getStaticAddress('P')
)
if (matchingTx) {
Object.assign(wallet, { pendingTx: matchingTx })
}
}
}

// Check active wallet
assignPendingTx(this.activeWallet)

// Check inactive wallets
wallets.forEach(assignPendingTx)
return wallets
}
}
</script>

Expand Down
2 changes: 1 addition & 1 deletion src/components/wallet/manage/mountKyesComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const mountKyesComponent = (el: string, props: any) => {
return {
dispatchNotification: (params) => dispatchNotification(params),
dispatchSetNewName: () => dispatchSetNewName(),
updateStore: (params) => props.updateStore(params),
updateStore: (type, params) => props.updateStore(type, params),
setAccount: (params) => setAccount(params),
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/wallet/sidebar/mountAccountMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export const mountAccountMenu = (el: string, props: any) => {
setAccount: (acc) => setAccount(acc),
dispatchNotification: (params) => dispatchNotification(params),
dispatchSetNewName: () => dispatchSetNewName(),
updateStore: (params) => props.updateStore(params),
updateStore: (type, params) => props.updateStore(type, params),
}
}
},
Expand Down
1 change: 1 addition & 0 deletions src/js/wallets/WalletCore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ abstract class WalletCore {
name: string = ''
type?: WalletNameType
accountHash?: Buffer
pendingTx?: Object | undefined

utxoset: AVMUTXOSet
platformUtxoset: PlatformUTXOSet
Expand Down
62 changes: 61 additions & 1 deletion src/store/modules/signavault/signavault.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const signavault_module: Module<SignavaultState, RootState> = {
namespaced: true,
state: {
transactions: [],
importedTransactions: [],
},
getters: {
transactions(state) {
Expand All @@ -16,6 +17,10 @@ const signavault_module: Module<SignavaultState, RootState> = {
transaction: (state) => (txID: string) => {
return state.transactions.find((t) => t.tx.id === txID)
},

importedTransactions(state) {
return state.importedTransactions
},
},
mutations: {
clear(state) {
Expand All @@ -24,9 +29,16 @@ const signavault_module: Module<SignavaultState, RootState> = {
setTx(state, newTx: MultisigTx[]) {
state.transactions = newTx
},

setImportedTx(state, newTx: MultisigTx[]) {
state.importedTransactions = newTx
},
clearImported(state) {
state.importedTransactions = []
},
},
actions: {
async updateTransaction({ commit, rootState, rootGetters }) {
async updateTransaction({ commit, dispatch, rootState, rootGetters }) {
const wallet = rootState.activeWallet
if (!wallet || !(wallet instanceof MultisigWallet)) return commit('clear')

Expand Down Expand Up @@ -54,10 +66,58 @@ const signavault_module: Module<SignavaultState, RootState> = {
})
)
)
await dispatch('updateImportedMultiSigTransaction')
} catch (e: any) {
return commit('clear')
}
},
async updateImportedMultiSigTransaction({ commit, rootState, rootGetters }) {
try {
const network = rootGetters['Network/selectedNetwork']
if (!network) return commit('clearImported')

const multisigWallets = rootState.wallets.filter(
(wallet) => wallet.type === 'multisig'
)

const allTxPromises = multisigWallets.map(async (wallet) => {
if (!(wallet instanceof MultisigWallet)) {
commit('clearImported')
return
}

const staticAddress = wallet.getStaticAddress('P')
const signingKeyPair = wallet.wallets[0]?.getStaticKeyPair()

if (!signingKeyPair) {
console.log('wallet returned undefined staticKeyPair')
commit('clearImported')
return
}

return await SignaVaultTx(staticAddress, signingKeyPair) // Get transactions for each wallet
})

const allTxResults = (await Promise.all(allTxPromises)).flat()

const multisigTxs = allTxResults
.map((mms, index) => {
const wallet = multisigWallets[index]
if (!mms || !(wallet instanceof MultisigWallet)) return []

return {
tx: mms,
state: wallet.getSignatureStatus(mms),
}
})
.filter((tx: any) => tx.length !== 0) // Filter out empty results

commit('setImportedTx', multisigTxs.flat())
} catch (e: any) {
console.error('Error fetching transactions:', e)
commit('clearImported')
}
},
},
}

Expand Down
Loading
Loading