aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/taler-wallet-cli/src/index.ts22
-rw-r--r--packages/taler-wallet-core/src/operations/backup.ts53
-rw-r--r--packages/taler-wallet-core/src/operations/state.ts4
-rw-r--r--packages/taler-wallet-core/src/types/backupTypes.ts1
-rw-r--r--packages/taler-wallet-core/src/wallet.ts9
-rw-r--r--packages/taler-wallet-webextension/manifest.json4
-rw-r--r--packages/taler-wallet-webextension/package.json2
7 files changed, 79 insertions, 16 deletions
diff --git a/packages/taler-wallet-cli/src/index.ts b/packages/taler-wallet-cli/src/index.ts
index e8e09f8fa..f4970e73d 100644
--- a/packages/taler-wallet-cli/src/index.ts
+++ b/packages/taler-wallet-cli/src/index.ts
@@ -36,9 +36,6 @@ import {
NodeThreadCryptoWorkerFactory,
CryptoApi,
rsaBlind,
- encodeCrock,
- rsaUnblind,
- rsaVerify,
} from "taler-wallet-core";
import * as clk from "./clk";
import { deepStrictEqual } from "assert";
@@ -401,6 +398,25 @@ exchangesCli
});
});
+const backupCli = walletCli.subcommand("backupArgs", "backup", {
+ help: "Subcommands for backups",
+});
+
+backupCli.subcommand("exportPlain", "export-plain").action(async (args) => {
+ await withWallet(args, async (wallet) => {
+ const backup = await wallet.exportBackupPlain();
+ console.log(JSON.stringify(backup, undefined, 2));
+ });
+});
+
+
+backupCli.subcommand("importPlain", "import-plain").action(async (args) => {
+ await withWallet(args, async (wallet) => {
+ const data = JSON.parse(await read(process.stdin));
+ await wallet.importBackupPlain(data);
+ });
+});
+
const advancedCli = walletCli.subcommand("advancedArgs", "advanced", {
help:
"Subcommands for advanced operations (only use if you know what you're doing!).",
diff --git a/packages/taler-wallet-core/src/operations/backup.ts b/packages/taler-wallet-core/src/operations/backup.ts
index b82e63ff2..4f736c3df 100644
--- a/packages/taler-wallet-core/src/operations/backup.ts
+++ b/packages/taler-wallet-core/src/operations/backup.ts
@@ -588,10 +588,6 @@ export async function exportBackup(
);
}
-export interface BackupRequest {
- backupBlob: any;
-}
-
export async function encryptBackup(
config: WalletBackupConfState,
blob: WalletBackupContentV1,
@@ -621,7 +617,7 @@ interface BackupCryptoPrecomputedData {
/**
* Compute cryptographic values for a backup blob.
- *
+ *
* FIXME: Take data that we already know from the DB.
* FIXME: Move computations into crypto worker.
*/
@@ -650,7 +646,7 @@ async function computeBackupCryptoData(
cryptoData.coinPrivToCompletedCoin[backupCoin.coin_priv] = {
coinEvHash: encodeCrock(hash(blindedCoin)),
coinPub,
- }
+ };
}
cryptoData.denomPubToHash[backupDenom.denom_pub] = encodeCrock(
hash(decodeCrock(backupDenom.denom_pub)),
@@ -777,16 +773,35 @@ async function recoverPayCoinSelection(
};
}
-function getDenomSelStateFromBackup(
+async function getDenomSelStateFromBackup(
tx: TransactionHandle<typeof Stores.denominations>,
+ exchangeBaseUrl: string,
sel: BackupDenomSel,
): Promise<DenomSelectionState> {
- throw Error("not implemented");
+ const d0 = await tx.get(Stores.denominations, [exchangeBaseUrl, sel[0].denom_pub_hash]);
+ checkBackupInvariant(!!d0);
+ const selectedDenoms: {
+ denomPubHash: string;
+ count: number;
+ }[] = [];
+ let totalCoinValue = Amounts.getZero(d0.value.currency);
+ let totalWithdrawCost = Amounts.getZero(d0.value.currency);
+ for (const s of sel) {
+ const d = await tx.get(Stores.denominations, [exchangeBaseUrl, s.denom_pub_hash]);
+ checkBackupInvariant(!!d);
+ totalCoinValue = Amounts.add(totalCoinValue, d.value).amount;
+ totalWithdrawCost = Amounts.add(totalWithdrawCost, d.value, d.feeWithdraw).amount;
+ }
+ return {
+ selectedDenoms,
+ totalCoinValue,
+ totalWithdrawCost,
+ }
}
export async function importBackup(
ws: InternalWalletState,
- backupRequest: BackupRequest,
+ backupBlobArg: any,
cryptoComp: BackupCryptoPrecomputedData,
): Promise<void> {
await provideBackupState(ws);
@@ -807,7 +822,7 @@ export async function importBackup(
],
async (tx) => {
// FIXME: validate schema!
- const backupBlob = backupRequest.backupBlob as WalletBackupContentV1;
+ const backupBlob = backupBlobArg as WalletBackupContentV1;
// FIXME: validate version
@@ -993,6 +1008,7 @@ export async function importBackup(
reserveStatus: ReserveRecordStatus.QUERYING_STATUS,
initialDenomSel: await getDenomSelStateFromBackup(
tx,
+ backupExchange.base_url,
backupReserve.initial_selected_denoms,
),
});
@@ -1006,6 +1022,7 @@ export async function importBackup(
await tx.put(Stores.withdrawalGroups, {
denomsSel: await getDenomSelStateFromBackup(
tx,
+ backupExchange.base_url,
backupWg.selected_denoms,
),
exchangeBaseUrl: backupExchange.base_url,
@@ -1300,9 +1317,12 @@ export async function importBackup(
| undefined
)[] = [];
for (const oldCoin of backupRefreshGroup.old_coins) {
+ const c = await tx.get(Stores.coins, oldCoin.coin_pub);
+ checkBackupInvariant(!!c);
if (oldCoin.refresh_session) {
const denomSel = await getDenomSelStateFromBackup(
tx,
+ c.exchangeBaseUrl,
oldCoin.refresh_session.new_denoms,
);
refreshSessionPerCoin.push({
@@ -1346,6 +1366,7 @@ export async function importBackup(
if (!existingTip) {
const denomsSel = await getDenomSelStateFromBackup(
tx,
+ backupTip.exchange_base_url,
backupTip.selected_denoms,
);
await tx.put(Stores.tips, {
@@ -1530,6 +1551,18 @@ export interface BackupInfo {
providers: ProviderInfo[];
}
+export async function importBackupPlain(
+ ws: InternalWalletState,
+ blob: any,
+): Promise<void> {
+ // FIXME: parse
+ const backup: WalletBackupContentV1 = blob;
+
+ const cryptoData = await computeBackupCryptoData(ws.cryptoApi, backup);
+
+ await importBackup(ws, blob, cryptoData);
+}
+
/**
* Get information about the current state of wallet backups.
*/
diff --git a/packages/taler-wallet-core/src/operations/state.ts b/packages/taler-wallet-core/src/operations/state.ts
index 11695f6d0..1733f13bb 100644
--- a/packages/taler-wallet-core/src/operations/state.ts
+++ b/packages/taler-wallet-core/src/operations/state.ts
@@ -55,6 +55,10 @@ export class InternalWalletState {
private resourceLocks: Set<string> = new Set();
constructor(
+ // FIXME: Make this a getter and make
+ // the actual value nullable.
+ // Check if we are in a DB migration / garbage collection
+ // and throw an error in that case.
public db: Database,
public http: HttpRequestLibrary,
cryptoWorkerFactory: CryptoWorkerFactory,
diff --git a/packages/taler-wallet-core/src/types/backupTypes.ts b/packages/taler-wallet-core/src/types/backupTypes.ts
index fdc244d8f..f7bd8784d 100644
--- a/packages/taler-wallet-core/src/types/backupTypes.ts
+++ b/packages/taler-wallet-core/src/types/backupTypes.ts
@@ -39,6 +39,7 @@
* 10. Re-denominated payments/refreshes are not shown properly in the total
* payment cost.
* 11. Failed refunds do not have any information about why they failed.
+ * => This should go into the general "error reports"
*
* Questions:
* 1. What happens when two backups are merged that have
diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts
index a09bfcc0f..b917246fc 100644
--- a/packages/taler-wallet-core/src/wallet.ts
+++ b/packages/taler-wallet-core/src/wallet.ts
@@ -161,6 +161,7 @@ import {
codecForAddBackupProviderRequest,
runBackupCycle,
exportBackup,
+ importBackupPlain,
} from "./operations/backup";
const builtinCurrencies: CurrencyRecord[] = [
@@ -933,6 +934,14 @@ export class Wallet {
return testPay(this.ws.http, this, args);
}
+ async exportBackupPlain() {
+ return exportBackup(this.ws);
+ }
+
+ async importBackupPlain(backup: any) {
+ return importBackupPlain(this.ws, backup);
+ }
+
/**
* Implementation of the "wallet-core" API.
*/
diff --git a/packages/taler-wallet-webextension/manifest.json b/packages/taler-wallet-webextension/manifest.json
index 44dfe8cdd..8d25d062e 100644
--- a/packages/taler-wallet-webextension/manifest.json
+++ b/packages/taler-wallet-webextension/manifest.json
@@ -4,8 +4,8 @@
"name": "GNU Taler Wallet (git)",
"description": "Privacy preserving and transparent payments",
"author": "GNU Taler Developers",
- "version": "0.8.0.5",
- "version_name": "0.8.1-dev.1",
+ "version": "0.8.0.6",
+ "version_name": "0.8.1-dev.2",
"minimum_chrome_version": "51",
"minimum_opera_version": "36",
diff --git a/packages/taler-wallet-webextension/package.json b/packages/taler-wallet-webextension/package.json
index 5dc1f1b04..971cb3bf6 100644
--- a/packages/taler-wallet-webextension/package.json
+++ b/packages/taler-wallet-webextension/package.json
@@ -1,6 +1,6 @@
{
"name": "taler-wallet-webextension",
- "version": "0.8.1-dev.1",
+ "version": "0.8.1-dev.2",
"description": "GNU Taler Wallet browser extension",
"main": "./build/index.js",
"types": "./build/index.d.ts",