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

Transition to Dexie proof storage #252

Merged
merged 29 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
8cb73d7
dexie works
callebtc Nov 13, 2024
6bf11b6
alternative way of getting activeProofs
callebtc Nov 13, 2024
280cc03
dexie export to localstorage
callebtc Nov 13, 2024
f415ab9
Merge branch 'main' into dexie-storage-2
callebtc Dec 27, 2024
8f82eed
npm lock
callebtc Dec 27, 2024
919012c
improve watcher
callebtc Dec 27, 2024
09d87e4
remove spent proofs
callebtc Dec 27, 2024
f791b47
fix wallet
callebtc Dec 27, 2024
64a17a3
activeProofs works
callebtc Dec 27, 2024
da5a67f
fix animated number progress
callebtc Dec 27, 2024
3ca3849
cleanup
callebtc Dec 28, 2024
510566e
fix comment
callebtc Dec 28, 2024
d71b718
refactor restore into storageStore
callebtc Dec 28, 2024
fb623e1
refactor
callebtc Dec 28, 2024
371337c
async calls
callebtc Dec 30, 2024
1fff18b
dexie modify works
callebtc Dec 30, 2024
0531650
dexie works
callebtc Dec 30, 2024
81681e0
npm run format
callebtc Dec 30, 2024
334e64c
Merge branch 'main' into dexie-storage-2
callebtc Dec 30, 2024
9307673
remove proofs before adding new ones, and move wallet methods
callebtc Dec 31, 2024
ff70c09
npm run format
callebtc Dec 31, 2024
3ece3db
export wallet state before dexie migration
callebtc Dec 31, 2024
def0c70
notifications
callebtc Dec 31, 2024
956abe8
edits
callebtc Jan 2, 2025
48497a6
edit migration
callebtc Jan 2, 2025
28fce20
edit better
callebtc Jan 2, 2025
61a81cc
wip move proof methods from mintsStore to proofsStore
callebtc Jan 2, 2025
14d6a69
fix: unset reserved proofs in settings
callebtc Jan 13, 2025
276cbf6
fix header location
callebtc Jan 13, 2025
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
5,143 changes: 1,467 additions & 3,676 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"capacitor-plugin-safe-area": "^3.0.4",
"core-js": "^3.37.0",
"date-fns": "^3.6.0",
"dexie": "^4.0.9",
"light-bolt11-decoder": "^3.1.1",
"lucide-vue-next": "^0.453.0",
"nostr-tools": "^2.5.2",
Expand Down
12 changes: 11 additions & 1 deletion src/components/AnimatedNumber.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,27 @@ export default defineComponent({
},
setup(props) {
const displayedValue = ref(props.value);
// value to remember that we do not want to animate the very first update (when the component is created)
const initialized = ref(false);

watch(
() => props.value,
(newValue, oldValue) => {
if (!initialized.value) {
displayedValue.value = newValue;
if (newValue > 0) {
// do not animate until we set the first value
initialized.value = true;
}
return;
}
const startTime = performance.now();
const startValue = oldValue !== undefined ? oldValue : newValue;
const endValue = newValue;

const animate = (currentTime: number) => {
const elapsed = currentTime - startTime;
const progress = Math.min(elapsed / props.duration, 1);
const progress = Math.max(Math.min(elapsed / props.duration, 1), 0);
const currentValue = startValue + (endValue - startValue) * progress;
displayedValue.value = currentValue;
if (progress < 1) {
Expand Down
21 changes: 7 additions & 14 deletions src/components/BalanceView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@
Balance:
<b>
<AnimatedNumber
:value="getActiveMintBalance"
:value="getActiveBalance"
:format="(val) => formatCurrency(val, activeUnit)"
class="q-my-none q-py-none cursor-pointer"
/>
Expand Down Expand Up @@ -163,28 +163,23 @@ export default defineComponent({
...mapState(useMintsStore, [
"activeMintUrl",
"activeProofs",
"mints",
"proofs",
"activeBalance",
"mints",
"totalUnitBalance",
"activeUnit",
"activeMint",
]),
...mapState(useTokensStore, ["historyTokens"]),
...mapState(useUiStore, ["globalMutexLock"]),
...mapState(usePriceStore, ["bitcoinPrice"]),
...mapWritableState(useMintsStore, ["activeUnit"]),
...mapWritableState(useUiStore, ["hideBalance"]),
...mapWritableState(useUiStore, ["hideBalance", "lastBalanceCached"]),
pendingBalance: function () {
return -this.historyTokens
.filter((t) => t.status == "pending")
.filter((t) => t.unit == this.activeUnit)
.reduce((sum, el) => (sum += el.amount), 0);
},
balance: function () {
return this.activeProofs
.flat()
.reduce((sum, el) => (sum += el.amount), 0);
},
balancesOptions: function () {
const mint = this.activeMint();
return Object.entries(mint.allBalances).map(([key, value]) => ({
Expand All @@ -196,12 +191,10 @@ export default defineComponent({
return [].concat(...this.mints.map((m) => m.keysets));
},
getTotalBalance: function () {
return this.activeBalance;
return this.totalUnitBalance;
},
getActiveMintBalance: function () {
return this.activeProofs
.flat()
.reduce((sum, el) => (sum += el.amount), 0);
getActiveBalance: function () {
return this.activeBalance;
},
activeMintLabel: function () {
const mintClass = this.activeMint();
Expand Down
1 change: 0 additions & 1 deletion src/components/ChooseMint.vue
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ export default defineComponent({
"activeMintUrl",
"activeProofs",
"mints",
"proofs",
"activeUnit",
]),
...mapWritableState(useMintsStore, ["activeMintUrl"]),
Expand Down
6 changes: 3 additions & 3 deletions src/components/MainHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,8 @@ export default defineComponent({
});
</script>
<style scoped>
.glassy-header {
background: rgba(255, 255, 255, 0.5);
backdrop-filter: blur(10px);
.q-header {
position: relative;
z-index: auto;
}
</style>
56 changes: 0 additions & 56 deletions src/components/MintSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -198,16 +198,6 @@
>
</q-item-section>
</q-item>
<q-item v-if="false">
<q-btn
class="q-ml-sm q-px-md"
color="primary"
rounded
outline
@click="initNdk"
>Link to extension</q-btn
>
</q-item>
<q-item>
<q-btn
class="q-ml-sm q-px-md"
Expand Down Expand Up @@ -735,52 +725,6 @@ export default defineComponent({
await this.mintAmountSwap(swapAmountData);
this.clearSwapData();
},
enable_terminal: function () {
// enable debug terminal
var script = document.createElement("script");
script.src = "//cdn.jsdelivr.net/npm/eruda";
document.body.appendChild(script);
script.onload = function () {
eruda.init();
};
},
getLocalstorageToFile: async function () {
// https://stackoverflow.com/questions/24263682/save-restore-local-storage-to-a-local-file
const fileName = `cashu_backup_${currentDateStr()}.json`;
var a = {};
for (var i = 0; i < localStorage.length; i++) {
var k = localStorage.key(i);
var v = localStorage.getItem(k);
a[k] = v;
}
var textToSave = JSON.stringify(a);
var textToSaveAsBlob = new Blob([textToSave], {
type: "text/plain",
});
var textToSaveAsURL = window.URL.createObjectURL(textToSaveAsBlob);

var downloadLink = document.createElement("a");
downloadLink.download = fileName;
downloadLink.innerHTML = "Download File";
downloadLink.href = textToSaveAsURL;
downloadLink.onclick = function () {
document.body.removeChild(event.target);
};
downloadLink.style.display = "none";
document.body.appendChild(downloadLink);
downloadLink.click();
},
toggleGetBitcoinPrice: function () {
this.getBitcoinPrice = !this.getBitcoinPrice;
},
initNdk: async function () {
await this.initNdkReadOnly();
console.log(await this.getUserPubkey());
// console.log("### fetch events");
// console.log(await this.fetchEventsFromUser());
// console.log("### fetch mints");
// console.log(await this.fetchMints());
},
fetchMintsFromNdk: async function () {
this.discoveringMints = true;
await this.initNdkReadOnly();
Expand Down
15 changes: 8 additions & 7 deletions src/components/PayInvoiceDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,10 @@
<div class="col-12">
<ChooseMint />
</div>
<div v-if="enoughActiveBalance" class="row q-mt-lg">
<div
v-if="enoughtotalUnitBalance || globalMutexLock"
class="row q-mt-lg"
>
<q-btn
unelevated
rounded
Expand Down Expand Up @@ -296,10 +299,9 @@ export default defineComponent({
"activeMintUrl",
"activeProofs",
"mints",
"proofs",
"activeUnit",
"totalUnitBalance",
"activeBalance",
"activeMintBalance",
]),
...mapState(usePriceStore, ["bitcoinPrice"]),
canPasteFromClipboard: function () {
Expand All @@ -309,10 +311,9 @@ export default defineComponent({
navigator.clipboard.readText
);
},
enoughActiveBalance: function () {
enoughtotalUnitBalance: function () {
return (
this.activeMintBalance() >=
this.payInvoiceData.meltQuote.response.amount
this.activeBalance >= this.payInvoiceData.meltQuote.response.amount
);
},
},
Expand All @@ -326,7 +327,7 @@ export default defineComponent({
...mapActions(useCameraStore, ["closeCamera", "showCamera"]),
canPay: function () {
if (!this.payInvoiceData.invoice) return false;
return payInvoiceData.meltQuote.response.amount <= this.activeBalance;
return payInvoiceData.meltQuote.response.amount <= this.totalUnitBalance;
},
closeParseDialog: function () {
setTimeout(() => {
Expand Down
9 changes: 3 additions & 6 deletions src/components/SendTokenDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,7 @@
</div>
</div>
</transition>
<div
v-if="activeMintBalance() >= sendData.amount"
class="row q-mt-lg"
>
<div v-if="activeBalance >= sendData.amount" class="row q-mt-lg">
<q-btn
v-if="!sendData.tokens"
:disable="
Expand Down Expand Up @@ -203,7 +200,7 @@
v-if="
sendData.amount > 0 &&
!showLockInput &&
activeMintBalance() >= sendData.amount
activeBalance >= sendData.amount
"
:disable="sendData.p2pkPubkey == null || sendData.amount <= 0"
color="primary"
Expand Down Expand Up @@ -537,7 +534,7 @@ export default defineComponent({
"activeUnitLabel",
"activeUnitCurrencyMultiplyer",
"activeMintUrl",
"activeMintBalance",
"activeBalance",
]),
...mapState(useSettingsStore, [
"checkSentTokens",
Expand Down
70 changes: 18 additions & 52 deletions src/components/SettingsView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -1164,11 +1164,12 @@
</q-btn></row
><row>
<q-item-label class="q-px-sm" caption
>To avoid double-spending attempts, this wallet marks
ecash as reserved so you don't reuse it. This button will
unset all reserved tokens so they can be used again. If
you do this, your wallet might include spent proofs. Press
the "Remove spent proofs" button to get rid of them.
>This wallet marks pending outgoing ecash as reserved (and
subtracts it from your balance) to prevent double-spend
attempts. This button will unset all reserved tokens so
they can be used again. If you do this, your wallet might
include spent proofs. Press the "Remove spent proofs"
button to get rid of them.
</q-item-label>
</row>
</q-item-section>
Expand Down Expand Up @@ -1234,13 +1235,7 @@
<q-item>
<q-item-section>
<row>
<q-btn
dense
flat
outline
click
@click="getLocalstorageToFile"
>
<q-btn dense flat outline click @click="exportWalletState">
Export wallet data
</q-btn></row
><row>
Expand Down Expand Up @@ -1276,7 +1271,6 @@ import { mapActions, mapState, mapWritableState } from "pinia";
import { useMintsStore, MintClass } from "src/stores/mints";
import { useWalletStore } from "src/stores/wallet";
import { map } from "underscore";
import { currentDateStr } from "src/js/utils";
import { useSettingsStore } from "src/stores/settings";
import { useNostrStore } from "src/stores/nostr";
import { useNPCStore } from "src/stores/npubcash";
Expand All @@ -1287,8 +1281,10 @@ import { useWorkersStore } from "src/stores/workers";
import { useProofsStore } from "src/stores/proofs";
import { usePRStore } from "../stores/payment-request";
import { useRestoreStore } from "src/stores/restore";
import { useDexieStore } from "../stores/dexie";
import { useReceiveTokensStore } from "../stores/receiveTokensStore";
import { useWelcomeStore } from "src/stores/welcome";
import { useStorageStore } from "src/stores/storage";

export default defineComponent({
name: "SettingsView",
Expand Down Expand Up @@ -1340,12 +1336,7 @@ export default defineComponent({
"showP2PkButtonInDrawer",
]),
...mapWritableState(useNWCStore, ["showNWCDialog", "showNWCData"]),
...mapState(useMintsStore, [
"activeMintUrl",
"mints",
"activeProofs",
"proofs",
]),
...mapState(useMintsStore, ["activeMintUrl", "mints", "activeProofs"]),
...mapState(useNPCStore, ["npcLoading"]),
...mapState(useNostrStore, [
"pubkey",
Expand Down Expand Up @@ -1441,7 +1432,6 @@ export default defineComponent({
"removeMint",
"activateMintUrl",
"updateMint",
"restoreFromBackup",
]),
...mapActions(useWalletStore, [
"newMnemonic",
Expand All @@ -1452,6 +1442,8 @@ export default defineComponent({
...mapActions(useProofsStore, ["serializeProofs"]),
...mapActions(useNPCStore, ["generateNPCConnection"]),
...mapActions(useRestoreStore, ["restoreMint"]),
...mapActions(useDexieStore, ["deleteAllTables"]),
...mapActions(useStorageStore, ["restoreFromBackup", "exportWalletState"]),
generateNewMnemonic: async function () {
this.newMnemonic();
await this.initSigner();
Expand All @@ -1466,39 +1458,11 @@ export default defineComponent({
toggleTerminal: function () {
useUiStore().toggleDebugConsole();
},
getLocalstorageToFile: async function () {
// https://stackoverflow.com/questions/24263682/save-restore-local-storage-to-a-local-file
const fileName = `cashu_backup_${currentDateStr()}.json`;
var a = {};
for (var i = 0; i < localStorage.length; i++) {
var k = localStorage.key(i);
var v = localStorage.getItem(k);
a[k] = v;
}
var textToSave = JSON.stringify(a);
var textToSaveAsBlob = new Blob([textToSave], {
type: "text/plain",
});
var textToSaveAsURL = window.URL.createObjectURL(textToSaveAsBlob);

var downloadLink = document.createElement("a");
downloadLink.download = fileName;
downloadLink.innerHTML = "Download File";
downloadLink.href = textToSaveAsURL;
downloadLink.onclick = function () {
document.body.removeChild(event.target);
};
downloadLink.style.display = "none";
document.body.appendChild(downloadLink);
downloadLink.click();
},
unsetAllReservedProofs: async function () {
// mark all this.proofs as reserved=false
for (let proof of this.proofs) {
proof.reserved = false;
proof.quote = undefined;
}
this.notifySuccess("No reserved proofs left");
const proofsStore = useProofsStore();
await proofsStore.setReserved(await proofsStore.getProofs(), false);
this.notifySuccess("All reserved proofs unset");
},
checkActiveProofsSpendable: async function () {
// iterate over this.activeProofs in batches of 50 and check if they are spendable
Expand Down Expand Up @@ -1571,7 +1535,9 @@ export default defineComponent({
},
nukeWallet: async function () {
// create a backup just in case
await this.getLocalstorageToFile();
await this.exportWalletState();
// clear dexie tables
this.deleteAllTables();
localStorage.clear();
window.location.href = "/";
},
Expand Down
Loading
Loading