towards backup based on add/remove set instead of clocks
This commit is contained in:
parent
83b02069c9
commit
debc2254fd
@ -70,19 +70,13 @@ type BackupAmountString = string;
|
|||||||
*/
|
*/
|
||||||
type DeviceIdString = string;
|
type DeviceIdString = string;
|
||||||
|
|
||||||
/**
|
|
||||||
* Lamport clock timestamp.
|
|
||||||
*/
|
|
||||||
export interface ClockStamp {
|
|
||||||
deviceId: string;
|
|
||||||
value: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contract terms JSON.
|
* Contract terms JSON.
|
||||||
*/
|
*/
|
||||||
type RawContractTerms = any;
|
type RawContractTerms = any;
|
||||||
|
|
||||||
|
type OperationUid = string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Content of the backup.
|
* Content of the backup.
|
||||||
*
|
*
|
||||||
@ -115,16 +109,6 @@ export interface WalletBackupContentV1 {
|
|||||||
*/
|
*/
|
||||||
current_device_id: DeviceIdString;
|
current_device_id: DeviceIdString;
|
||||||
|
|
||||||
/**
|
|
||||||
* Monotonically increasing clock of the wallet,
|
|
||||||
* used to determine causality when merging backups.
|
|
||||||
*
|
|
||||||
* Information about other clocks, used to delete
|
|
||||||
* tombstones in the hopefully rare case that multiple wallets
|
|
||||||
* are connected to the same sync server.
|
|
||||||
*/
|
|
||||||
clocks: { [device_id: string]: number };
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Timestamp of the backup.
|
* Timestamp of the backup.
|
||||||
*
|
*
|
||||||
@ -182,21 +166,6 @@ export interface WalletBackupContentV1 {
|
|||||||
*/
|
*/
|
||||||
recoup_groups: BackupRecoupGroup[];
|
recoup_groups: BackupRecoupGroup[];
|
||||||
|
|
||||||
/**
|
|
||||||
* Tombstones for deleting purchases.
|
|
||||||
*/
|
|
||||||
purchase_tombstones: {
|
|
||||||
/**
|
|
||||||
* Clock when the purchase was deleted
|
|
||||||
*/
|
|
||||||
clock_deleted: ClockStamp;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Proposal ID identifying the purchase.
|
|
||||||
*/
|
|
||||||
proposal_id: string;
|
|
||||||
}[];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trusted auditors, either for official (3 letter) or local (4-12 letter)
|
* Trusted auditors, either for official (3 letter) or local (4-12 letter)
|
||||||
* currencies.
|
* currencies.
|
||||||
@ -224,6 +193,17 @@ export interface WalletBackupContentV1 {
|
|||||||
* Permanent error reports.
|
* Permanent error reports.
|
||||||
*/
|
*/
|
||||||
error_reports: BackupErrorReport[];
|
error_reports: BackupErrorReport[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletion tombstones. Sorted by (type, id)
|
||||||
|
* in ascending order.
|
||||||
|
*/
|
||||||
|
tombstones: Tombstone[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Tombstone {
|
||||||
|
type: string;
|
||||||
|
id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -256,17 +236,10 @@ export interface BackupTrustAuditor {
|
|||||||
auditor_pub: string;
|
auditor_pub: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clock when the auditor trust has been added.
|
* UIDs for the operation of adding this auditor
|
||||||
*
|
* as a trusted auditor.
|
||||||
* Can be undefined if this entry represents a removal delta
|
|
||||||
* from the wallet's defaults.
|
|
||||||
*/
|
*/
|
||||||
clock_added?: ClockStamp;
|
uids: OperationUid;
|
||||||
|
|
||||||
/**
|
|
||||||
* Clock for when the auditor trust has been removed.
|
|
||||||
*/
|
|
||||||
clock_removed?: ClockStamp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -289,17 +262,10 @@ export interface BackupTrustExchange {
|
|||||||
exchange_master_pub: string;
|
exchange_master_pub: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clock when the exchange trust has been added.
|
* UIDs for the operation of adding this exchange
|
||||||
*
|
* as trusted.
|
||||||
* Can be undefined if this entry represents a removal delta
|
|
||||||
* from the wallet's defaults.
|
|
||||||
*/
|
*/
|
||||||
clock_added?: ClockStamp;
|
uids: OperationUid;
|
||||||
|
|
||||||
/**
|
|
||||||
* Clock for when the exchange trust has been removed.
|
|
||||||
*/
|
|
||||||
clock_removed?: ClockStamp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class BackupBackupProviderTerms {
|
export class BackupBackupProviderTerms {
|
||||||
@ -483,11 +449,6 @@ export interface BackupCoin {
|
|||||||
* be refreshed in most situations.
|
* be refreshed in most situations.
|
||||||
*/
|
*/
|
||||||
fresh: boolean;
|
fresh: boolean;
|
||||||
|
|
||||||
/**
|
|
||||||
* Clock for the last update to current_amount/fresh.
|
|
||||||
*/
|
|
||||||
last_clock?: ClockStamp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -521,7 +482,6 @@ export interface BackupTip {
|
|||||||
timestamp_created: Timestamp;
|
timestamp_created: Timestamp;
|
||||||
|
|
||||||
timestamp_finished?: Timestamp;
|
timestamp_finished?: Timestamp;
|
||||||
finish_clock?: ClockStamp;
|
|
||||||
finish_is_failure?: boolean;
|
finish_is_failure?: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -549,7 +509,11 @@ export interface BackupTip {
|
|||||||
*/
|
*/
|
||||||
selected_denoms: BackupDenomSel;
|
selected_denoms: BackupDenomSel;
|
||||||
|
|
||||||
selected_denoms_clock?: ClockStamp;
|
/**
|
||||||
|
* UID for the denomination selection.
|
||||||
|
* Used to disambiguate when merging.
|
||||||
|
*/
|
||||||
|
selected_denoms_uid: OperationUid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -640,7 +604,6 @@ export interface BackupRefreshGroup {
|
|||||||
timestamp_created: Timestamp;
|
timestamp_created: Timestamp;
|
||||||
|
|
||||||
timestamp_finish?: Timestamp;
|
timestamp_finish?: Timestamp;
|
||||||
finish_clock?: ClockStamp;
|
|
||||||
finish_is_failure?: boolean;
|
finish_is_failure?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -664,7 +627,6 @@ export interface BackupWithdrawalGroup {
|
|||||||
timestamp_created: Timestamp;
|
timestamp_created: Timestamp;
|
||||||
|
|
||||||
timestamp_finish?: Timestamp;
|
timestamp_finish?: Timestamp;
|
||||||
finish_clock?: ClockStamp;
|
|
||||||
finish_is_failure?: boolean;
|
finish_is_failure?: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -682,7 +644,7 @@ export interface BackupWithdrawalGroup {
|
|||||||
*/
|
*/
|
||||||
selected_denoms: BackupDenomSel;
|
selected_denoms: BackupDenomSel;
|
||||||
|
|
||||||
selected_denoms_clock?: ClockStamp;
|
selected_denoms_id: OperationUid;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum BackupRefundState {
|
export enum BackupRefundState {
|
||||||
@ -731,8 +693,6 @@ export interface BackupRefundItemCommon {
|
|||||||
* accurately.
|
* accurately.
|
||||||
*/
|
*/
|
||||||
total_refresh_cost_bound: BackupAmountString;
|
total_refresh_cost_bound: BackupAmountString;
|
||||||
|
|
||||||
last_clock?: ClockStamp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -795,9 +755,9 @@ export interface BackupPurchase {
|
|||||||
}[];
|
}[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clock when the pay coin selection was made/updated.
|
* Unique ID to disambiguate pay coin selection on merge.
|
||||||
*/
|
*/
|
||||||
pay_coins_clock?: ClockStamp;
|
pay_coins_uid: OperationUid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Total cost initially shown to the user.
|
* Total cost initially shown to the user.
|
||||||
@ -841,11 +801,6 @@ export interface BackupPurchase {
|
|||||||
*/
|
*/
|
||||||
defunct?: boolean;
|
defunct?: boolean;
|
||||||
|
|
||||||
/**
|
|
||||||
* Clock for last update to defunct status.
|
|
||||||
*/
|
|
||||||
defunct_clock?: ClockStamp;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abort status of the payment.
|
* Abort status of the payment.
|
||||||
*/
|
*/
|
||||||
@ -1042,7 +997,6 @@ export interface BackupReserve {
|
|||||||
withdrawal_groups: BackupWithdrawalGroup[];
|
withdrawal_groups: BackupWithdrawalGroup[];
|
||||||
|
|
||||||
defective?: boolean;
|
defective?: boolean;
|
||||||
defective_clock?: ClockStamp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1196,17 +1150,10 @@ export interface BackupExchange {
|
|||||||
*/
|
*/
|
||||||
tos_etag_accepted: string | undefined;
|
tos_etag_accepted: string | undefined;
|
||||||
|
|
||||||
/**
|
|
||||||
* Clock value of the last update.
|
|
||||||
*/
|
|
||||||
last_clock?: ClockStamp;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should this exchange be considered defective?
|
* Should this exchange be considered defective?
|
||||||
*/
|
*/
|
||||||
defective?: boolean;
|
defective?: boolean;
|
||||||
|
|
||||||
defective_clock?: ClockStamp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum BackupProposalStatus {
|
export enum BackupProposalStatus {
|
||||||
@ -1284,8 +1231,6 @@ export interface BackupProposal {
|
|||||||
*/
|
*/
|
||||||
proposal_status: BackupProposalStatus;
|
proposal_status: BackupProposalStatus;
|
||||||
|
|
||||||
proposal_status_clock?: ClockStamp;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Proposal that this one got "redirected" to as part of
|
* Proposal that this one got "redirected" to as part of
|
||||||
* the repurchase detection.
|
* the repurchase detection.
|
||||||
|
@ -978,6 +978,8 @@ export interface TipRecord {
|
|||||||
*/
|
*/
|
||||||
denomsSel: DenomSelectionState;
|
denomsSel: DenomSelectionState;
|
||||||
|
|
||||||
|
denomSelUid: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tip ID chosen by the wallet.
|
* Tip ID chosen by the wallet.
|
||||||
*/
|
*/
|
||||||
@ -1310,6 +1312,8 @@ export interface PurchaseRecord {
|
|||||||
|
|
||||||
payCoinSelection: PayCoinSelection;
|
payCoinSelection: PayCoinSelection;
|
||||||
|
|
||||||
|
payCoinSelectionUid: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pending removals from pay coin selection.
|
* Pending removals from pay coin selection.
|
||||||
*
|
*
|
||||||
@ -1460,6 +1464,8 @@ export interface WithdrawalGroupRecord {
|
|||||||
|
|
||||||
denomsSel: DenomSelectionState;
|
denomsSel: DenomSelectionState;
|
||||||
|
|
||||||
|
denomSelUid: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retry info, always present even on completed operations so that indexing works.
|
* Retry info, always present even on completed operations so that indexing works.
|
||||||
*/
|
*/
|
||||||
@ -1564,12 +1570,6 @@ export interface BackupProviderRecord {
|
|||||||
*/
|
*/
|
||||||
lastBackupHash?: string;
|
lastBackupHash?: string;
|
||||||
|
|
||||||
/**
|
|
||||||
* Clock of the last backup that we already
|
|
||||||
* merged.
|
|
||||||
*/
|
|
||||||
lastBackupClock?: number;
|
|
||||||
|
|
||||||
lastBackupTimestamp?: Timestamp;
|
lastBackupTimestamp?: Timestamp;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -118,6 +118,7 @@ export async function exportBackup(
|
|||||||
timestamp_finish: wg.timestampFinish,
|
timestamp_finish: wg.timestampFinish,
|
||||||
withdrawal_group_id: wg.withdrawalGroupId,
|
withdrawal_group_id: wg.withdrawalGroupId,
|
||||||
secret_seed: wg.secretSeed,
|
secret_seed: wg.secretSeed,
|
||||||
|
selected_denoms_id: wg.denomSelUid,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -160,6 +161,7 @@ export async function exportBackup(
|
|||||||
timestamp_created: tip.createdTimestamp,
|
timestamp_created: tip.createdTimestamp,
|
||||||
timestamp_expiration: tip.tipExpiration,
|
timestamp_expiration: tip.tipExpiration,
|
||||||
tip_amount_raw: Amounts.stringify(tip.tipAmountRaw),
|
tip_amount_raw: Amounts.stringify(tip.tipAmountRaw),
|
||||||
|
selected_denoms_uid: tip.denomSelUid,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -363,6 +365,7 @@ export async function exportBackup(
|
|||||||
nonce_priv: purch.noncePriv,
|
nonce_priv: purch.noncePriv,
|
||||||
merchant_sig: purch.download.contractData.merchantSig,
|
merchant_sig: purch.download.contractData.merchantSig,
|
||||||
total_pay_cost: Amounts.stringify(purch.totalPayCost),
|
total_pay_cost: Amounts.stringify(purch.totalPayCost),
|
||||||
|
pay_coins_uid: purch.payCoinSelectionUid,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -446,13 +449,11 @@ export async function exportBackup(
|
|||||||
const backupBlob: WalletBackupContentV1 = {
|
const backupBlob: WalletBackupContentV1 = {
|
||||||
schema_id: "gnu-taler-wallet-backup-content",
|
schema_id: "gnu-taler-wallet-backup-content",
|
||||||
schema_version: 1,
|
schema_version: 1,
|
||||||
clocks: bs.clocks,
|
|
||||||
exchanges: backupExchanges,
|
exchanges: backupExchanges,
|
||||||
wallet_root_pub: bs.walletRootPub,
|
wallet_root_pub: bs.walletRootPub,
|
||||||
backup_providers: backupBackupProviders,
|
backup_providers: backupBackupProviders,
|
||||||
current_device_id: bs.deviceId,
|
current_device_id: bs.deviceId,
|
||||||
proposals: backupProposals,
|
proposals: backupProposals,
|
||||||
purchase_tombstones: [],
|
|
||||||
purchases: backupPurchases,
|
purchases: backupPurchases,
|
||||||
recoup_groups: backupRecoupGroups,
|
recoup_groups: backupRecoupGroups,
|
||||||
refresh_groups: backupRefreshGroups,
|
refresh_groups: backupRefreshGroups,
|
||||||
@ -462,13 +463,13 @@ export async function exportBackup(
|
|||||||
trusted_exchanges: {},
|
trusted_exchanges: {},
|
||||||
intern_table: {},
|
intern_table: {},
|
||||||
error_reports: [],
|
error_reports: [],
|
||||||
|
tombstones: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
// If the backup changed, we increment our clock.
|
// If the backup changed, we increment our clock.
|
||||||
|
|
||||||
let h = encodeCrock(hash(stringToBytes(canonicalJson(backupBlob))));
|
let h = encodeCrock(hash(stringToBytes(canonicalJson(backupBlob))));
|
||||||
if (h != bs.lastBackupPlainHash) {
|
if (h != bs.lastBackupPlainHash) {
|
||||||
backupBlob.clocks[bs.deviceId] = ++bs.clocks[bs.deviceId];
|
|
||||||
bs.lastBackupPlainHash = encodeCrock(
|
bs.lastBackupPlainHash = encodeCrock(
|
||||||
hash(stringToBytes(canonicalJson(backupBlob))),
|
hash(stringToBytes(canonicalJson(backupBlob))),
|
||||||
);
|
);
|
||||||
|
@ -302,7 +302,9 @@ export async function importBackup(
|
|||||||
denomPubHash,
|
denomPubHash,
|
||||||
]);
|
]);
|
||||||
if (!existingDenom) {
|
if (!existingDenom) {
|
||||||
logger.info(`importing backup denomination: ${j2s(backupDenomination)}`);
|
logger.info(
|
||||||
|
`importing backup denomination: ${j2s(backupDenomination)}`,
|
||||||
|
);
|
||||||
|
|
||||||
await tx.put(Stores.denominations, {
|
await tx.put(Stores.denominations, {
|
||||||
denomPub: backupDenomination.denom_pub,
|
denomPub: backupDenomination.denom_pub,
|
||||||
@ -446,6 +448,7 @@ export async function importBackup(
|
|||||||
timestampStart: backupWg.timestamp_created,
|
timestampStart: backupWg.timestamp_created,
|
||||||
timestampFinish: backupWg.timestamp_finish,
|
timestampFinish: backupWg.timestamp_finish,
|
||||||
withdrawalGroupId: backupWg.withdrawal_group_id,
|
withdrawalGroupId: backupWg.withdrawal_group_id,
|
||||||
|
denomSelUid: backupWg.selected_denoms_id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -695,6 +698,7 @@ export async function importBackup(
|
|||||||
coinDepositPermissions: undefined,
|
coinDepositPermissions: undefined,
|
||||||
totalPayCost: Amounts.parseOrThrow(backupPurchase.total_pay_cost),
|
totalPayCost: Amounts.parseOrThrow(backupPurchase.total_pay_cost),
|
||||||
refunds,
|
refunds,
|
||||||
|
payCoinSelectionUid: backupPurchase.pay_coins_uid,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -801,6 +805,7 @@ export async function importBackup(
|
|||||||
tipAmountRaw: Amounts.parseOrThrow(backupTip.tip_amount_raw),
|
tipAmountRaw: Amounts.parseOrThrow(backupTip.tip_amount_raw),
|
||||||
tipExpiration: backupTip.timestamp_expiration,
|
tipExpiration: backupTip.timestamp_expiration,
|
||||||
walletTipId: backupTip.wallet_tip_id,
|
walletTipId: backupTip.wallet_tip_id,
|
||||||
|
denomSelUid: backupTip.selected_denoms_uid,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -349,7 +349,6 @@ async function runBackupCycleForProvider(
|
|||||||
}
|
}
|
||||||
prov.lastBackupHash = encodeCrock(currentBackupHash);
|
prov.lastBackupHash = encodeCrock(currentBackupHash);
|
||||||
prov.lastBackupTimestamp = getTimestampNow();
|
prov.lastBackupTimestamp = getTimestampNow();
|
||||||
prov.lastBackupClock = backupJson.clocks[backupJson.current_device_id];
|
|
||||||
prov.lastError = undefined;
|
prov.lastError = undefined;
|
||||||
await tx.put(Stores.backupProviders, prov);
|
await tx.put(Stores.backupProviders, prov);
|
||||||
},
|
},
|
||||||
@ -372,7 +371,6 @@ async function runBackupCycleForProvider(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
prov.lastBackupHash = encodeCrock(hash(backupEnc));
|
prov.lastBackupHash = encodeCrock(hash(backupEnc));
|
||||||
prov.lastBackupClock = blob.clocks[blob.current_device_id];
|
|
||||||
prov.lastBackupTimestamp = getTimestampNow();
|
prov.lastBackupTimestamp = getTimestampNow();
|
||||||
prov.lastError = undefined;
|
prov.lastError = undefined;
|
||||||
await tx.put(Stores.backupProviders, prov);
|
await tx.put(Stores.backupProviders, prov);
|
||||||
@ -624,7 +622,6 @@ export async function getBackupInfo(
|
|||||||
for (const x of providerRecords) {
|
for (const x of providerRecords) {
|
||||||
providers.push({
|
providers.push({
|
||||||
active: x.active,
|
active: x.active,
|
||||||
lastRemoteClock: x.lastBackupClock,
|
|
||||||
syncProviderBaseUrl: x.baseUrl,
|
syncProviderBaseUrl: x.baseUrl,
|
||||||
lastBackupTimestamp: x.lastBackupTimestamp,
|
lastBackupTimestamp: x.lastBackupTimestamp,
|
||||||
paymentProposalIds: x.paymentProposalIds,
|
paymentProposalIds: x.paymentProposalIds,
|
||||||
@ -696,7 +693,6 @@ async function backupRecoveryTheirs(
|
|||||||
for (const prov of providers) {
|
for (const prov of providers) {
|
||||||
prov.lastBackupTimestamp = undefined;
|
prov.lastBackupTimestamp = undefined;
|
||||||
prov.lastBackupHash = undefined;
|
prov.lastBackupHash = undefined;
|
||||||
prov.lastBackupClock = undefined;
|
|
||||||
await tx.put(Stores.backupProviders, prov);
|
await tx.put(Stores.backupProviders, prov);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -406,6 +406,7 @@ async function recordConfirmPay(
|
|||||||
download: d,
|
download: d,
|
||||||
lastSessionId: sessionId,
|
lastSessionId: sessionId,
|
||||||
payCoinSelection: coinSelection,
|
payCoinSelection: coinSelection,
|
||||||
|
payCoinSelectionUid: encodeCrock(getRandomBytes(32)),
|
||||||
totalPayCost: payCostInfo,
|
totalPayCost: payCostInfo,
|
||||||
coinDepositPermissions,
|
coinDepositPermissions,
|
||||||
timestampAccept: getTimestampNow(),
|
timestampAccept: getTimestampNow(),
|
||||||
|
@ -633,6 +633,7 @@ async function updateReserve(
|
|||||||
lastError: undefined,
|
lastError: undefined,
|
||||||
denomsSel: denomSelectionInfoToState(denomSelInfo),
|
denomsSel: denomSelectionInfoToState(denomSelInfo),
|
||||||
secretSeed: encodeCrock(getRandomBytes(64)),
|
secretSeed: encodeCrock(getRandomBytes(64)),
|
||||||
|
denomSelUid: encodeCrock(getRandomBytes(32)),
|
||||||
};
|
};
|
||||||
|
|
||||||
newReserve.lastError = undefined;
|
newReserve.lastError = undefined;
|
||||||
|
@ -107,6 +107,7 @@ export async function prepareTip(
|
|||||||
const selectedDenoms = selectWithdrawalDenominations(amount, denoms);
|
const selectedDenoms = selectWithdrawalDenominations(amount, denoms);
|
||||||
|
|
||||||
const secretSeed = encodeCrock(getRandomBytes(64));
|
const secretSeed = encodeCrock(getRandomBytes(64));
|
||||||
|
const denomSelUid = encodeCrock(getRandomBytes(32));
|
||||||
|
|
||||||
tipRecord = {
|
tipRecord = {
|
||||||
walletTipId: walletTipId,
|
walletTipId: walletTipId,
|
||||||
@ -127,6 +128,7 @@ export async function prepareTip(
|
|||||||
denomsSel: denomSelectionInfoToState(selectedDenoms),
|
denomsSel: denomSelectionInfoToState(selectedDenoms),
|
||||||
pickedUpTimestamp: undefined,
|
pickedUpTimestamp: undefined,
|
||||||
secretSeed,
|
secretSeed,
|
||||||
|
denomSelUid,
|
||||||
};
|
};
|
||||||
await ws.db.put(Stores.tips, tipRecord);
|
await ws.db.put(Stores.tips, tipRecord);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user