renaming / dce
This commit is contained in:
parent
a92b7dc0df
commit
ded02bf11f
@ -30,7 +30,7 @@ window.addEventListener("load", () => {
|
|||||||
defaultJSExtensions: true,
|
defaultJSExtensions: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
System.import("../wxMessaging")
|
System.import("../wxBackend")
|
||||||
.then((wxMessaging: any) => {
|
.then((wxMessaging: any) => {
|
||||||
// Export as global for debugger
|
// Export as global for debugger
|
||||||
(window as any).wxMessaging = wxMessaging;
|
(window as any).wxMessaging = wxMessaging;
|
||||||
|
@ -21,12 +21,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
import {PreCoin, Coin, ReserveRecord, AmountJson} from "./types";
|
import {PreCoinRecord, CoinRecord, ReserveRecord, AmountJson} from "./types";
|
||||||
import {Denomination} from "./types";
|
import {Denomination} from "./types";
|
||||||
import {Offer} from "./wallet";
|
import {OfferRecord} from "./wallet";
|
||||||
import {CoinWithDenom} from "./wallet";
|
import {CoinWithDenom} from "./wallet";
|
||||||
import {PayCoinInfo} from "./types";
|
import {PayCoinInfo} from "./types";
|
||||||
import {RefreshSession} from "./types";
|
import {RefreshSessionRecord} from "./types";
|
||||||
|
|
||||||
|
|
||||||
interface WorkerState {
|
interface WorkerState {
|
||||||
@ -214,7 +214,7 @@ export class CryptoApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
createPreCoin(denom: Denomination, reserve: ReserveRecord): Promise<PreCoin> {
|
createPreCoin(denom: Denomination, reserve: ReserveRecord): Promise<PreCoinRecord> {
|
||||||
return this.doRpc("createPreCoin", 1, denom, reserve);
|
return this.doRpc("createPreCoin", 1, denom, reserve);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,7 +227,7 @@ export class CryptoApi {
|
|||||||
return this.doRpc("isValidDenom", 2, denom, masterPub);
|
return this.doRpc("isValidDenom", 2, denom, masterPub);
|
||||||
}
|
}
|
||||||
|
|
||||||
signDeposit(offer: Offer,
|
signDeposit(offer: OfferRecord,
|
||||||
cds: CoinWithDenom[]): Promise<PayCoinInfo> {
|
cds: CoinWithDenom[]): Promise<PayCoinInfo> {
|
||||||
return this.doRpc("signDeposit", 3, offer, cds);
|
return this.doRpc("signDeposit", 3, offer, cds);
|
||||||
}
|
}
|
||||||
@ -242,9 +242,9 @@ export class CryptoApi {
|
|||||||
|
|
||||||
createRefreshSession(exchangeBaseUrl: string,
|
createRefreshSession(exchangeBaseUrl: string,
|
||||||
kappa: number,
|
kappa: number,
|
||||||
meltCoin: Coin,
|
meltCoin: CoinRecord,
|
||||||
newCoinDenoms: Denomination[],
|
newCoinDenoms: Denomination[],
|
||||||
meltFee: AmountJson): Promise<RefreshSession> {
|
meltFee: AmountJson): Promise<RefreshSessionRecord> {
|
||||||
return this.doRpc("createRefreshSession",
|
return this.doRpc("createRefreshSession",
|
||||||
4,
|
4,
|
||||||
exchangeBaseUrl,
|
exchangeBaseUrl,
|
||||||
|
@ -23,13 +23,13 @@
|
|||||||
|
|
||||||
import * as native from "./emscriptif";
|
import * as native from "./emscriptif";
|
||||||
import {
|
import {
|
||||||
PreCoin, PayCoinInfo, AmountJson,
|
PreCoinRecord, PayCoinInfo, AmountJson,
|
||||||
RefreshSession, RefreshPreCoin, ReserveRecord
|
RefreshSessionRecord, RefreshPreCoinRecord, ReserveRecord
|
||||||
} from "./types";
|
} from "./types";
|
||||||
import create = chrome.alarms.create;
|
import create = chrome.alarms.create;
|
||||||
import {Offer} from "./wallet";
|
import {OfferRecord} from "./wallet";
|
||||||
import {CoinWithDenom} from "./wallet";
|
import {CoinWithDenom} from "./wallet";
|
||||||
import {CoinPaySig, Coin} from "./types";
|
import {CoinPaySig, CoinRecord} from "./types";
|
||||||
import {Denomination, Amounts} from "./types";
|
import {Denomination, Amounts} from "./types";
|
||||||
import {Amount} from "./emscriptif";
|
import {Amount} from "./emscriptif";
|
||||||
import {HashContext} from "./emscriptif";
|
import {HashContext} from "./emscriptif";
|
||||||
@ -68,7 +68,7 @@ namespace RpcFunctions {
|
|||||||
* reserve.
|
* reserve.
|
||||||
*/
|
*/
|
||||||
export function createPreCoin(denom: Denomination,
|
export function createPreCoin(denom: Denomination,
|
||||||
reserve: ReserveRecord): PreCoin {
|
reserve: ReserveRecord): PreCoinRecord {
|
||||||
let reservePriv = new native.EddsaPrivateKey();
|
let reservePriv = new native.EddsaPrivateKey();
|
||||||
reservePriv.loadCrock(reserve.reserve_priv);
|
reservePriv.loadCrock(reserve.reserve_priv);
|
||||||
let reservePub = new native.EddsaPublicKey();
|
let reservePub = new native.EddsaPublicKey();
|
||||||
@ -105,7 +105,7 @@ namespace RpcFunctions {
|
|||||||
|
|
||||||
var sig = native.eddsaSign(withdrawRequest.toPurpose(), reservePriv);
|
var sig = native.eddsaSign(withdrawRequest.toPurpose(), reservePriv);
|
||||||
|
|
||||||
let preCoin: PreCoin = {
|
let preCoin: PreCoinRecord = {
|
||||||
reservePub: reservePub.toCrock(),
|
reservePub: reservePub.toCrock(),
|
||||||
blindingKey: blindingFactor.toCrock(),
|
blindingKey: blindingFactor.toCrock(),
|
||||||
coinPub: coinPub.toCrock(),
|
coinPub: coinPub.toCrock(),
|
||||||
@ -170,7 +170,7 @@ namespace RpcFunctions {
|
|||||||
* Generate updated coins (to store in the database)
|
* Generate updated coins (to store in the database)
|
||||||
* and deposit permissions for each given coin.
|
* and deposit permissions for each given coin.
|
||||||
*/
|
*/
|
||||||
export function signDeposit(offer: Offer,
|
export function signDeposit(offer: OfferRecord,
|
||||||
cds: CoinWithDenom[]): PayCoinInfo {
|
cds: CoinWithDenom[]): PayCoinInfo {
|
||||||
let ret: PayCoinInfo = [];
|
let ret: PayCoinInfo = [];
|
||||||
let amountSpent = native.Amount.getZero(cds[0].coin.currentAmount.currency);
|
let amountSpent = native.Amount.getZero(cds[0].coin.currentAmount.currency);
|
||||||
@ -228,9 +228,9 @@ namespace RpcFunctions {
|
|||||||
|
|
||||||
export function createRefreshSession(exchangeBaseUrl: string,
|
export function createRefreshSession(exchangeBaseUrl: string,
|
||||||
kappa: number,
|
kappa: number,
|
||||||
meltCoin: Coin,
|
meltCoin: CoinRecord,
|
||||||
newCoinDenoms: Denomination[],
|
newCoinDenoms: Denomination[],
|
||||||
meltFee: AmountJson): RefreshSession {
|
meltFee: AmountJson): RefreshSessionRecord {
|
||||||
|
|
||||||
let valueWithFee = Amounts.getZero(newCoinDenoms[0].value.currency);
|
let valueWithFee = Amounts.getZero(newCoinDenoms[0].value.currency);
|
||||||
|
|
||||||
@ -248,7 +248,7 @@ namespace RpcFunctions {
|
|||||||
let transferPubs: string[] = [];
|
let transferPubs: string[] = [];
|
||||||
let transferPrivs: string[] = [];
|
let transferPrivs: string[] = [];
|
||||||
|
|
||||||
let preCoinsForGammas: RefreshPreCoin[][] = [];
|
let preCoinsForGammas: RefreshPreCoinRecord[][] = [];
|
||||||
|
|
||||||
for (let i = 0; i < kappa; i++) {
|
for (let i = 0; i < kappa; i++) {
|
||||||
let t = native.EcdhePrivateKey.create();
|
let t = native.EcdhePrivateKey.create();
|
||||||
@ -267,7 +267,7 @@ namespace RpcFunctions {
|
|||||||
sessionHc.read((new native.Amount(valueWithFee)).toNbo());
|
sessionHc.read((new native.Amount(valueWithFee)).toNbo());
|
||||||
|
|
||||||
for (let i = 0; i < kappa; i++) {
|
for (let i = 0; i < kappa; i++) {
|
||||||
let preCoins: RefreshPreCoin[] = [];
|
let preCoins: RefreshPreCoinRecord[] = [];
|
||||||
for (let j = 0; j < newCoinDenoms.length; j++) {
|
for (let j = 0; j < newCoinDenoms.length; j++) {
|
||||||
|
|
||||||
let transferPriv = native.EcdhePrivateKey.fromCrock(transferPrivs[i]);
|
let transferPriv = native.EcdhePrivateKey.fromCrock(transferPrivs[i]);
|
||||||
@ -287,7 +287,7 @@ namespace RpcFunctions {
|
|||||||
if (!ev) {
|
if (!ev) {
|
||||||
throw Error("couldn't blind (malicious exchange key?)");
|
throw Error("couldn't blind (malicious exchange key?)");
|
||||||
}
|
}
|
||||||
let preCoin: RefreshPreCoin = {
|
let preCoin: RefreshPreCoinRecord = {
|
||||||
blindingKey: blindingFactor.toCrock(),
|
blindingKey: blindingFactor.toCrock(),
|
||||||
coinEv: ev.toCrock(),
|
coinEv: ev.toCrock(),
|
||||||
publicKey: coinPub.toCrock(),
|
publicKey: coinPub.toCrock(),
|
||||||
@ -320,7 +320,7 @@ namespace RpcFunctions {
|
|||||||
valueOutput = Amounts.add(valueOutput, denom.value).amount;
|
valueOutput = Amounts.add(valueOutput, denom.value).amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
let refreshSession: RefreshSession = {
|
let refreshSession: RefreshSessionRecord = {
|
||||||
meltCoinPub: meltCoin.coinPub,
|
meltCoinPub: meltCoin.coinPub,
|
||||||
newDenoms: newCoinDenoms.map((d) => d.denom_pub),
|
newDenoms: newCoinDenoms.map((d) => d.denom_pub),
|
||||||
confirmSig,
|
confirmSig,
|
||||||
|
117
src/db.ts
117
src/db.ts
@ -1,117 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is part of TALER
|
|
||||||
(C) 2016 GNUnet e.V.
|
|
||||||
|
|
||||||
TALER is free software; you can redistribute it and/or modify it under the
|
|
||||||
terms of the GNU General Public License as published by the Free Software
|
|
||||||
Foundation; either version 3, or (at your option) any later version.
|
|
||||||
|
|
||||||
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along with
|
|
||||||
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
*/
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
import {IExchangeInfo} from "./types";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Declarations and helpers for
|
|
||||||
* things that are stored in the wallet's
|
|
||||||
* database.
|
|
||||||
* @module Db
|
|
||||||
* @author Florian Dold
|
|
||||||
*/
|
|
||||||
|
|
||||||
const DB_NAME = "taler";
|
|
||||||
const DB_VERSION = 11;
|
|
||||||
|
|
||||||
import {Stores} from "./wallet";
|
|
||||||
import {Store, Index} from "./query";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a promise that resolves
|
|
||||||
* to the taler wallet db.
|
|
||||||
*/
|
|
||||||
export function openTalerDb(): Promise<IDBDatabase> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const req = indexedDB.open(DB_NAME, DB_VERSION);
|
|
||||||
req.onerror = (e) => {
|
|
||||||
reject(e);
|
|
||||||
};
|
|
||||||
req.onsuccess = (e) => {
|
|
||||||
resolve(req.result);
|
|
||||||
};
|
|
||||||
req.onupgradeneeded = (e) => {
|
|
||||||
const db = req.result;
|
|
||||||
console.log("DB: upgrade needed: oldVersion = " + e.oldVersion);
|
|
||||||
switch (e.oldVersion) {
|
|
||||||
case 0: // DB does not exist yet
|
|
||||||
|
|
||||||
for (let n in Stores) {
|
|
||||||
if ((Stores as any)[n] instanceof Store) {
|
|
||||||
let si: Store<any> = (Stores as any)[n];
|
|
||||||
const s = db.createObjectStore(si.name, si.storeParams);
|
|
||||||
for (let indexName in (si as any)) {
|
|
||||||
if ((si as any)[indexName] instanceof Index) {
|
|
||||||
let ii: Index<any,any> = (si as any)[indexName];
|
|
||||||
s.createIndex(ii.indexName, ii.keyPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (e.oldVersion != DB_VERSION) {
|
|
||||||
window.alert("Incompatible wallet dababase version, please reset" +
|
|
||||||
" db.");
|
|
||||||
chrome.browserAction.setBadgeText({text: "err"});
|
|
||||||
chrome.browserAction.setBadgeBackgroundColor({color: "#F00"});
|
|
||||||
throw Error("incompatible DB");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export function exportDb(db: IDBDatabase): Promise<any> {
|
|
||||||
let dump = {
|
|
||||||
name: db.name,
|
|
||||||
version: db.version,
|
|
||||||
stores: {} as {[s: string]: any},
|
|
||||||
};
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
|
|
||||||
let tx = db.transaction(Array.from(db.objectStoreNames));
|
|
||||||
tx.addEventListener("complete", () => {
|
|
||||||
resolve(dump);
|
|
||||||
});
|
|
||||||
for (let i = 0; i < db.objectStoreNames.length; i++) {
|
|
||||||
let name = db.objectStoreNames[i];
|
|
||||||
let storeDump = {} as {[s: string]: any};
|
|
||||||
dump.stores[name] = storeDump;
|
|
||||||
let store = tx.objectStore(name)
|
|
||||||
.openCursor()
|
|
||||||
.addEventListener("success", (e: Event) => {
|
|
||||||
let cursor = (e.target as any).result;
|
|
||||||
if (cursor) {
|
|
||||||
storeDump[cursor.key] = cursor.value;
|
|
||||||
cursor.continue();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function deleteDb() {
|
|
||||||
indexedDB.deleteDatabase(DB_NAME);
|
|
||||||
}
|
|
@ -24,8 +24,8 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
import {substituteFulfillmentUrl} from "src/helpers";
|
import {substituteFulfillmentUrl} from "src/helpers";
|
||||||
import {Contract, AmountJson, IExchangeInfo} from "src/types";
|
import {Contract, AmountJson, ExchangeRecord} from "src/types";
|
||||||
import {Offer} from "src/wallet";
|
import {OfferRecord} from "src/wallet";
|
||||||
import {renderContract, prettyAmount} from "src/renderHtml";
|
import {renderContract, prettyAmount} from "src/renderHtml";
|
||||||
import {getExchanges} from "src/wxApi";
|
import {getExchanges} from "src/wxApi";
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ interface DetailState {
|
|||||||
interface DetailProps {
|
interface DetailProps {
|
||||||
contract: Contract
|
contract: Contract
|
||||||
collapsed: boolean
|
collapsed: boolean
|
||||||
exchanges: null|IExchangeInfo[];
|
exchanges: null|ExchangeRecord[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ class Details extends React.Component<DetailProps, DetailState> {
|
|||||||
Exchanges in the wallet:
|
Exchanges in the wallet:
|
||||||
<ul>
|
<ul>
|
||||||
{(this.props.exchanges || []).map(
|
{(this.props.exchanges || []).map(
|
||||||
(e: IExchangeInfo) =>
|
(e: ExchangeRecord) =>
|
||||||
<li>{`${e.baseUrl}: ${e.masterPublicKey}`}</li>)}
|
<li>{`${e.baseUrl}: ${e.masterPublicKey}`}</li>)}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -92,10 +92,10 @@ interface ContractPromptProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface ContractPromptState {
|
interface ContractPromptState {
|
||||||
offer: Offer|null;
|
offer: OfferRecord|null;
|
||||||
error: string|null;
|
error: string|null;
|
||||||
payDisabled: boolean;
|
payDisabled: boolean;
|
||||||
exchanges: null|IExchangeInfo[];
|
exchanges: null|ExchangeRecord[];
|
||||||
}
|
}
|
||||||
|
|
||||||
class ContractPrompt extends React.Component<ContractPromptProps, ContractPromptState> {
|
class ContractPrompt extends React.Component<ContractPromptProps, ContractPromptState> {
|
||||||
@ -125,7 +125,7 @@ class ContractPrompt extends React.Component<ContractPromptProps, ContractPrompt
|
|||||||
this.setState({exchanges} as any);
|
this.setState({exchanges} as any);
|
||||||
}
|
}
|
||||||
|
|
||||||
getOffer(): Promise<Offer> {
|
getOffer(): Promise<OfferRecord> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let msg = {
|
let msg = {
|
||||||
type: 'get-offer',
|
type: 'get-offer',
|
||||||
|
@ -21,8 +21,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
import { IExchangeInfo } from "src/types";
|
import { ExchangeRecord } from "src/types";
|
||||||
import { ReserveRecord, Coin, PreCoin, Denomination } from "src/types";
|
import { ReserveRecord, CoinRecord, PreCoinRecord, Denomination } from "src/types";
|
||||||
import { ImplicitStateComponent, StateHolder } from "src/components";
|
import { ImplicitStateComponent, StateHolder } from "src/components";
|
||||||
import {
|
import {
|
||||||
getReserves, getExchanges, getCoins, getPreCoins,
|
getReserves, getExchanges, getCoins, getPreCoins,
|
||||||
@ -87,11 +87,11 @@ class Toggle extends ImplicitStateComponent<ToggleProps> {
|
|||||||
|
|
||||||
|
|
||||||
interface CoinViewProps {
|
interface CoinViewProps {
|
||||||
coin: Coin;
|
coin: CoinRecord;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface RefreshDialogProps {
|
interface RefreshDialogProps {
|
||||||
coin: Coin;
|
coin: CoinRecord;
|
||||||
}
|
}
|
||||||
|
|
||||||
class RefreshDialog extends ImplicitStateComponent<RefreshDialogProps> {
|
class RefreshDialog extends ImplicitStateComponent<RefreshDialogProps> {
|
||||||
@ -134,7 +134,7 @@ class CoinView extends React.Component<CoinViewProps, void> {
|
|||||||
|
|
||||||
|
|
||||||
interface PreCoinViewProps {
|
interface PreCoinViewProps {
|
||||||
precoin: PreCoin;
|
precoin: PreCoinRecord;
|
||||||
}
|
}
|
||||||
|
|
||||||
class PreCoinView extends React.Component<PreCoinViewProps, void> {
|
class PreCoinView extends React.Component<PreCoinViewProps, void> {
|
||||||
@ -155,7 +155,7 @@ interface CoinListProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class CoinList extends ImplicitStateComponent<CoinListProps> {
|
class CoinList extends ImplicitStateComponent<CoinListProps> {
|
||||||
coins = this.makeState<Coin[] | null>(null);
|
coins = this.makeState<CoinRecord[] | null>(null);
|
||||||
expanded = this.makeState<boolean>(false);
|
expanded = this.makeState<boolean>(false);
|
||||||
|
|
||||||
constructor(props: CoinListProps) {
|
constructor(props: CoinListProps) {
|
||||||
@ -194,7 +194,7 @@ interface PreCoinListProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class PreCoinList extends ImplicitStateComponent<PreCoinListProps> {
|
class PreCoinList extends ImplicitStateComponent<PreCoinListProps> {
|
||||||
precoins = this.makeState<PreCoin[] | null>(null);
|
precoins = this.makeState<PreCoinRecord[] | null>(null);
|
||||||
expanded = this.makeState<boolean>(false);
|
expanded = this.makeState<boolean>(false);
|
||||||
|
|
||||||
constructor(props: PreCoinListProps) {
|
constructor(props: PreCoinListProps) {
|
||||||
@ -224,7 +224,7 @@ class PreCoinList extends ImplicitStateComponent<PreCoinListProps> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface DenominationListProps {
|
interface DenominationListProps {
|
||||||
exchange: IExchangeInfo;
|
exchange: ExchangeRecord;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ExpanderTextProps {
|
interface ExpanderTextProps {
|
||||||
@ -336,7 +336,7 @@ class ReserveList extends ImplicitStateComponent<ReserveListProps> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface ExchangeProps {
|
interface ExchangeProps {
|
||||||
exchange: IExchangeInfo;
|
exchange: ExchangeRecord;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ExchangeView extends React.Component<ExchangeProps, void> {
|
class ExchangeView extends React.Component<ExchangeProps, void> {
|
||||||
@ -358,7 +358,7 @@ class ExchangeView extends React.Component<ExchangeProps, void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface ExchangesListState {
|
interface ExchangesListState {
|
||||||
exchanges?: IExchangeInfo[];
|
exchanges?: ExchangeRecord[];
|
||||||
}
|
}
|
||||||
|
|
||||||
class ExchangesList extends React.Component<any, ExchangesListState> {
|
class ExchangesList extends React.Component<any, ExchangesListState> {
|
||||||
|
18
src/types.ts
18
src/types.ts
@ -132,7 +132,7 @@ export class Denomination {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface IExchangeInfo {
|
export interface ExchangeRecord {
|
||||||
baseUrl: string;
|
baseUrl: string;
|
||||||
masterPublicKey: string;
|
masterPublicKey: string;
|
||||||
|
|
||||||
@ -159,7 +159,7 @@ export interface WireInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ReserveCreationInfo {
|
export interface ReserveCreationInfo {
|
||||||
exchangeInfo: IExchangeInfo;
|
exchangeInfo: ExchangeRecord;
|
||||||
wireInfo: WireInfo;
|
wireInfo: WireInfo;
|
||||||
selectedDenoms: Denomination[];
|
selectedDenoms: Denomination[];
|
||||||
withdrawFee: AmountJson;
|
withdrawFee: AmountJson;
|
||||||
@ -170,7 +170,7 @@ export interface ReserveCreationInfo {
|
|||||||
/**
|
/**
|
||||||
* A coin that isn't yet signed by an exchange.
|
* A coin that isn't yet signed by an exchange.
|
||||||
*/
|
*/
|
||||||
export interface PreCoin {
|
export interface PreCoinRecord {
|
||||||
coinPub: string;
|
coinPub: string;
|
||||||
coinPriv: string;
|
coinPriv: string;
|
||||||
reservePub: string;
|
reservePub: string;
|
||||||
@ -182,7 +182,7 @@ export interface PreCoin {
|
|||||||
coinValue: AmountJson;
|
coinValue: AmountJson;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RefreshPreCoin {
|
export interface RefreshPreCoinRecord {
|
||||||
publicKey: string;
|
publicKey: string;
|
||||||
privateKey: string;
|
privateKey: string;
|
||||||
coinEv: string;
|
coinEv: string;
|
||||||
@ -193,7 +193,7 @@ export interface RefreshPreCoin {
|
|||||||
/**
|
/**
|
||||||
* Ongoing refresh
|
* Ongoing refresh
|
||||||
*/
|
*/
|
||||||
export interface RefreshSession {
|
export interface RefreshSessionRecord {
|
||||||
/**
|
/**
|
||||||
* Public key that's being melted in this session.
|
* Public key that's being melted in this session.
|
||||||
*/
|
*/
|
||||||
@ -222,7 +222,7 @@ export interface RefreshSession {
|
|||||||
newDenoms: string[];
|
newDenoms: string[];
|
||||||
|
|
||||||
|
|
||||||
preCoinsForGammas: RefreshPreCoin[][];
|
preCoinsForGammas: RefreshPreCoinRecord[][];
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -257,10 +257,10 @@ export interface CoinPaySig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Coin as stored in the "coins" data store
|
* CoinRecord as stored in the "coins" data store
|
||||||
* of the wallet database.
|
* of the wallet database.
|
||||||
*/
|
*/
|
||||||
export interface Coin {
|
export interface CoinRecord {
|
||||||
/**
|
/**
|
||||||
* Public key of the coin.
|
* Public key of the coin.
|
||||||
*/
|
*/
|
||||||
@ -436,7 +436,7 @@ export class Contract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export type PayCoinInfo = Array<{ updatedCoin: Coin, sig: CoinPaySig }>;
|
export type PayCoinInfo = Array<{ updatedCoin: CoinRecord, sig: CoinPaySig }>;
|
||||||
|
|
||||||
|
|
||||||
export namespace Amounts {
|
export namespace Amounts {
|
||||||
|
146
src/wallet.ts
146
src/wallet.ts
@ -25,17 +25,17 @@ import {
|
|||||||
AmountJson,
|
AmountJson,
|
||||||
Amounts,
|
Amounts,
|
||||||
CheckRepurchaseResult,
|
CheckRepurchaseResult,
|
||||||
Coin,
|
CoinRecord,
|
||||||
CoinPaySig,
|
CoinPaySig,
|
||||||
Contract,
|
Contract,
|
||||||
CreateReserveResponse,
|
CreateReserveResponse,
|
||||||
Denomination,
|
Denomination,
|
||||||
ExchangeHandle,
|
ExchangeHandle,
|
||||||
IExchangeInfo,
|
ExchangeRecord,
|
||||||
Notifier,
|
Notifier,
|
||||||
PayCoinInfo,
|
PayCoinInfo,
|
||||||
PreCoin,
|
PreCoinRecord,
|
||||||
RefreshSession,
|
RefreshSessionRecord,
|
||||||
ReserveCreationInfo,
|
ReserveCreationInfo,
|
||||||
ReserveRecord,
|
ReserveRecord,
|
||||||
WalletBalance,
|
WalletBalance,
|
||||||
@ -68,7 +68,7 @@ import {CryptoApi} from "./cryptoApi";
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
export interface CoinWithDenom {
|
export interface CoinWithDenom {
|
||||||
coin: Coin;
|
coin: CoinRecord;
|
||||||
denom: Denomination;
|
denom: Denomination;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,7 +132,7 @@ export class ConfirmReserveRequest {
|
|||||||
|
|
||||||
|
|
||||||
@Checkable.Class
|
@Checkable.Class
|
||||||
export class Offer {
|
export class OfferRecord {
|
||||||
@Checkable.Value(Contract)
|
@Checkable.Value(Contract)
|
||||||
contract: Contract;
|
contract: Contract;
|
||||||
|
|
||||||
@ -151,7 +151,7 @@ export class Offer {
|
|||||||
@Checkable.Optional(Checkable.Number)
|
@Checkable.Optional(Checkable.Number)
|
||||||
id?: number;
|
id?: number;
|
||||||
|
|
||||||
static checked: (obj: any) => Offer;
|
static checked: (obj: any) => OfferRecord;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface HistoryRecord {
|
export interface HistoryRecord {
|
||||||
@ -163,10 +163,6 @@ export interface HistoryRecord {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
interface ExchangeCoins {
|
|
||||||
[exchangeUrl: string]: CoinWithDenom[];
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PayReq {
|
interface PayReq {
|
||||||
amount: AmountJson;
|
amount: AmountJson;
|
||||||
coins: CoinPaySig[];
|
coins: CoinPaySig[];
|
||||||
@ -185,7 +181,7 @@ interface PayReq {
|
|||||||
instance?: string;
|
instance?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Transaction {
|
interface TransactionRecord {
|
||||||
contractHash: string;
|
contractHash: string;
|
||||||
contract: Contract;
|
contract: Contract;
|
||||||
payReq: PayReq;
|
payReq: PayReq;
|
||||||
@ -303,20 +299,20 @@ function getWithdrawDenomList(amountAvailable: AmountJson,
|
|||||||
|
|
||||||
|
|
||||||
export namespace Stores {
|
export namespace Stores {
|
||||||
class ExchangeStore extends Store<IExchangeInfo> {
|
class ExchangeStore extends Store<ExchangeRecord> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("exchanges", {keyPath: "baseUrl"});
|
super("exchanges", {keyPath: "baseUrl"});
|
||||||
}
|
}
|
||||||
|
|
||||||
pubKeyIndex = new Index<string,IExchangeInfo>(this, "pubKey", "masterPublicKey");
|
pubKeyIndex = new Index<string,ExchangeRecord>(this, "pubKey", "masterPublicKey");
|
||||||
}
|
}
|
||||||
|
|
||||||
class CoinsStore extends Store<Coin> {
|
class CoinsStore extends Store<CoinRecord> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("coins", {keyPath: "coinPub"});
|
super("coins", {keyPath: "coinPub"});
|
||||||
}
|
}
|
||||||
|
|
||||||
exchangeBaseUrlIndex = new Index<string,Coin>(this, "exchangeBaseUrl", "exchangeBaseUrl");
|
exchangeBaseUrlIndex = new Index<string,CoinRecord>(this, "exchangeBaseUrl", "exchangeBaseUrl");
|
||||||
}
|
}
|
||||||
|
|
||||||
class HistoryStore extends Store<HistoryRecord> {
|
class HistoryStore extends Store<HistoryRecord> {
|
||||||
@ -330,7 +326,7 @@ export namespace Stores {
|
|||||||
timestampIndex = new Index<number,HistoryRecord>(this, "timestamp", "timestamp");
|
timestampIndex = new Index<number,HistoryRecord>(this, "timestamp", "timestamp");
|
||||||
}
|
}
|
||||||
|
|
||||||
class OffersStore extends Store<Offer> {
|
class OffersStore extends Store<OfferRecord> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("offers", {
|
super("offers", {
|
||||||
keyPath: "id",
|
keyPath: "id",
|
||||||
@ -339,12 +335,12 @@ export namespace Stores {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TransactionsStore extends Store<Transaction> {
|
class TransactionsStore extends Store<TransactionRecord> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("transactions", {keyPath: "contractHash"});
|
super("transactions", {keyPath: "contractHash"});
|
||||||
}
|
}
|
||||||
|
|
||||||
repurchaseIndex = new Index<[string,string],Transaction>(this, "repurchase", [
|
repurchaseIndex = new Index<[string,string],TransactionRecord>(this, "repurchase", [
|
||||||
"contract.merchant_pub",
|
"contract.merchant_pub",
|
||||||
"contract.repurchase_correlation_id"
|
"contract.repurchase_correlation_id"
|
||||||
]);
|
]);
|
||||||
@ -354,10 +350,10 @@ export namespace Stores {
|
|||||||
export let transactions: TransactionsStore = new TransactionsStore();
|
export let transactions: TransactionsStore = new TransactionsStore();
|
||||||
export let reserves: Store<ReserveRecord> = new Store<ReserveRecord>("reserves", {keyPath: "reserve_pub"});
|
export let reserves: Store<ReserveRecord> = new Store<ReserveRecord>("reserves", {keyPath: "reserve_pub"});
|
||||||
export let coins: CoinsStore = new CoinsStore();
|
export let coins: CoinsStore = new CoinsStore();
|
||||||
export let refresh: Store<RefreshSession> = new Store<RefreshSession>("refresh", {keyPath: "meltCoinPub"});
|
export let refresh: Store<RefreshSessionRecord> = new Store<RefreshSessionRecord>("refresh", {keyPath: "meltCoinPub"});
|
||||||
export let history: HistoryStore = new HistoryStore();
|
export let history: HistoryStore = new HistoryStore();
|
||||||
export let offers: OffersStore = new OffersStore();
|
export let offers: OffersStore = new OffersStore();
|
||||||
export let precoins: Store<PreCoin> = new Store<PreCoin>("precoins", {keyPath: "coinPub"});
|
export let precoins: Store<PreCoinRecord> = new Store<PreCoinRecord>("precoins", {keyPath: "coinPub"});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -442,14 +438,14 @@ export class Wallet {
|
|||||||
|
|
||||||
this.q()
|
this.q()
|
||||||
.iter(Stores.refresh)
|
.iter(Stores.refresh)
|
||||||
.reduce((r: RefreshSession) => {
|
.reduce((r: RefreshSessionRecord) => {
|
||||||
this.continueRefreshSession(r);
|
this.continueRefreshSession(r);
|
||||||
});
|
});
|
||||||
|
|
||||||
// FIXME: optimize via index
|
// FIXME: optimize via index
|
||||||
this.q()
|
this.q()
|
||||||
.iter(Stores.coins)
|
.iter(Stores.coins)
|
||||||
.reduce((c: Coin) => {
|
.reduce((c: CoinRecord) => {
|
||||||
if (c.dirty && !c.transactionPending) {
|
if (c.dirty && !c.transactionPending) {
|
||||||
this.refresh(c.coinPub);
|
this.refresh(c.coinPub);
|
||||||
}
|
}
|
||||||
@ -471,7 +467,7 @@ export class Wallet {
|
|||||||
console.error("db inconsistent");
|
console.error("db inconsistent");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let coins: Coin[] = await this.q().iterIndex(Stores.coins.exchangeBaseUrlIndex, exchangeHandle.url).toArray();
|
let coins: CoinRecord[] = await this.q().iterIndex(Stores.coins.exchangeBaseUrlIndex, exchangeHandle.url).toArray();
|
||||||
if (!coins || coins.length == 0) {
|
if (!coins || coins.length == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -515,7 +511,7 @@ export class Wallet {
|
|||||||
* Record all information that is necessary to
|
* Record all information that is necessary to
|
||||||
* pay for a contract in the wallet's database.
|
* pay for a contract in the wallet's database.
|
||||||
*/
|
*/
|
||||||
private async recordConfirmPay(offer: Offer,
|
private async recordConfirmPay(offer: OfferRecord,
|
||||||
payCoinInfo: PayCoinInfo,
|
payCoinInfo: PayCoinInfo,
|
||||||
chosenExchange: string): Promise<void> {
|
chosenExchange: string): Promise<void> {
|
||||||
let payReq: PayReq = {
|
let payReq: PayReq = {
|
||||||
@ -531,7 +527,7 @@ export class Wallet {
|
|||||||
transaction_id: offer.contract.transaction_id,
|
transaction_id: offer.contract.transaction_id,
|
||||||
instance: offer.contract.merchant.instance
|
instance: offer.contract.merchant.instance
|
||||||
};
|
};
|
||||||
let t: Transaction = {
|
let t: TransactionRecord = {
|
||||||
contractHash: offer.H_contract,
|
contractHash: offer.H_contract,
|
||||||
contract: offer.contract,
|
contract: offer.contract,
|
||||||
payReq: payReq,
|
payReq: payReq,
|
||||||
@ -568,7 +564,7 @@ export class Wallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async saveOffer(offer: Offer): Promise<number> {
|
async saveOffer(offer: OfferRecord): Promise<number> {
|
||||||
console.log(`saving offer in wallet.ts`);
|
console.log(`saving offer in wallet.ts`);
|
||||||
let id = await this.q().putWithResult(Stores.offers, offer);
|
let id = await this.q().putWithResult(Stores.offers, offer);
|
||||||
this.notifier.notify();
|
this.notifier.notify();
|
||||||
@ -584,7 +580,7 @@ export class Wallet {
|
|||||||
* Add a contract to the wallet and sign coins,
|
* Add a contract to the wallet and sign coins,
|
||||||
* but do not send them yet.
|
* but do not send them yet.
|
||||||
*/
|
*/
|
||||||
async confirmPay(offer: Offer): Promise<any> {
|
async confirmPay(offer: OfferRecord): Promise<any> {
|
||||||
console.log("executing confirmPay");
|
console.log("executing confirmPay");
|
||||||
|
|
||||||
let transaction = await this.q().get(Stores.transactions, offer.H_contract);
|
let transaction = await this.q().get(Stores.transactions, offer.H_contract);
|
||||||
@ -618,7 +614,7 @@ export class Wallet {
|
|||||||
* Add a contract to the wallet and sign coins,
|
* Add a contract to the wallet and sign coins,
|
||||||
* but do not send them yet.
|
* but do not send them yet.
|
||||||
*/
|
*/
|
||||||
async checkPay(offer: Offer): Promise<any> {
|
async checkPay(offer: OfferRecord): Promise<any> {
|
||||||
// First check if we already payed for it.
|
// First check if we already payed for it.
|
||||||
let transaction = await this.q().get(Stores.transactions, offer.H_contract);
|
let transaction = await this.q().get(Stores.transactions, offer.H_contract);
|
||||||
if (transaction) {
|
if (transaction) {
|
||||||
@ -645,7 +641,7 @@ export class Wallet {
|
|||||||
* with the given hash.
|
* with the given hash.
|
||||||
*/
|
*/
|
||||||
async executePayment(H_contract: string): Promise<any> {
|
async executePayment(H_contract: string): Promise<any> {
|
||||||
let t = await this.q().get<Transaction>(Stores.transactions, H_contract);
|
let t = await this.q().get<TransactionRecord>(Stores.transactions, H_contract);
|
||||||
if (!t) {
|
if (!t) {
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
@ -704,7 +700,7 @@ export class Wallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private async processPreCoin(preCoin: PreCoin,
|
private async processPreCoin(preCoin: PreCoinRecord,
|
||||||
retryDelayMs = 100): Promise<void> {
|
retryDelayMs = 100): Promise<void> {
|
||||||
|
|
||||||
let exchange = await this.q().get(Stores.exchanges,
|
let exchange = await this.q().get(Stores.exchanges,
|
||||||
@ -852,7 +848,7 @@ export class Wallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private async withdrawExecute(pc: PreCoin): Promise<Coin> {
|
private async withdrawExecute(pc: PreCoinRecord): Promise<CoinRecord> {
|
||||||
let reserve = await this.q().get<ReserveRecord>(Stores.reserves,
|
let reserve = await this.q().get<ReserveRecord>(Stores.reserves,
|
||||||
pc.reservePub);
|
pc.reservePub);
|
||||||
|
|
||||||
@ -879,7 +875,7 @@ export class Wallet {
|
|||||||
let denomSig = await this.cryptoApi.rsaUnblind(r.ev_sig,
|
let denomSig = await this.cryptoApi.rsaUnblind(r.ev_sig,
|
||||||
pc.blindingKey,
|
pc.blindingKey,
|
||||||
pc.denomPub);
|
pc.denomPub);
|
||||||
let coin: Coin = {
|
let coin: CoinRecord = {
|
||||||
coinPub: pc.coinPub,
|
coinPub: pc.coinPub,
|
||||||
coinPriv: pc.coinPriv,
|
coinPriv: pc.coinPriv,
|
||||||
denomPub: pc.denomPub,
|
denomPub: pc.denomPub,
|
||||||
@ -897,7 +893,7 @@ export class Wallet {
|
|||||||
* Withdraw coins from a reserve until it is empty.
|
* Withdraw coins from a reserve until it is empty.
|
||||||
*/
|
*/
|
||||||
private async depleteReserve(reserve: ReserveRecord,
|
private async depleteReserve(reserve: ReserveRecord,
|
||||||
exchange: IExchangeInfo): Promise<number> {
|
exchange: ExchangeRecord): Promise<number> {
|
||||||
if (!reserve.current_amount) {
|
if (!reserve.current_amount) {
|
||||||
throw Error("can't withdraw when amount is unknown");
|
throw Error("can't withdraw when amount is unknown");
|
||||||
}
|
}
|
||||||
@ -947,7 +943,7 @@ export class Wallet {
|
|||||||
* by quering the reserve's exchange.
|
* by quering the reserve's exchange.
|
||||||
*/
|
*/
|
||||||
private async updateReserve(reservePub: string,
|
private async updateReserve(reservePub: string,
|
||||||
exchange: IExchangeInfo): Promise<ReserveRecord> {
|
exchange: ExchangeRecord): Promise<ReserveRecord> {
|
||||||
let reserve = await this.q()
|
let reserve = await this.q()
|
||||||
.get<ReserveRecord>(Stores.reserves, reservePub);
|
.get<ReserveRecord>(Stores.reserves, reservePub);
|
||||||
if (!reserve) {
|
if (!reserve) {
|
||||||
@ -1037,7 +1033,7 @@ export class Wallet {
|
|||||||
* Optionally link the reserve entry to the new or existing
|
* Optionally link the reserve entry to the new or existing
|
||||||
* exchange entry in then DB.
|
* exchange entry in then DB.
|
||||||
*/
|
*/
|
||||||
async updateExchangeFromUrl(baseUrl: string): Promise<IExchangeInfo> {
|
async updateExchangeFromUrl(baseUrl: string): Promise<ExchangeRecord> {
|
||||||
baseUrl = canonicalizeBaseUrl(baseUrl);
|
baseUrl = canonicalizeBaseUrl(baseUrl);
|
||||||
let reqUrl = URI("keys").absoluteTo(baseUrl);
|
let reqUrl = URI("keys").absoluteTo(baseUrl);
|
||||||
let resp = await this.http.get(reqUrl);
|
let resp = await this.http.get(reqUrl);
|
||||||
@ -1048,11 +1044,11 @@ export class Wallet {
|
|||||||
return this.updateExchangeFromJson(baseUrl, exchangeKeysJson);
|
return this.updateExchangeFromJson(baseUrl, exchangeKeysJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async suspendCoins(exchangeInfo: IExchangeInfo): Promise<void> {
|
private async suspendCoins(exchangeInfo: ExchangeRecord): Promise<void> {
|
||||||
let suspendedCoins = await (
|
let suspendedCoins = await (
|
||||||
this.q()
|
this.q()
|
||||||
.iterIndex(Stores.coins.exchangeBaseUrlIndex, exchangeInfo.baseUrl)
|
.iterIndex(Stores.coins.exchangeBaseUrlIndex, exchangeInfo.baseUrl)
|
||||||
.reduce((coin: Coin, suspendedCoins: Coin[]) => {
|
.reduce((coin: CoinRecord, suspendedCoins: CoinRecord[]) => {
|
||||||
if (!exchangeInfo.active_denoms.find((c) => c.denom_pub == coin.denomPub)) {
|
if (!exchangeInfo.active_denoms.find((c) => c.denom_pub == coin.denomPub)) {
|
||||||
return Array.prototype.concat(suspendedCoins, [coin]);
|
return Array.prototype.concat(suspendedCoins, [coin]);
|
||||||
}
|
}
|
||||||
@ -1070,15 +1066,15 @@ export class Wallet {
|
|||||||
|
|
||||||
|
|
||||||
private async updateExchangeFromJson(baseUrl: string,
|
private async updateExchangeFromJson(baseUrl: string,
|
||||||
exchangeKeysJson: KeysJson): Promise<IExchangeInfo> {
|
exchangeKeysJson: KeysJson): Promise<ExchangeRecord> {
|
||||||
const updateTimeSec = getTalerStampSec(exchangeKeysJson.list_issue_date);
|
const updateTimeSec = getTalerStampSec(exchangeKeysJson.list_issue_date);
|
||||||
if (updateTimeSec === null) {
|
if (updateTimeSec === null) {
|
||||||
throw Error("invalid update time");
|
throw Error("invalid update time");
|
||||||
}
|
}
|
||||||
|
|
||||||
let r = await this.q().get<IExchangeInfo>(Stores.exchanges, baseUrl);
|
let r = await this.q().get<ExchangeRecord>(Stores.exchanges, baseUrl);
|
||||||
|
|
||||||
let exchangeInfo: IExchangeInfo;
|
let exchangeInfo: ExchangeRecord;
|
||||||
|
|
||||||
if (!r) {
|
if (!r) {
|
||||||
exchangeInfo = {
|
exchangeInfo = {
|
||||||
@ -1110,8 +1106,8 @@ export class Wallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private async updateExchangeInfo(exchangeInfo: IExchangeInfo,
|
private async updateExchangeInfo(exchangeInfo: ExchangeRecord,
|
||||||
newKeys: KeysJson): Promise<IExchangeInfo> {
|
newKeys: KeysJson): Promise<ExchangeRecord> {
|
||||||
if (exchangeInfo.masterPublicKey != newKeys.master_public_key) {
|
if (exchangeInfo.masterPublicKey != newKeys.master_public_key) {
|
||||||
throw Error("public keys do not match");
|
throw Error("public keys do not match");
|
||||||
}
|
}
|
||||||
@ -1186,7 +1182,7 @@ export class Wallet {
|
|||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
function collectBalances(c: Coin, balance: WalletBalance) {
|
function collectBalances(c: CoinRecord, balance: WalletBalance) {
|
||||||
if (c.suspended) {
|
if (c.suspended) {
|
||||||
return balance;
|
return balance;
|
||||||
}
|
}
|
||||||
@ -1213,7 +1209,7 @@ export class Wallet {
|
|||||||
return balance;
|
return balance;
|
||||||
}
|
}
|
||||||
|
|
||||||
function collectPendingRefresh(r: RefreshSession, balance: WalletBalance) {
|
function collectPendingRefresh(r: RefreshSessionRecord, balance: WalletBalance) {
|
||||||
if (!r.finished) {
|
if (!r.finished) {
|
||||||
return balance;
|
return balance;
|
||||||
}
|
}
|
||||||
@ -1224,7 +1220,7 @@ export class Wallet {
|
|||||||
return balance;
|
return balance;
|
||||||
}
|
}
|
||||||
|
|
||||||
function collectPayments(t: Transaction, balance: WalletBalance) {
|
function collectPayments(t: TransactionRecord, balance: WalletBalance) {
|
||||||
if (t.finished) {
|
if (t.finished) {
|
||||||
return balance;
|
return balance;
|
||||||
}
|
}
|
||||||
@ -1235,7 +1231,7 @@ export class Wallet {
|
|||||||
return balance;
|
return balance;
|
||||||
}
|
}
|
||||||
|
|
||||||
function collectSmallestWithdraw(e: IExchangeInfo, sw: any) {
|
function collectSmallestWithdraw(e: ExchangeRecord, sw: any) {
|
||||||
let min: AmountJson|undefined;
|
let min: AmountJson|undefined;
|
||||||
for (let d of e.active_denoms) {
|
for (let d of e.active_denoms) {
|
||||||
let v = Amounts.add(d.value, d.fee_withdraw).amount;
|
let v = Amounts.add(d.value, d.fee_withdraw).amount;
|
||||||
@ -1277,8 +1273,8 @@ export class Wallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async createRefreshSession(oldCoinPub: string): Promise<RefreshSession|undefined> {
|
async createRefreshSession(oldCoinPub: string): Promise<RefreshSessionRecord|undefined> {
|
||||||
let coin = await this.q().get<Coin>(Stores.coins, oldCoinPub);
|
let coin = await this.q().get<CoinRecord>(Stores.coins, oldCoinPub);
|
||||||
|
|
||||||
if (!coin) {
|
if (!coin) {
|
||||||
throw Error("coin not found");
|
throw Error("coin not found");
|
||||||
@ -1312,14 +1308,14 @@ export class Wallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
let refreshSession: RefreshSession = await (
|
let refreshSession: RefreshSessionRecord = await (
|
||||||
this.cryptoApi.createRefreshSession(exchange.baseUrl,
|
this.cryptoApi.createRefreshSession(exchange.baseUrl,
|
||||||
3,
|
3,
|
||||||
coin,
|
coin,
|
||||||
newCoinDenoms,
|
newCoinDenoms,
|
||||||
oldDenom.fee_refresh));
|
oldDenom.fee_refresh));
|
||||||
|
|
||||||
function mutateCoin(c: Coin): Coin {
|
function mutateCoin(c: CoinRecord): CoinRecord {
|
||||||
let r = Amounts.sub(c.currentAmount,
|
let r = Amounts.sub(c.currentAmount,
|
||||||
refreshSession.valueWithFee);
|
refreshSession.valueWithFee);
|
||||||
if (r.saturated) {
|
if (r.saturated) {
|
||||||
@ -1340,7 +1336,7 @@ export class Wallet {
|
|||||||
|
|
||||||
|
|
||||||
async refresh(oldCoinPub: string): Promise<void> {
|
async refresh(oldCoinPub: string): Promise<void> {
|
||||||
let refreshSession: RefreshSession|undefined;
|
let refreshSession: RefreshSessionRecord|undefined;
|
||||||
let oldSession = await this.q().get(Stores.refresh, oldCoinPub);
|
let oldSession = await this.q().get(Stores.refresh, oldCoinPub);
|
||||||
if (oldSession) {
|
if (oldSession) {
|
||||||
refreshSession = oldSession;
|
refreshSession = oldSession;
|
||||||
@ -1354,14 +1350,14 @@ export class Wallet {
|
|||||||
this.continueRefreshSession(refreshSession);
|
this.continueRefreshSession(refreshSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
async continueRefreshSession(refreshSession: RefreshSession) {
|
async continueRefreshSession(refreshSession: RefreshSessionRecord) {
|
||||||
if (refreshSession.finished) {
|
if (refreshSession.finished) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (typeof refreshSession.norevealIndex !== "number") {
|
if (typeof refreshSession.norevealIndex !== "number") {
|
||||||
let coinPub = refreshSession.meltCoinPub;
|
let coinPub = refreshSession.meltCoinPub;
|
||||||
await this.refreshMelt(refreshSession);
|
await this.refreshMelt(refreshSession);
|
||||||
let r = await this.q().get<RefreshSession>(Stores.refresh, coinPub);
|
let r = await this.q().get<RefreshSessionRecord>(Stores.refresh, coinPub);
|
||||||
if (!r) {
|
if (!r) {
|
||||||
throw Error("refresh session does not exist anymore");
|
throw Error("refresh session does not exist anymore");
|
||||||
}
|
}
|
||||||
@ -1372,14 +1368,14 @@ export class Wallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async refreshMelt(refreshSession: RefreshSession): Promise<void> {
|
async refreshMelt(refreshSession: RefreshSessionRecord): Promise<void> {
|
||||||
if (refreshSession.norevealIndex != undefined) {
|
if (refreshSession.norevealIndex != undefined) {
|
||||||
console.error("won't melt again");
|
console.error("won't melt again");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let coin = await this.q().get<Coin>(Stores.coins,
|
let coin = await this.q().get<CoinRecord>(Stores.coins,
|
||||||
refreshSession.meltCoinPub);
|
refreshSession.meltCoinPub);
|
||||||
if (!coin) {
|
if (!coin) {
|
||||||
console.error("can't melt coin, it does not exist");
|
console.error("can't melt coin, it does not exist");
|
||||||
return;
|
return;
|
||||||
@ -1429,7 +1425,7 @@ export class Wallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async refreshReveal(refreshSession: RefreshSession): Promise<void> {
|
async refreshReveal(refreshSession: RefreshSessionRecord): Promise<void> {
|
||||||
let norevealIndex = refreshSession.norevealIndex;
|
let norevealIndex = refreshSession.norevealIndex;
|
||||||
if (norevealIndex == undefined) {
|
if (norevealIndex == undefined) {
|
||||||
throw Error("can't reveal without melting first");
|
throw Error("can't reveal without melting first");
|
||||||
@ -1461,14 +1457,14 @@ export class Wallet {
|
|||||||
console.log("/refresh/reveal did not contain ev_sigs");
|
console.log("/refresh/reveal did not contain ev_sigs");
|
||||||
}
|
}
|
||||||
|
|
||||||
let exchange = await this.q().get<IExchangeInfo>(Stores.exchanges,
|
let exchange = await this.q().get<ExchangeRecord>(Stores.exchanges,
|
||||||
refreshSession.exchangeBaseUrl);
|
refreshSession.exchangeBaseUrl);
|
||||||
if (!exchange) {
|
if (!exchange) {
|
||||||
console.error(`exchange ${refreshSession.exchangeBaseUrl} not found`);
|
console.error(`exchange ${refreshSession.exchangeBaseUrl} not found`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let coins: Coin[] = [];
|
let coins: CoinRecord[] = [];
|
||||||
|
|
||||||
for (let i = 0; i < respJson.ev_sigs.length; i++) {
|
for (let i = 0; i < respJson.ev_sigs.length; i++) {
|
||||||
let denom = exchange.all_denoms.find((d) => d.denom_pub == refreshSession.newDenoms[i]);
|
let denom = exchange.all_denoms.find((d) => d.denom_pub == refreshSession.newDenoms[i]);
|
||||||
@ -1480,7 +1476,7 @@ export class Wallet {
|
|||||||
let denomSig = await this.cryptoApi.rsaUnblind(respJson.ev_sigs[i].ev_sig,
|
let denomSig = await this.cryptoApi.rsaUnblind(respJson.ev_sigs[i].ev_sig,
|
||||||
pc.blindingKey,
|
pc.blindingKey,
|
||||||
denom.denom_pub);
|
denom.denom_pub);
|
||||||
let coin: Coin = {
|
let coin: CoinRecord = {
|
||||||
coinPub: pc.publicKey,
|
coinPub: pc.publicKey,
|
||||||
coinPriv: pc.privateKey,
|
coinPriv: pc.privateKey,
|
||||||
denomPub: denom.denom_pub,
|
denomPub: denom.denom_pub,
|
||||||
@ -1526,9 +1522,9 @@ export class Wallet {
|
|||||||
return offer;
|
return offer;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getExchanges(): Promise<IExchangeInfo[]> {
|
async getExchanges(): Promise<ExchangeRecord[]> {
|
||||||
return this.q()
|
return this.q()
|
||||||
.iter<IExchangeInfo>(Stores.exchanges)
|
.iter<ExchangeRecord>(Stores.exchanges)
|
||||||
.flatMap((e) => [e])
|
.flatMap((e) => [e])
|
||||||
.toArray();
|
.toArray();
|
||||||
}
|
}
|
||||||
@ -1540,17 +1536,17 @@ export class Wallet {
|
|||||||
.toArray();
|
.toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
async getCoins(exchangeBaseUrl: string): Promise<Coin[]> {
|
async getCoins(exchangeBaseUrl: string): Promise<CoinRecord[]> {
|
||||||
return this.q()
|
return this.q()
|
||||||
.iter<Coin>(Stores.coins)
|
.iter<CoinRecord>(Stores.coins)
|
||||||
.filter((c: Coin) => c.exchangeBaseUrl === exchangeBaseUrl)
|
.filter((c: CoinRecord) => c.exchangeBaseUrl === exchangeBaseUrl)
|
||||||
.toArray();
|
.toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
async getPreCoins(exchangeBaseUrl: string): Promise<PreCoin[]> {
|
async getPreCoins(exchangeBaseUrl: string): Promise<PreCoinRecord[]> {
|
||||||
return this.q()
|
return this.q()
|
||||||
.iter<PreCoin>(Stores.precoins)
|
.iter<PreCoinRecord>(Stores.precoins)
|
||||||
.filter((c: PreCoin) => c.exchangeBaseUrl === exchangeBaseUrl)
|
.filter((c: PreCoinRecord) => c.exchangeBaseUrl === exchangeBaseUrl)
|
||||||
.toArray();
|
.toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1566,7 +1562,7 @@ export class Wallet {
|
|||||||
console.log("no repurchase: no correlation id");
|
console.log("no repurchase: no correlation id");
|
||||||
return {isRepurchase: false};
|
return {isRepurchase: false};
|
||||||
}
|
}
|
||||||
let result: Transaction|undefined = await (
|
let result: TransactionRecord|undefined = await (
|
||||||
this.q()
|
this.q()
|
||||||
.getIndexed(Stores.transactions.repurchaseIndex,
|
.getIndexed(Stores.transactions.repurchaseIndex,
|
||||||
[
|
[
|
||||||
@ -1589,16 +1585,16 @@ export class Wallet {
|
|||||||
|
|
||||||
async paymentSucceeded(contractHash: string): Promise<any> {
|
async paymentSucceeded(contractHash: string): Promise<any> {
|
||||||
const doPaymentSucceeded = async() => {
|
const doPaymentSucceeded = async() => {
|
||||||
let t = await this.q().get<Transaction>(Stores.transactions,
|
let t = await this.q().get<TransactionRecord>(Stores.transactions,
|
||||||
contractHash);
|
contractHash);
|
||||||
if (!t) {
|
if (!t) {
|
||||||
console.error("contract not found");
|
console.error("contract not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
t.finished = true;
|
t.finished = true;
|
||||||
let modifiedCoins: Coin[] = [];
|
let modifiedCoins: CoinRecord[] = [];
|
||||||
for (let pc of t.payReq.coins) {
|
for (let pc of t.payReq.coins) {
|
||||||
let c = await this.q().get<Coin>(Stores.coins, pc.coin_pub);
|
let c = await this.q().get<CoinRecord>(Stores.coins, pc.coin_pub);
|
||||||
if (!c) {
|
if (!c) {
|
||||||
console.error("coin not found");
|
console.error("coin not found");
|
||||||
return;
|
return;
|
||||||
|
14
src/wxApi.ts
14
src/wxApi.ts
@ -16,10 +16,10 @@
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
AmountJson,
|
AmountJson,
|
||||||
Coin,
|
CoinRecord,
|
||||||
PreCoin,
|
PreCoinRecord,
|
||||||
ReserveCreationInfo,
|
ReserveCreationInfo,
|
||||||
IExchangeInfo,
|
ExchangeRecord,
|
||||||
ReserveRecord
|
ReserveRecord
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
@ -47,14 +47,14 @@ export function getReserveCreationInfo(baseUrl: string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function callBackend(type: string, detail?: any): Promise<any> {
|
export async function callBackend(type: string, detail?: any): Promise<any> {
|
||||||
return new Promise<IExchangeInfo[]>((resolve, reject) => {
|
return new Promise<ExchangeRecord[]>((resolve, reject) => {
|
||||||
chrome.runtime.sendMessage({ type, detail }, (resp) => {
|
chrome.runtime.sendMessage({ type, detail }, (resp) => {
|
||||||
resolve(resp);
|
resolve(resp);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getExchanges(): Promise<IExchangeInfo[]> {
|
export async function getExchanges(): Promise<ExchangeRecord[]> {
|
||||||
return await callBackend("get-exchanges");
|
return await callBackend("get-exchanges");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,11 +62,11 @@ export async function getReserves(exchangeBaseUrl: string): Promise<ReserveRecor
|
|||||||
return await callBackend("get-reserves", { exchangeBaseUrl });
|
return await callBackend("get-reserves", { exchangeBaseUrl });
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getCoins(exchangeBaseUrl: string): Promise<Coin[]> {
|
export async function getCoins(exchangeBaseUrl: string): Promise<CoinRecord[]> {
|
||||||
return await callBackend("get-coins", { exchangeBaseUrl });
|
return await callBackend("get-coins", { exchangeBaseUrl });
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getPreCoins(exchangeBaseUrl: string): Promise<PreCoin[]> {
|
export async function getPreCoins(exchangeBaseUrl: string): Promise<PreCoinRecord[]> {
|
||||||
return await callBackend("get-precoins", { exchangeBaseUrl });
|
return await callBackend("get-precoins", { exchangeBaseUrl });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,12 +17,11 @@
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
Wallet,
|
Wallet,
|
||||||
Offer,
|
OfferRecord,
|
||||||
Badge,
|
Badge,
|
||||||
ConfirmReserveRequest,
|
ConfirmReserveRequest,
|
||||||
CreateReserveRequest
|
CreateReserveRequest
|
||||||
} from "./wallet";
|
} from "./wallet";
|
||||||
import { deleteDb, exportDb, openTalerDb } from "./db";
|
|
||||||
import { BrowserHttpLib } from "./http";
|
import { BrowserHttpLib } from "./http";
|
||||||
import { Checkable } from "./checkable";
|
import { Checkable } from "./checkable";
|
||||||
import { AmountJson } from "./types";
|
import { AmountJson } from "./types";
|
||||||
@ -34,6 +33,12 @@ import { ChromeBadge } from "./chromeBadge";
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
const DB_NAME = "taler";
|
||||||
|
const DB_VERSION = 11;
|
||||||
|
|
||||||
|
import {Stores} from "./wallet";
|
||||||
|
import {Store, Index} from "./query";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Messaging for the WebExtensions wallet. Should contain
|
* Messaging for the WebExtensions wallet. Should contain
|
||||||
* parts that are specific for WebExtensions, but as little business
|
* parts that are specific for WebExtensions, but as little business
|
||||||
@ -97,9 +102,9 @@ function makeHandlers(db: IDBDatabase,
|
|||||||
return wallet.confirmReserve(req);
|
return wallet.confirmReserve(req);
|
||||||
},
|
},
|
||||||
["confirm-pay"]: function (detail, sender) {
|
["confirm-pay"]: function (detail, sender) {
|
||||||
let offer: Offer;
|
let offer: OfferRecord;
|
||||||
try {
|
try {
|
||||||
offer = Offer.checked(detail.offer);
|
offer = OfferRecord.checked(detail.offer);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof Checkable.SchemaError) {
|
if (e instanceof Checkable.SchemaError) {
|
||||||
console.error("schema error:", e.message);
|
console.error("schema error:", e.message);
|
||||||
@ -116,9 +121,9 @@ function makeHandlers(db: IDBDatabase,
|
|||||||
return wallet.confirmPay(offer);
|
return wallet.confirmPay(offer);
|
||||||
},
|
},
|
||||||
["check-pay"]: function (detail, sender) {
|
["check-pay"]: function (detail, sender) {
|
||||||
let offer: Offer;
|
let offer: OfferRecord;
|
||||||
try {
|
try {
|
||||||
offer = Offer.checked(detail.offer);
|
offer = OfferRecord.checked(detail.offer);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof Checkable.SchemaError) {
|
if (e instanceof Checkable.SchemaError) {
|
||||||
console.error("schema error:", e.message);
|
console.error("schema error:", e.message);
|
||||||
@ -437,3 +442,86 @@ export function wxMain() {
|
|||||||
console.error(e);
|
console.error(e);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a promise that resolves
|
||||||
|
* to the taler wallet db.
|
||||||
|
*/
|
||||||
|
function openTalerDb(): Promise<IDBDatabase> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const req = indexedDB.open(DB_NAME, DB_VERSION);
|
||||||
|
req.onerror = (e) => {
|
||||||
|
reject(e);
|
||||||
|
};
|
||||||
|
req.onsuccess = (e) => {
|
||||||
|
resolve(req.result);
|
||||||
|
};
|
||||||
|
req.onupgradeneeded = (e) => {
|
||||||
|
const db = req.result;
|
||||||
|
console.log("DB: upgrade needed: oldVersion = " + e.oldVersion);
|
||||||
|
switch (e.oldVersion) {
|
||||||
|
case 0: // DB does not exist yet
|
||||||
|
|
||||||
|
for (let n in Stores) {
|
||||||
|
if ((Stores as any)[n] instanceof Store) {
|
||||||
|
let si: Store<any> = (Stores as any)[n];
|
||||||
|
const s = db.createObjectStore(si.name, si.storeParams);
|
||||||
|
for (let indexName in (si as any)) {
|
||||||
|
if ((si as any)[indexName] instanceof Index) {
|
||||||
|
let ii: Index<any,any> = (si as any)[indexName];
|
||||||
|
s.createIndex(ii.indexName, ii.keyPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (e.oldVersion != DB_VERSION) {
|
||||||
|
window.alert("Incompatible wallet dababase version, please reset" +
|
||||||
|
" db.");
|
||||||
|
chrome.browserAction.setBadgeText({text: "err"});
|
||||||
|
chrome.browserAction.setBadgeBackgroundColor({color: "#F00"});
|
||||||
|
throw Error("incompatible DB");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function exportDb(db: IDBDatabase): Promise<any> {
|
||||||
|
let dump = {
|
||||||
|
name: db.name,
|
||||||
|
version: db.version,
|
||||||
|
stores: {} as {[s: string]: any},
|
||||||
|
};
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
|
let tx = db.transaction(Array.from(db.objectStoreNames));
|
||||||
|
tx.addEventListener("complete", () => {
|
||||||
|
resolve(dump);
|
||||||
|
});
|
||||||
|
for (let i = 0; i < db.objectStoreNames.length; i++) {
|
||||||
|
let name = db.objectStoreNames[i];
|
||||||
|
let storeDump = {} as {[s: string]: any};
|
||||||
|
dump.stores[name] = storeDump;
|
||||||
|
let store = tx.objectStore(name)
|
||||||
|
.openCursor()
|
||||||
|
.addEventListener("success", (e: Event) => {
|
||||||
|
let cursor = (e.target as any).result;
|
||||||
|
if (cursor) {
|
||||||
|
storeDump[cursor.key] = cursor.value;
|
||||||
|
cursor.continue();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteDb() {
|
||||||
|
indexedDB.deleteDatabase(DB_NAME);
|
||||||
|
}
|
@ -16,20 +16,19 @@
|
|||||||
"src/checkable.ts",
|
"src/checkable.ts",
|
||||||
"decl/lib.es6.d.ts",
|
"decl/lib.es6.d.ts",
|
||||||
"src/chromeBadge.ts",
|
"src/chromeBadge.ts",
|
||||||
"decl/urijs/URIjs.d.ts",
|
|
||||||
"src/cryptoApi-test.ts",
|
"src/cryptoApi-test.ts",
|
||||||
|
"decl/urijs/URIjs.d.ts",
|
||||||
"src/components.ts",
|
"src/components.ts",
|
||||||
"decl/systemjs/systemjs.d.ts",
|
|
||||||
"src/emscriptif-test.ts",
|
"src/emscriptif-test.ts",
|
||||||
|
"decl/systemjs/systemjs.d.ts",
|
||||||
"src/cryptoApi.ts",
|
"src/cryptoApi.ts",
|
||||||
"decl/react-global.d.ts",
|
|
||||||
"src/helpers-test.ts",
|
"src/helpers-test.ts",
|
||||||
|
"decl/react-global.d.ts",
|
||||||
"src/cryptoLib.ts",
|
"src/cryptoLib.ts",
|
||||||
"src/types-test.ts",
|
"src/types-test.ts",
|
||||||
"decl/chrome/chrome.d.ts",
|
"decl/chrome/chrome.d.ts",
|
||||||
"src/cryptoWorker.ts",
|
"src/cryptoWorker.ts",
|
||||||
"src/wallet-test.ts",
|
"src/wallet-test.ts",
|
||||||
"src/db.ts",
|
|
||||||
"src/emscriptif.ts",
|
"src/emscriptif.ts",
|
||||||
"src/helpers.ts",
|
"src/helpers.ts",
|
||||||
"src/http.ts",
|
"src/http.ts",
|
||||||
@ -39,7 +38,7 @@
|
|||||||
"src/types.ts",
|
"src/types.ts",
|
||||||
"src/wallet.ts",
|
"src/wallet.ts",
|
||||||
"src/wxApi.ts",
|
"src/wxApi.ts",
|
||||||
"src/wxMessaging.ts",
|
"src/wxBackend.ts",
|
||||||
"src/renderHtml.tsx",
|
"src/renderHtml.tsx",
|
||||||
"src/background/background.ts",
|
"src/background/background.ts",
|
||||||
"src/content_scripts/notify.ts",
|
"src/content_scripts/notify.ts",
|
||||||
|
Loading…
Reference in New Issue
Block a user