commit 336b1619972a27a7227b2d744580d0687e9f3b19
parent 54289ce4b23828a7178cf0f80c657fe5dfee2e11
Author: Florian Dold <florian@dold.me>
Date: Wed, 30 Oct 2024 19:45:16 +0100
wallet-core: pass merchant_sig to exchange in batch-deposit
Diffstat:
4 files changed, 47 insertions(+), 0 deletions(-)
diff --git a/packages/taler-util/src/types-taler-exchange.ts b/packages/taler-util/src/types-taler-exchange.ts
@@ -1357,6 +1357,10 @@ export interface ExchangeBatchDepositRequest {
// The merchant's account details.
merchant_payto_uri: string;
+ // Merchant's signature over the h_contract_terms.
+ // @since v22
+ merchant_sig: EddsaSignatureString;
+
// The salt is used to hide the ``payto_uri`` from customers
// when computing the ``h_wire`` of the merchant.
wire_salt: WireSalt;
diff --git a/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts b/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts
@@ -105,6 +105,8 @@ import {
EncryptContractResponse,
SignCoinHistoryRequest,
SignCoinHistoryResponse,
+ SignContractTermsHashRequest,
+ SignContractTermsHashResponse,
SignDeletePurseRequest,
SignDeletePurseResponse,
SignPurseMergeRequest,
@@ -265,6 +267,10 @@ export interface TalerCryptoInterface {
signWalletKycAuth(
req: SignWalletKycAuthRequest,
): Promise<SignWalletKycAuthResponse>;
+
+ signContractTermsHash(
+ req: SignContractTermsHashRequest,
+ ): Promise<SignContractTermsHashResponse>;
}
/**
@@ -471,6 +477,11 @@ export const nullCrypto: TalerCryptoInterface = {
): Promise<SignWalletKycAuthResponse> {
throw new Error("Function not implemented.");
},
+ signContractTermsHash: function (
+ req: SignContractTermsHashRequest,
+ ): Promise<SignContractTermsHashResponse> {
+ throw new Error("Function not implemented.");
+ },
};
export type WithArg<X> = X extends (req: infer T) => infer R
@@ -1820,6 +1831,21 @@ export const nativeCryptoR: TalerCryptoInterfaceR = {
sig: sigResp.sig,
};
},
+ async signContractTermsHash(
+ tci: TalerCryptoInterfaceR,
+ req: SignContractTermsHashRequest,
+ ): Promise<SignContractTermsHashResponse> {
+ const sigData = buildSigPS(TalerSignaturePurpose.MERCHANT_CONTRACT)
+ .put(decodeCrock(req.contractTermsHash))
+ .build();
+ const sigRes = await tci.eddsaSign(tci, {
+ msg: encodeCrock(sigData),
+ priv: req.merchantPriv,
+ });
+ return {
+ sig: sigRes.sig,
+ };
+ },
};
export interface EddsaSignRequest {
diff --git a/packages/taler-wallet-core/src/crypto/cryptoTypes.ts b/packages/taler-wallet-core/src/crypto/cryptoTypes.ts
@@ -33,9 +33,11 @@ import {
AmountString,
CoinEnvelope,
DenominationPubKey,
+ EddsaPrivateKeyString,
EddsaPublicKeyString,
EddsaSignatureString,
ExchangeProtocolVersion,
+ HashCodeString,
RefreshPlanchetInfo,
TalerProtocolTimestamp,
UnblindedSignature,
@@ -244,6 +246,15 @@ export interface SignWalletKycAuthResponse {
sig: string;
}
+export interface SignContractTermsHashRequest {
+ merchantPriv: EddsaPrivateKeyString;
+ contractTermsHash: HashCodeString;
+}
+
+export interface SignContractTermsHashResponse {
+ sig: string;
+}
+
export interface SignPurseMergeRequest {
mergeTimestamp: TalerProtocolTimestamp;
diff --git a/packages/taler-wallet-core/src/deposits.ts b/packages/taler-wallet-core/src/deposits.ts
@@ -1582,6 +1582,11 @@ async function processDepositGroupPendingDeposit(
exchanges.add(dp.exchange_url);
}
+ const merchantSigResp = await wex.ws.cryptoApi.signContractTermsHash({
+ contractTermsHash: depositGroup.contractTermsHash,
+ merchantPriv: depositGroup.merchantPriv,
+ });
+
// We need to do one batch per exchange.
for (const exchangeBaseUrl of exchanges.values()) {
const coins: BatchDepositRequestCoin[] = [];
@@ -1596,6 +1601,7 @@ async function processDepositGroupPendingDeposit(
wire_salt: depositGroup.wire.salt,
wire_transfer_deadline: contractTerms.wire_transfer_deadline,
refund_deadline: contractTerms.refund_deadline,
+ merchant_sig: merchantSigResp.sig,
};
for (let i = 0; i < depositPermissions.length; i++) {