support for talerpay URLs with session ID
This commit is contained in:
parent
87fdafb1a5
commit
d454f7547d
@ -156,7 +156,7 @@ export function installAndroidWalletListener() {
|
|||||||
}
|
}
|
||||||
case "confirmPay": {
|
case "confirmPay": {
|
||||||
const wallet = await wp.promise;
|
const wallet = await wp.promise;
|
||||||
result = await wallet.confirmPay(msg.args.proposalId, undefined);
|
result = await wallet.confirmPay(msg.args.proposalId, msg.args.sessionId);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "startTunnel": {
|
case "startTunnel": {
|
||||||
|
@ -545,6 +545,12 @@ export class ProposalDownloadRecord {
|
|||||||
@Checkable.String()
|
@Checkable.String()
|
||||||
noncePriv: string;
|
noncePriv: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Session ID we got when downloading the contract.
|
||||||
|
*/
|
||||||
|
@Checkable.Optional(Checkable.String())
|
||||||
|
downloadSessionId?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify that a value matches the schema of this class and convert it into a
|
* Verify that a value matches the schema of this class and convert it into a
|
||||||
* member.
|
* member.
|
||||||
|
@ -381,8 +381,7 @@ export class Wallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async fillDefaults() {
|
private async fillDefaults() {
|
||||||
const onTrue = (r: QueryRoot) => {
|
const onTrue = (r: QueryRoot) => {};
|
||||||
};
|
|
||||||
const onFalse = (r: QueryRoot) => {
|
const onFalse = (r: QueryRoot) => {
|
||||||
Wallet.enableTracing && console.log("applying defaults");
|
Wallet.enableTracing && console.log("applying defaults");
|
||||||
r.put(Stores.config, { key: "currencyDefaultsApplied", value: true })
|
r.put(Stores.config, { key: "currencyDefaultsApplied", value: true })
|
||||||
@ -428,19 +427,19 @@ export class Wallet {
|
|||||||
* by looking at the database.
|
* by looking at the database.
|
||||||
*/
|
*/
|
||||||
private resumePendingFromDb(): void {
|
private resumePendingFromDb(): void {
|
||||||
console.log("resuming pending operations from db");
|
Wallet.enableTracing && console.log("resuming pending operations from db");
|
||||||
|
|
||||||
this.q()
|
this.q()
|
||||||
.iter(Stores.reserves)
|
.iter(Stores.reserves)
|
||||||
.forEach(reserve => {
|
.forEach(reserve => {
|
||||||
console.log("resuming reserve", reserve.reserve_pub);
|
Wallet.enableTracing && console.log("resuming reserve", reserve.reserve_pub);
|
||||||
this.processReserve(reserve.reserve_pub);
|
this.processReserve(reserve.reserve_pub);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.q()
|
this.q()
|
||||||
.iter(Stores.precoins)
|
.iter(Stores.precoins)
|
||||||
.forEach(preCoin => {
|
.forEach(preCoin => {
|
||||||
console.log("resuming precoin");
|
Wallet.enableTracing && console.log("resuming precoin");
|
||||||
this.processPreCoin(preCoin.coinPub);
|
this.processPreCoin(preCoin.coinPub);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -461,7 +460,7 @@ export class Wallet {
|
|||||||
.iter(Stores.coins)
|
.iter(Stores.coins)
|
||||||
.forEach((c: CoinRecord) => {
|
.forEach((c: CoinRecord) => {
|
||||||
if (c.status === CoinStatus.Dirty) {
|
if (c.status === CoinStatus.Dirty) {
|
||||||
console.log("resuming pending refresh for coin", c);
|
Wallet.enableTracing && console.log("resuming pending refresh for coin", c);
|
||||||
this.refresh(c.coinPub);
|
this.refresh(c.coinPub);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -592,8 +591,6 @@ export class Wallet {
|
|||||||
.iterIndex(Stores.coins.exchangeBaseUrlIndex, exchange.baseUrl)
|
.iterIndex(Stores.coins.exchangeBaseUrlIndex, exchange.baseUrl)
|
||||||
.toArray();
|
.toArray();
|
||||||
|
|
||||||
console.log("considering coins", coins);
|
|
||||||
|
|
||||||
const denoms = await this.q()
|
const denoms = await this.q()
|
||||||
.iterIndex(Stores.denominations.exchangeBaseUrlIndex, exchange.baseUrl)
|
.iterIndex(Stores.denominations.exchangeBaseUrlIndex, exchange.baseUrl)
|
||||||
.toArray();
|
.toArray();
|
||||||
@ -720,15 +717,18 @@ export class Wallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async preparePay(url: string): Promise<PreparePayResult> {
|
async preparePay(url: string): Promise<PreparePayResult> {
|
||||||
const talerpayPrefix = "talerpay:"
|
const talerpayPrefix = "talerpay:";
|
||||||
|
let downloadSessionId: string | undefined;
|
||||||
if (url.startsWith(talerpayPrefix)) {
|
if (url.startsWith(talerpayPrefix)) {
|
||||||
url = decodeURIComponent(url.substring(talerpayPrefix.length));
|
let [p1, p2] = url.substring(talerpayPrefix.length).split(";");
|
||||||
|
url = decodeURIComponent(p1);
|
||||||
|
downloadSessionId = p2;
|
||||||
}
|
}
|
||||||
let proposalId: number;
|
let proposalId: number;
|
||||||
let checkResult: CheckPayResult;
|
let checkResult: CheckPayResult;
|
||||||
try {
|
try {
|
||||||
console.log("downloading proposal");
|
console.log("downloading proposal");
|
||||||
proposalId = await this.downloadProposal(url);
|
proposalId = await this.downloadProposal(url, downloadSessionId);
|
||||||
console.log("calling checkPay");
|
console.log("calling checkPay");
|
||||||
checkResult = await this.checkPay(proposalId);
|
checkResult = await this.checkPay(proposalId);
|
||||||
console.log("checkPay result", checkResult);
|
console.log("checkPay result", checkResult);
|
||||||
@ -736,7 +736,7 @@ export class Wallet {
|
|||||||
return {
|
return {
|
||||||
status: "error",
|
status: "error",
|
||||||
error: e.toString(),
|
error: e.toString(),
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
const proposal = await this.getProposal(proposalId);
|
const proposal = await this.getProposal(proposalId);
|
||||||
if (!proposal) {
|
if (!proposal) {
|
||||||
@ -770,13 +770,19 @@ export class Wallet {
|
|||||||
/**
|
/**
|
||||||
* Download a proposal and store it in the database.
|
* Download a proposal and store it in the database.
|
||||||
* Returns an id for it to retrieve it later.
|
* Returns an id for it to retrieve it later.
|
||||||
|
*
|
||||||
|
* @param sessionId Current session ID, if the proposal is being
|
||||||
|
* downloaded in the context of a session ID.
|
||||||
*/
|
*/
|
||||||
async downloadProposal(url: string): Promise<number> {
|
async downloadProposal(url: string, sessionId?: string): Promise<number> {
|
||||||
|
console.log("downloading proposal from", url);
|
||||||
|
console.log("context session id is", sessionId);
|
||||||
const oldProposal = await this.q().getIndexed(
|
const oldProposal = await this.q().getIndexed(
|
||||||
Stores.proposals.urlIndex,
|
Stores.proposals.urlIndex,
|
||||||
url,
|
url,
|
||||||
);
|
);
|
||||||
if (oldProposal) {
|
if (oldProposal) {
|
||||||
|
console.log("old proposal exists:", oldProposal);
|
||||||
return oldProposal.id!;
|
return oldProposal.id!;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -803,6 +809,7 @@ export class Wallet {
|
|||||||
noncePriv: priv,
|
noncePriv: priv,
|
||||||
timestamp: new Date().getTime(),
|
timestamp: new Date().getTime(),
|
||||||
url,
|
url,
|
||||||
|
downloadSessionId: sessionId,
|
||||||
};
|
};
|
||||||
|
|
||||||
const id = await this.q().putWithResult(Stores.proposals, proposalRecord);
|
const id = await this.q().putWithResult(Stores.proposals, proposalRecord);
|
||||||
@ -852,7 +859,7 @@ export class Wallet {
|
|||||||
const payReq = { ...purchase.payReq, session_id: sessionId };
|
const payReq = { ...purchase.payReq, session_id: sessionId };
|
||||||
|
|
||||||
try {
|
try {
|
||||||
resp = await this.http.postJson(purchase.contractTerms.pay_url, payReq)
|
resp = await this.http.postJson(purchase.contractTerms.pay_url, payReq);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Gives the user the option to retry / abort and refresh
|
// Gives the user the option to retry / abort and refresh
|
||||||
console.log("payment failed", e);
|
console.log("payment failed", e);
|
||||||
@ -913,10 +920,10 @@ export class Wallet {
|
|||||||
*/
|
*/
|
||||||
async confirmPay(
|
async confirmPay(
|
||||||
proposalId: number,
|
proposalId: number,
|
||||||
sessionId: string | undefined,
|
sessionIdOverride: string | undefined,
|
||||||
): Promise<ConfirmPayResult> {
|
): Promise<ConfirmPayResult> {
|
||||||
console.log(
|
console.log(
|
||||||
`executing confirmPay with proposalId ${proposalId} and sessionId ${sessionId}`,
|
`executing confirmPay with proposalId ${proposalId} and sessionIdOverride ${sessionIdOverride}`,
|
||||||
);
|
);
|
||||||
const proposal: ProposalDownloadRecord | undefined = await this.q().get(
|
const proposal: ProposalDownloadRecord | undefined = await this.q().get(
|
||||||
Stores.proposals,
|
Stores.proposals,
|
||||||
@ -927,6 +934,8 @@ export class Wallet {
|
|||||||
throw Error(`proposal with id ${proposalId} not found`);
|
throw Error(`proposal with id ${proposalId} not found`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const sessionId = sessionIdOverride || proposal.downloadSessionId;
|
||||||
|
|
||||||
let purchase = await this.q().get(
|
let purchase = await this.q().get(
|
||||||
Stores.purchases,
|
Stores.purchases,
|
||||||
proposal.contractTermsHash,
|
proposal.contractTermsHash,
|
||||||
@ -1028,6 +1037,9 @@ export class Wallet {
|
|||||||
* look faster to the user.
|
* look faster to the user.
|
||||||
*/
|
*/
|
||||||
async checkPay(proposalId: number): Promise<CheckPayResult> {
|
async checkPay(proposalId: number): Promise<CheckPayResult> {
|
||||||
|
|
||||||
|
console.log("doing checkPay for proposalId", proposalId)
|
||||||
|
|
||||||
const proposal = await this.q().get(Stores.proposals, proposalId);
|
const proposal = await this.q().get(Stores.proposals, proposalId);
|
||||||
|
|
||||||
if (!proposal) {
|
if (!proposal) {
|
||||||
@ -1040,12 +1052,16 @@ export class Wallet {
|
|||||||
proposal.contractTermsHash,
|
proposal.contractTermsHash,
|
||||||
);
|
);
|
||||||
if (purchase) {
|
if (purchase) {
|
||||||
|
console.log("got purchase", purchase)
|
||||||
return { status: "paid" };
|
return { status: "paid" };
|
||||||
}
|
}
|
||||||
|
|
||||||
const paymentAmount = Amounts.parseOrThrow(proposal.contractTerms.amount);
|
const paymentAmount = Amounts.parseOrThrow(proposal.contractTerms.amount);
|
||||||
|
|
||||||
Wallet.enableTracing && console.log(`checking if payment of ${JSON.stringify(paymentAmount)} is possible`);
|
Wallet.enableTracing &&
|
||||||
|
console.log(
|
||||||
|
`checking if payment of ${JSON.stringify(paymentAmount)} is possible`,
|
||||||
|
);
|
||||||
|
|
||||||
let wireFeeLimit;
|
let wireFeeLimit;
|
||||||
if (proposal.contractTerms.max_wire_fee) {
|
if (proposal.contractTerms.max_wire_fee) {
|
||||||
@ -2317,7 +2333,7 @@ export class Wallet {
|
|||||||
.iter(Stores.refresh)
|
.iter(Stores.refresh)
|
||||||
.toArray();
|
.toArray();
|
||||||
for (const session of oldRefreshSessions) {
|
for (const session of oldRefreshSessions) {
|
||||||
console.log("got old session for", oldCoinPub, session);
|
Wallet.enableTracing && console.log("got old refresh session for", oldCoinPub, session);
|
||||||
this.continueRefreshSession(session);
|
this.continueRefreshSession(session);
|
||||||
}
|
}
|
||||||
const coin = await this.q().get(Stores.coins, oldCoinPub);
|
const coin = await this.q().get(Stores.coins, oldCoinPub);
|
||||||
@ -3418,7 +3434,6 @@ export class Wallet {
|
|||||||
*/
|
*/
|
||||||
async collectGarbage() {
|
async collectGarbage() {
|
||||||
// FIXME(#5845)
|
// FIXME(#5845)
|
||||||
|
|
||||||
// We currently do not garbage-collect the wallet database. This might change
|
// We currently do not garbage-collect the wallet database. This might change
|
||||||
// after the feature has been properly re-designed, and we have come up with a
|
// after the feature has been properly re-designed, and we have come up with a
|
||||||
// strategy to test it.
|
// strategy to test it.
|
||||||
|
Loading…
Reference in New Issue
Block a user