towards consuming new merchant API

This commit is contained in:
Florian Dold 2020-07-21 12:23:48 +05:30
parent dd2efc3d78
commit f4a8702b3c
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
10 changed files with 41 additions and 70 deletions

View File

@ -336,7 +336,7 @@ export class CryptoImplementation {
const d = buildSigPS(SignaturePurpose.WALLET_COIN_DEPOSIT)
.put(decodeCrock(depositInfo.contractTermsHash))
.put(decodeCrock(depositInfo.wireInfoHash))
.put(hash(decodeCrock(depositInfo.denomPub)))
.put(decodeCrock(depositInfo.denomPubHash))
.put(timestampRoundedToBuffer(depositInfo.timestamp))
.put(timestampRoundedToBuffer(depositInfo.refundDeadline))
.put(amountToBuffer(depositInfo.spendAmount))
@ -350,7 +350,7 @@ export class CryptoImplementation {
coin_pub: depositInfo.coinPub,
coin_sig: encodeCrock(coinSig),
contribution: Amounts.stringify(depositInfo.spendAmount),
denom_pub: depositInfo.denomPub,
h_denom: depositInfo.denomPubHash,
exchange_url: depositInfo.exchangeBaseUrl,
ub_sig: depositInfo.denomSig,
};

View File

@ -25,6 +25,7 @@ import { NodeHttpLib } from "./NodeHttpLib";
import { Wallet } from "../wallet";
import { Configuration } from "../util/talerconfig";
import { Amounts, AmountJson } from "../util/amounts";
import { OperationFailedAndReportedError, OperationFailedError } from "../operations/errors";
const logger = new Logger("integrationtest.ts");
@ -69,9 +70,9 @@ async function makePayment(
}
const confirmPayResult = await wallet.confirmPay(
preparePayResult.proposalId,
undefined,
);
preparePayResult.proposalId,
undefined,
);
console.log("confirmPayResult", confirmPayResult);

View File

