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

Contribution from cc-wallet dev session #13

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
5303a13
Add featured tokens support
mainnet-pat Jul 29, 2024
85b209d
Add settings toggles to show wallet connect and token creation dialog…
mainnet-pat Jul 29, 2024
43a39a2
Update mainnet-js, allow for wallet fiat currency selection, currentl…
mainnet-pat Jul 29, 2024
17c71c1
Add history tab
mainnet-pat Aug 1, 2024
145901e
Rework favorite tokens handling, add favorite toggle to token cards
mainnet-pat Aug 1, 2024
a091e29
Fix lint errors
mainnet-pat Aug 1, 2024
e9c775a
Shuffle utils around, fix minor issues
mainnet-pat Aug 1, 2024
236c8df
Fix issues, tokens page refreshes after bcmr fetch, float favorite to…
mainnet-pat Aug 2, 2024
6c89874
Extract toggleFavorite to store, add addToFavorites, add route /addTo…
mainnet-pat Aug 2, 2024
52890b3
Better refresh behaviour of tokens page
mainnet-pat Aug 7, 2024
eabacc5
Rework token icon handling
mainnet-pat Aug 7, 2024
eb18674
Fix visual quirks
mainnet-pat Aug 7, 2024
1339a33
Fix history darkmode styling, use token decimals for amount display
mainnet-pat Aug 8, 2024
1625ea0
Respect token decimals in transaction view
mainnet-pat Aug 8, 2024
ca7adbe
Reset defaults for settingsStore, compact view of menu on mobile devices
mainnet-pat Aug 8, 2024
39f0141
Cleanup and lint
mainnet-pat Aug 8, 2024
d7acd19
Add token fiat value display in tokens, history and transactions views
mainnet-pat Aug 9, 2024
85b2053
Fix issue with historical prices were off by one transaction, add adv…
mainnet-pat Aug 10, 2024
6279936
Add qrcode scanning dialog, use it on wallet page for address scans a…
mainnet-pat Aug 10, 2024
df884e2
Some improvements to qr code scanning
mainnet-pat Aug 11, 2024
c29cd94
Fix token price calculation to disregard decimals
mainnet-pat Aug 12, 2024
c5234ea
Add qr-scan buttons to fungible, nft groups, single nfts and nft chil…
mainnet-pat Aug 12, 2024
ec88e6e
Fix video constraints in qrcode scanner
mainnet-pat Aug 12, 2024
395548d
Use cached fetch for authguard, bcmr file and bcmr-per token lookups …
mainnet-pat Aug 12, 2024
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
9 changes: 0 additions & 9 deletions .editorconfig

This file was deleted.

4 changes: 2 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"editor.bracketPairColorization.enabled": true,
"editor.guides.bracketPairs": true,
// "editor.bracketPairColorization.enabled": true,
// "editor.guides.bracketPairs": true,
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": [
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ Because of its minimalist design, Cashonize is a user-friendly wallet, even for
Cashonize nicely displays your NFT collections by collapsing NFTs of the same tokenId, making it ideal for NFT collectors.

Cashonize is a single-address wallet, for privacy-centered users is better to use a HD-wallet.
Cashonize does not have a display for your transaction history and for now it only supports USD for denomating BCH balances.

