commit 8b22ae29a035bbabab132ba3e0f7078e943525e4
parent d9af4dd3f745d17d171d292d21da8ebf7e44f5f7
Author: Iván Ávalos <avalos@disroot.org>
Date: Thu, 27 Mar 2025 17:30:08 +0100
WIP: split DB access and token selection logic
Diffstat:
1 file changed, 56 insertions(+), 30 deletions(-)
diff --git a/packages/taler-wallet-core/src/tokenSelection.ts b/packages/taler-wallet-core/src/tokenSelection.ts
@@ -20,6 +20,7 @@ import {
hashTokenIssuePub,
j2s,
Logger,
+ MerchantContractInput,
MerchantContractInputType,
MerchantContractTermsV1,
MerchantContractTokenDetails,
@@ -176,7 +177,54 @@ export async function selectPayTokensInTx(
throw Error(`proposal ${req.proposalId} could not be found`);
}
- const records: TokenRecord[] = [];
+ const inputs = req.contractTerms.choices[req.choiceIndex].inputs;
+ const inputTokens: {[slug: string]: TokenRecord[]} = {};
+ for (const input of inputs) {
+ if (input.type == MerchantContractInputType.Token) {
+ const slug = input.token_family_slug;
+ const keys = req.contractTerms.token_families[slug].keys;
+
+ for (const key of keys) {
+ const keyHash = encodeCrock(hashTokenIssuePub(key));
+ const t = await tx.tokens.indexes.byTokenIssuePubHash.getAll(keyHash);
+ if (inputTokens[slug]) {
+ inputTokens[slug].push(...t);
+ } else {
+ inputTokens[slug] = t;
+ }
+ }
+ }
+ }
+
+ return selectTokenCandidates(
+ inputs,
+ inputTokens,
+ proposal.merchantBaseUrl,
+ );
+}
+
+export async function selectPayTokens(
+ wex: WalletExecutionContext,
+ req: SelectPayTokensRequest,
+): Promise<SelectPayTokensResult> {
+ return await wex.db.runReadOnlyTx(
+ {
+ storeNames: [
+ "tokens",
+ "purchases",
+ ]
+ },
+ async (tx) => {
+ return selectPayTokensInTx(tx, req);
+ }
+ );
+}
+
+export function selectTokenCandidates(
+ inputs: MerchantContractInput[],
+ inputTokens: {[slug: string]: TokenRecord[]},
+ merchantBaseUrl: string,
+): SelectPayTokensResult {
const details: PaymentTokenAvailabilityDetails = {
tokensRequested: 0,
tokensAvailable: 0,
@@ -186,29 +234,24 @@ export async function selectPayTokensInTx(
};
var insufficient = false;
+ const records: TokenRecord[] = [];
- const inputs = req.contractTerms.choices[req.choiceIndex].inputs;
for (const input of inputs) {
if (input.type == MerchantContractInputType.Token) {
const count = input.count ?? 1;
const slug = input.token_family_slug;
- const keys = req.contractTerms.token_families[slug].keys;
+ const tokens = inputTokens[slug];
details.tokensRequested += count;
- const tokens: TokenRecord[] = [];
- for (const key of keys) {
- const keyHash = encodeCrock(hashTokenIssuePub(key));
- const t = await tx.tokens.indexes.byTokenIssuePubHash.getAll(keyHash);
- tokens.push(...t);
+ for (const t of tokens) {
+ const keyHash = t.tokenIssuePubHash;
if (details.perTokenFamily[keyHash] === undefined) {
details.perTokenFamily[keyHash] = {
requested: count,
available: 0,
unexpected: 0,
untrusted: 0,
- };
- } else {
- details.perTokenFamily[keyHash].requested += count;
+ }
}
}
@@ -225,7 +268,7 @@ export async function selectPayTokensInTx(
AbsoluteTime.fromProtocolTimestamp(timestampProtocolFromDb(tok.validBefore)),
)).filter(tok => {
const res = verifyTokenMerchant(
- proposal.merchantBaseUrl,
+ merchantBaseUrl,
tok.merchantBaseUrl,
tok.extraData,
);
@@ -268,22 +311,5 @@ export async function selectPayTokensInTx(
type: "success",
tokens: records,
details: details,
- }
-}
-
-export async function selectPayTokens(
- wex: WalletExecutionContext,
- req: SelectPayTokensRequest,
-): Promise<SelectPayTokensResult> {
- return await wex.db.runReadOnlyTx(
- {
- storeNames: [
- "tokens",
- "purchases",
- ]
- },
- async (tx) => {
- return selectPayTokensInTx(tx, req);
- }
- );
+ };
}