@ -30,7 +30,7 @@ import {
setupRefreshPlanchet,
encodeCrock,
} from "../crypto/talerCrypto";
import { OperationFailedAndReportedError } from "../operations/errors";
import { OperationFailedAndReportedError, OperationFailedError } from "../operations/errors";
import { Bank } from "./bank";
import { classifyTalerUri, TalerUriType } from "../util/taleruri";
import { Configuration } from "../util/talerconfig";
@ -97,7 +97,6 @@ async function doPay(
if (pay) {
await wallet.confirmPay(result.proposalId, undefined);
console.log("paid!");
} else {
console.log("not paying");
}

View File

@ -130,7 +130,7 @@ export async function getBalancesInsideTransaction(
if (t.timestampFirstSuccessfulPay) {
return;
}
for (const c of t.payReq.coins) {
for (const c of t.coinDepositPermissions) {
addTo(
balanceStore,
"pendingPayment",

View File

@ -24,8 +24,6 @@
* Imports.
*/
import { OperationError } from "../types/walletTypes";
import { HttpResponse } from "../util/http";
import { Codec } from "../util/codec";
/**
* This exception is there to let the caller know that an error happened,

View File

@ -246,7 +246,7 @@ export async function getHistory(
contribution: string;
denomPub: string;
}[] = [];
for (const x of purchase.payReq.coins) {
for (const x of purchase.coinDepositPermissions) {
const c = await tx.get(Stores.coins, x.coin_pub);
if (!c) {
// FIXME: what to do here??
@ -269,7 +269,7 @@ export async function getHistory(
verboseDetails = { coins };
}
const amountPaidWithFees = Amounts.sum(
purchase.payReq.coins.map((x) =>
purchase.coinDepositPermissions.map((x) =>
Amounts.parseOrThrow(x.contribution),
),
).amount;
@ -280,7 +280,7 @@ export async function getHistory(
replay: pe.isReplay,
sessionId: pe.sessionId,
timestamp: pe.timestamp,
numCoins: purchase.payReq.coins.length,
numCoins: purchase.coinDepositPermissions.length,
amountPaidWithFees: Amounts.stringify(amountPaidWithFees),
verboseDetails,
});

View File

@ -42,6 +42,7 @@ import {
codecForProposal,
codecForContractTerms,
CoinDepositPermission,
codecForMerchantPayResponse,
} from "../types/talerTypes";
import {
ConfirmPayResult,
@ -431,12 +432,6 @@ async function recordConfirmPay(
sessionId = proposal.downloadSessionId;
}
logger.trace(`recording payment with session ID ${sessionId}`);
const payReq: PayReq = {
coins: coinDepositPermissions,
merchant_pub: d.contractData.merchantPub,
mode: "pay",
order_id: d.contractData.orderId,
};
const payCostInfo = await getTotalPaymentCost(ws, coinSelection);
const t: PurchaseRecord = {
abortDone: false,
@ -445,8 +440,8 @@ async function recordConfirmPay(
contractData: d.contractData,
lastSessionId: sessionId,
payCoinSelection: coinSelection,
payReq,
payCostInfo,
coinDepositPermissions,
timestampAccept: getTimestampNow(),
timestampLastRefundStatus: undefined,
proposalId: proposal.proposalId,
@ -609,7 +604,6 @@ async function processDownloadProposalImpl(
).href;
logger.trace("downloading contract from '" + orderClaimUrl + "'");
const proposalResp = await httpPostTalerJson({
url: orderClaimUrl,
body: {
@ -777,26 +771,24 @@ export async function submitPay(
throw Error("not submitting payment for aborted purchase");
}
const sessionId = purchase.lastSessionId;
let resp;
const payReq = { ...purchase.payReq, session_id: sessionId };
console.log("paying with session ID", sessionId);
const payUrl = new URL("pay", purchase.contractData.merchantBaseUrl).href;
const payUrl = new URL(
`orders/${purchase.contractData.orderId}/pay`,
purchase.contractData.merchantBaseUrl,
).href;
const merchantResp = await httpPostTalerJson({
url: payUrl,
body: {
coins: purchase.coinDepositPermissions,
session_id: purchase.lastSessionId,
},
codec: codecForMerchantPayResponse(),
http: ws.http,
});
try {
console.log("pay req", payReq);
resp = await ws.http.postJson(payUrl, payReq);
} catch (e) {
// Gives the user the option to retry / abort and refresh
console.log("payment failed", e);
throw e;
}
if (resp.status !== 200) {
console.log(await resp.json());
throw Error(`unexpected status (${resp.status}) for /pay`);
}
const merchantResp = await resp.json();
console.log("got success from pay URL", merchantResp);
const now = getTimestampNow();
@ -1030,7 +1022,7 @@ export async function confirmPay(
coinPriv: coin.coinPriv,
coinPub: coin.coinPub,
contractTermsHash: d.contractData.contractTermsHash,
denomPub: coin.denomPub,
denomPubHash: coin.denomPubHash,
denomSig: coin.denomSig,
exchangeBaseUrl: coin.exchangeBaseUrl,
feeDeposit: denom.feeDeposit,
@ -1050,8 +1042,6 @@ export async function confirmPay(
sessionIdOverride,
);
logger.trace("confirmPay: submitting payment after creating purchase record");
logger.trace("purchaseRecord:", purchase);
return submitPay(ws, proposalId);
}

View File

@ -1250,10 +1250,9 @@ export interface PurchaseRecord {
contractData: WalletContractData;
/**
* The payment request, ready to be send to the merchant's
* /pay URL.
* Deposit permissions, available once the user has accepted the payment.
*/
payReq: PayReq;
coinDepositPermissions: CoinDepositPermission[];
payCoinSelection: PayCoinSelection;

View File

@ -215,7 +215,7 @@ export interface CoinDepositPermission {
/**
* The denomination public key associated with this coin.
*/
denom_pub: string;
h_denom: string;
/**
* The amount that is subtracted from this coin with this payment.
*/
@ -433,31 +433,6 @@ export class ContractTerms {
extra: any;
}
/**
* Payment body sent to the merchant's /pay.
*/
export interface PayReq {
/**
* Coins with signature.
*/
coins: CoinDepositPermission[];
/**
* The merchant public key, used to uniquely
* identify the merchant instance.
*/
merchant_pub: string;
/**
* Order ID that's being payed for.
*/
order_id: string;
/**
* Mode for /pay.
*/
mode: "pay" | "abort-refund";
}
/**
* Refund permission in the format that the merchant gives it to us.
@ -809,6 +784,10 @@ export interface CoinDumpJson {
}>;
}
export interface MerchantPayResponse {
sig: string;
}
export type AmountString = string;
export type Base32String = string;
export type EddsaSignatureString = string;
@ -1044,3 +1023,8 @@ export const codecForWithdrawResponse = (): Codec<WithdrawResponse> =>
makeCodecForObject<WithdrawResponse>()
.property("ev_sig", codecForString)
.build("WithdrawResponse");
export const codecForMerchantPayResponse = (): Codec<MerchantPayResponse> =>
makeCodecForObject<MerchantPayResponse>()
.property("sig", codecForString)
.build("MerchantPayResponse");

View File

@ -473,7 +473,7 @@ export interface DepositInfo {
merchantPub: string;
feeDeposit: AmountJson;
wireInfoHash: string;
denomPub: string;
denomPubHash: string;
denomSig: string;
}