## Platforms

Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,24 @@
},
"dependencies": {
"@bitjson/qr-code": "^1.0.2",
"@capacitor-community/barcode-scanner": "^4.0.1",
"@capacitor/app": "^5.0.7",
"@capacitor/core": "^5.7.4",
"@download/blockies": "^1.0.3",
"@mainnet-cash/indexeddb-storage": "^2.2.7",
"@mainnet-pat/json5-bigint": "^2.2.5",
"@quasar/extras": "^1.16.4",
"@types/blockies": "^0.0.4",
"@vueform/toggle": "^2.1.4",
"@vueuse/core": "^10.7.2",
"@walletconnect/core": "^2.11.1",
"@walletconnect/web3wallet": "^1.10.1",
"chota": "^0.9.2",
"mainnet-js": "^2.3.13",
"mainnet-js": "^2.4.1",
"pinia": "^2.1.7",
"quasar": "^2.14.3",
"vue": "^3.3.4",
"vue-qrcode-reader": "^5.5.7",
"vue-router": "^4.0.12"
},
"devDependencies": {
Expand Down
1 change: 1 addition & 0 deletions public/images/qrscan.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 8 additions & 1 deletion quasar.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,14 @@ module.exports = configure(function (/* ctx */) {
// extendViteConf (viteConf) {},
// viteVuePluginOptions: {},


viteVuePluginOptions: {
template: {
compilerOptions: {
isCustomElement: (tag) => tag === ('qr-code')
}
}
},

vitePlugins: [
[
nodePolyfills
Expand Down
82 changes: 53 additions & 29 deletions src/components/bchWallet.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,20 @@
import { decodeCashAddress } from "@bitauth/libauth"
import { defineCustomElements } from '@bitjson/qr-code';
import alertDialog from 'src/components/alertDialog.vue'
import { CurrencySymbols, CurrencyShortNames, TokenDataFT, TokenDataNFT, TokenData } from 'src/interfaces/interfaces'
import { useStore } from '../stores/store'
import { useSettingsStore } from '../stores/settingsStore'
import { useQuasar } from 'quasar'
import QrCodeDialog from './qr/qrCodeScanDialog.vue';

const $q = useQuasar()
const store = useStore()
const settingsStore = useSettingsStore()
import { useWindowSize } from '@vueuse/core'
const { width } = useWindowSize();
const isMobile = computed(() => width.value < 480)

const nrTokenCategories = computed(() => store.tokenList?.length)
const nrTokenCategories = computed(() => store.tokenList?.filter((token: TokenData) => (token as TokenDataFT).amount > 0n || (token as TokenDataNFT).nfts?.length > 0).length)

const numberFormatter = new Intl.NumberFormat('en-US', {maximumFractionDigits: 8});

Expand All @@ -32,8 +35,9 @@
// reactive state
const displayeBchQr = ref(true);
const bchSendAmount = ref(undefined as (number | undefined));
const usdSendAmount = ref(undefined as (number | undefined));
const currencySendAmount = ref(undefined as (number | undefined));
const destinationAddr = ref("");
const showQrCodeDialog = ref(false);

function switchAddressTypeQr(){
displayeBchQr.value = !displayeBchQr.value;
Expand All @@ -57,29 +61,29 @@
let bchAmount = Number(params.split("amount=")[1]);
if(settingsStore.bchUnit == "sat") bchAmount = Math.round(bchAmount * 100_000_000);
bchSendAmount.value = bchAmount;
setUsdAmount()
setCurrencyAmount()
}
}
async function setUsdAmount() {
async function setCurrencyAmount() {
if(typeof bchSendAmount.value != 'number'){
usdSendAmount.value = undefined
currencySendAmount.value = undefined
return
}
const newUsdValue = await convert(bchSendAmount.value, settingsStore.bchUnit, "usd");
usdSendAmount.value = Number(newUsdValue.toFixed(2));
const newCurrencyValue = await convert(bchSendAmount.value, settingsStore.bchUnit, settingsStore.currency);
currencySendAmount.value = Number(newCurrencyValue.toFixed(2));
}
async function setBchAmount() {
if(typeof usdSendAmount.value != 'number'){
if(typeof currencySendAmount.value != 'number'){
bchSendAmount.value = undefined
return
}
const newBchValue = await convert(usdSendAmount.value, "usd", settingsStore.bchUnit);
const newBchValue = await convert(currencySendAmount.value, settingsStore.currency, settingsStore.bchUnit);
bchSendAmount.value = Number(newBchValue);
}
async function useMaxBchAmount(){
if(store.maxAmountToSend && store.maxAmountToSend[settingsStore.bchUnit]){
bchSendAmount.value = store.maxAmountToSend[settingsStore.bchUnit];
setUsdAmount()
setCurrencyAmount()
}
else{
$q.notify({
Expand Down Expand Up @@ -124,7 +128,7 @@
console.log(alertMessage);
// reset fields
bchSendAmount.value = undefined;
usdSendAmount.value = undefined;
currencySendAmount.value = undefined;
destinationAddr.value = "";
} catch(error){
console.log(error)
Expand All @@ -136,15 +140,26 @@
})
}
}
const qrDecode = (content: string) => {
destinationAddr.value = content;
}
const qrFilter = (content: string) => {
const decoded = decodeCashAddress(content);
if (typeof decoded === "string" || decoded.prefix !== store.wallet?.networkPrefix) {
return "Not a cashaddress on current network";
}

return true;
}
</script>


<template>
<fieldset style="margin-top: 20px; padding-top: 2rem; max-width: 75rem; margin: auto 10px;">
<div v-if="store.network == 'mainnet'" style="font-size: 1.2em">
USD balance:
{{ CurrencyShortNames[settingsStore.currency] }} balance:
<span style="color: hsla(160, 100%, 37%, 1);">
{{ store.balance && store.balance.usd != undefined ? (store.balance.usd).toFixed(2) + " $": "" }}
{{ store.balance && store.balance[settingsStore.currency] != undefined ? (store.balance[settingsStore.currency]).toFixed(2) + ` ${CurrencySymbols[settingsStore.currency]}`: "" }}
</span>
</div>
<span>
Expand All @@ -154,18 +169,20 @@
? numberFormatter.format(store.balance[settingsStore.bchUnit] as number) + displayUnitLong : "" }}
</span>
</span>
<span v-if="!isMobile">
, Tokens:
<span style="color: hsla(160, 100%, 37%, 1);">
{{ nrTokenCategories != undefined ? nrTokenCategories + " different categories" : ""}}
<span v-if="nrTokenCategories">
<span v-if="!isMobile">
, Tokens:
<span style="color: hsla(160, 100%, 37%, 1);">
{{ nrTokenCategories + " different categories"}}
</span>
</span>
<div v-else style="margin-bottom: 10px;">
Tokens:
<span style="color: hsla(160, 100%, 37%, 1);">
{{ nrTokenCategories + " different categories"}}
</span>
</div>
</span>
<div v-else style="margin-bottom: 10px;">
Tokens:
<span style="color: hsla(160, 100%, 37%, 1);">
{{ nrTokenCategories != undefined ? nrTokenCategories + " different categories" : ""}}
</span>
</div>
<div style="word-break: break-all;">
BCH address:
<span @click="() => copyToClipboard(store.wallet?.address)" style="cursor:pointer;">
Expand All @@ -191,21 +208,28 @@
</div>
<div style="margin-top: 5px;">
Send BCH:
<input v-model="destinationAddr" @input="parseAddrParams()" id="destinationAddr" placeholder="address">
<div style="display: flex; gap: 0.5rem;">
<input v-model="destinationAddr" @input="parseAddrParams()" id="destinationAddr" placeholder="address">
<button @click="() => showQrCodeDialog = true" style="padding: 12px">
<img src="images/qrscan.svg" />
</button>
</div>
<span class="sendAmountGroup">
<span style="position: relative; width: 50%;">
<input v-model="bchSendAmount" @input="setUsdAmount()" id="sendAmount" type="number" placeholder="amount">
<input v-model="bchSendAmount" @input="setCurrencyAmount()" id="sendAmount" type="number" placeholder="amount">
<i class="input-icon" style="color: black;">{{ bchDisplayUnit }}</i>
</span>
<span class="sendUsdInput">
<input v-model="usdSendAmount" @input="setBchAmount()" id="sendAmount" type="number" placeholder="amount">
<i class="input-icon" style="color: black;">{{store.network == "mainnet"? "USD $":"tUsd $"}}</i>
<span class="sendCurrencyInput">
<input v-model="currencySendAmount" @input="setBchAmount()" id="sendAmount" type="number" placeholder="amount">
<i class="input-icon" style="color: black;">{{(store.network == "mainnet"? "" : "t") + `${CurrencyShortNames[settingsStore.currency]} ${CurrencySymbols[settingsStore.currency]}`}}</i>
</span>
<button @click="useMaxBchAmount()" class="fillInMaxBch">max</button>
</span>
<div v-if="(store.maxAmountToSend?.[settingsStore.bchUnit] ?? 0) < (bchSendAmount ?? 0)" style="color: red;" id="warningNoBCH">Not enough BCH in wallet to send</div>

</div>
<input @click="sendBch()" type="button" class="primaryButton" id="send" value="Send" style="margin-top: 8px;">
</fieldset>
<div v-if="showQrCodeDialog">
<QrCodeDialog @hide="() => showQrCodeDialog = false" @decode="qrDecode" :filter="qrFilter"/>
</div>
</template>
6 changes: 5 additions & 1 deletion src/components/createTokens.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import alertDialog from 'src/components/alertDialog.vue'
import { useStore } from '../stores/store'
import { useQuasar } from 'quasar'
import { cachedFetch } from 'src/utils/utils';
const $q = useQuasar()
const store = useStore()

Expand Down Expand Up @@ -61,7 +62,10 @@
const fetchLocation = selectedUri.value != "IPFS" ? "https://" + inputField + bcmrLocation : inputField + inputField.slice(7);
try{
console.log("fetching bcmr at "+fetchLocation);
const response = await fetch(fetchLocation);
const response = await cachedFetch(fetchLocation, {
storageType: localStorage,
duration: 1000 * 60 * 60 * 24, // 1 day
});
if(response?.status == 200) validitityCheck.value = true;
const bcmrContent = await response.text();
const hashContent = sha256.hash(utf8ToBin(bcmrContent));
Expand Down
Loading