wallet-core: towards DD37 for deposits

This commit is contained in:
Florian Dold 2023-04-05 17:38:34 +02:00
parent 8eee38d559
commit 2823b1cdf4
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
12 changed files with 204 additions and 296 deletions

View File

@ -60,10 +60,4 @@ export async function runDepositTest(t: GlobalTestState) {
// The raw amount is what ends up on the bank account, which includes
// deposit and wire fees.
t.assertDeepEqual(transactions.transactions[1].amountRaw, "TESTKUDOS:9.79");
const trackResult = wallet.client.call(WalletApiOperation.TrackDepositGroup, {
depositGroupId,
});
console.log(JSON.stringify(trackResult, undefined, 2));
}

View File

@ -104,6 +104,8 @@ export interface HttpRequestLibrary {
* Make an HTTP GET request.
*
* FIXME: Get rid of this, we want the API surface to be minimal.
*
* @deprecated use fetch instead
*/
get(url: string, opt?: HttpRequestOptions): Promise<HttpResponse>;
@ -111,6 +113,8 @@ export interface HttpRequestLibrary {
* Make an HTTP POST request with a JSON body.
*
* FIXME: Get rid of this, we want the API surface to be minimal.
*
* @deprecated use fetch instead
*/
postJson(
url: string,

View File

@ -59,6 +59,11 @@ export enum ExtendedStatus {
KycRequired = "kyc-required",
}
export interface TransactionStateInfo {
txState: TransactionState;
txSubstate: TransactionSubstate;
}
export interface TransactionsRequest {
/**
* return only transactions in the given currency
@ -76,6 +81,32 @@ export interface TransactionsRequest {
includeRefreshes?: boolean;
}
export enum TransactionState {
// No state, only used when reporting transitions into the initial state
None = "none",
Pending = "pending",
Done = "done",
Aborting = "aborting",
Aborted = "aborted",
Suspended = "suspended",
Failed = "failed",
// Only used for the notification, never in the transaction history
Deleted = "deleted",
// Placeholder until D37 is fully implemented
Unknown = "unknown",
}
export enum TransactionSubstate {
// Placeholder until D37 is fully implemented
Unknown = "unknown",
// No substate
None = "none",
DepositPendingInitial = "initial",
DepositKycRequired = "kyc-required",
DepositPendingTrack = "track",
DepositAbortingRefresh = "refresh",
}
export interface TransactionsResponse {
// a list of past and pending transactions sorted by pending, timestamp and transactionId.
// In case two events are both pending and have the same timestamp,
@ -95,6 +126,13 @@ export interface TransactionCommon {
// main timestamp of the transaction
timestamp: TalerProtocolTimestamp;
txState: TransactionState;
txSubstate: TransactionSubstate;
/**
* @deprecated in favor of statusMajor and statusMinor
*/
extendedStatus: ExtendedStatus;
/**

View File

@ -1228,8 +1228,7 @@ export const codecForTestPayArgs = (): Codec<TestPayArgs> =>
export interface IntegrationTestArgs {
exchangeBaseUrl: string;
bankBaseUrl: string;
bankAccessApiBaseUrl?: string;
bankAccessApiBaseUrl: string;
merchantBaseUrl: string;
merchantAuthToken?: string;
amountToWithdraw: string;
@ -1239,12 +1238,11 @@ export interface IntegrationTestArgs {
export const codecForIntegrationTestArgs = (): Codec<IntegrationTestArgs> =>
buildCodecForObject<IntegrationTestArgs>()
.property("exchangeBaseUrl", codecForString())
.property("bankBaseUrl", codecForString())
.property("merchantBaseUrl", codecForString())
.property("merchantAuthToken", codecOptional(codecForString()))
.property("amountToSpend", codecForAmountString())
.property("amountToWithdraw", codecForAmountString())
.property("bankAccessApiBaseUrl", codecOptional(codecForAmountString()))
.property("bankAccessApiBaseUrl", codecForAmountString())
.build("IntegrationTestArgs");
export interface IntegrationTestV2Args {
@ -1499,11 +1497,10 @@ export interface CoreApiResponseError {
export interface WithdrawTestBalanceRequest {
amount: string;
bankBaseUrl: string;
/**
* Bank access API base URL. Defaults to the bankBaseUrl.
* Bank access API base URL.
*/
bankAccessApiBaseUrl?: string;
bankAccessApiBaseUrl: string;
exchangeBaseUrl: string;
forcedDenomSel?: ForcedDenomSel;
}
@ -1580,10 +1577,9 @@ export const codecForWithdrawTestBalance =
(): Codec<WithdrawTestBalanceRequest> =>
buildCodecForObject<WithdrawTestBalanceRequest>()
.property("amount", codecForString())
.property("bankBaseUrl", codecForString())
.property("exchangeBaseUrl", codecForString())
.property("forcedDenomSel", codecForAny())
.property("bankAccessApiBaseUrl", codecOptional(codecForString()))
.property("bankAccessApiBaseUrl", codecForString())
.build("WithdrawTestBalanceRequest");
export interface ApplyRefundResponse {
@ -1702,11 +1698,6 @@ export const codecForAbortTransaction = (): Codec<AbortTransactionRequest> =>
.property("forceImmediateAbort", codecOptional(codecForBoolean()))
.build("AbortTransactionRequest");
export interface GetFeeForDepositRequest {
depositPaytoUri: string;
amount: AmountString;
}
export interface DepositGroupFees {
coin: AmountString;
wire: AmountString;
@ -1718,12 +1709,6 @@ export interface CreateDepositGroupRequest {
amount: AmountString;
}
export const codecForGetFeeForDeposit = (): Codec<GetFeeForDepositRequest> =>
buildCodecForObject<GetFeeForDepositRequest>()
.property("amount", codecForAmountString())
.property("depositPaytoUri", codecForString())
.build("GetFeeForDepositRequest");
export interface PrepareDepositRequest {
depositPaytoUri: string;
amount: AmountString;
@ -1751,20 +1736,6 @@ export interface CreateDepositGroupResponse {
transactionId: string;
}
export interface TrackDepositGroupRequest {
depositGroupId: string;
}
export interface TrackDepositGroupResponse {
responses: TrackTransaction[];
}
export const codecForTrackDepositGroupRequest =
(): Codec<TrackDepositGroupRequest> =>
buildCodecForObject<TrackDepositGroupRequest>()
.property("depositGroupId", codecForAmountString())
.build("TrackDepositGroupRequest");
export interface WithdrawUriInfoResponse {
amount: AmountString;
defaultExchangeBaseUrl?: string;

View File

@ -37,7 +37,6 @@ import {
setDangerousTimetravel,
setGlobalLogLevelFromString,
summarizeTalerErrorDetail,
TalerProtocolTimestamp,
TalerUriType,
WalletNotification,
} from "@gnu-taler/taler-util";
@ -928,22 +927,6 @@ depositCli
});
});
// FIXME: should probably be removed
depositCli
.subcommand("trackDepositArgs", "track")
.requiredArgument("depositGroupId", clk.STRING)
.action(async (args) => {
await withWallet(args, async (wallet) => {
const resp = await wallet.client.call(
WalletApiOperation.TrackDepositGroup,
{
depositGroupId: args.trackDepositArgs.depositGroupId,
},
);
console.log(JSON.stringify(resp, undefined, 2));
});
});
const peerCli = walletCli.subcommand("peerArgs", "p2p", {
help: "Subcommands for peer-to-peer payments.",
});
@ -1244,7 +1227,6 @@ advancedCli
await wallet.client.call(WalletApiOperation.RunIntegrationTest, {
amountToSpend: "TESTKUDOS:1",
amountToWithdraw: "TESTKUDOS:3",
bankBaseUrl: "http://localhost:8082/",
bankAccessApiBaseUrl: "http://localhost:8082/taler-bank-access/",
exchangeBaseUrl: "http://localhost:8081/",
merchantBaseUrl: "http://localhost:8083/",
@ -1502,6 +1484,17 @@ testCli
});
});
testCli.subcommand("withdrawKudos", "withdraw-kudos").action(async (args) => {
await withWallet(args, async (wallet) => {
await wallet.client.call(WalletApiOperation.WithdrawTestBalance, {
amount: "KUDOS:50",
bankAccessApiBaseUrl:
"https://bank.demo.taler.net/demobanks/default/access-api/",
exchangeBaseUrl: "https://exchange.demo.taler.net/",
});
});
});
class PerfTimer {
tStarted: bigint | undefined;
tSum = BigInt(0);

View File

@ -858,6 +858,13 @@ export enum RefreshOperationStatus {
FinishedWithError = 51 /* DORMANT_START + 1 */,
}
export enum DepositGroupOperationStatus {
Finished = 50 /* DORMANT_START */,
Failed = 51 /* DORMANT_START + 1 */,
Pending = 10 /* ACTIVE_START */,
AbortingWithRefresh = 11 /* ACTIVE_START + 1 */,
}
export enum TransactionStatus {
Unknown = 10,
Accepted = 20,
@ -1662,6 +1669,11 @@ export interface DepositGroupRecord {
totalPayCost: AmountString;
/**
* The counterparty effective deposit amount.
*
* FIXME: If possible, rename to counterpartyEffectiveDepositAmount.
*/
effectiveDepositAmount: AmountString;
depositedPerCoin: boolean[];

View File

@ -363,6 +363,8 @@ export enum TombstoneTag {
/**
* Create an event ID from the type and the primary key for the event.
*
* @deprecated use constructTransactionIdentifier instead
*/
export function makeTransactionId(
type: TransactionType,

View File

@ -33,7 +33,6 @@ import {
durationFromSpec,
encodeCrock,
ExchangeDepositRequest,
GetFeeForDepositRequest,
getRandomBytes,
hashTruncate32,
hashWire,
@ -41,7 +40,6 @@ import {
j2s,
Logger,
MerchantContractTerms,
NotificationType,
parsePaytoUri,
PayCoinSelection,
PrepareDepositRequest,
@ -50,18 +48,16 @@ import {
stringToBytes,
TalerErrorCode,
TalerProtocolTimestamp,
TrackDepositGroupRequest,
TrackDepositGroupResponse,
TrackTransaction,
TrackTransactionWired,
TransactionState,
TransactionStateInfo,
TransactionSubstate,
TransactionType,
URL,
WireFee,
} from "@gnu-taler/taler-util";
import {
DenominationRecord,
DepositGroupRecord,
ExchangeDetailsRecord,
OperationStatus,
TransactionStatus,
} from "../db.js";
@ -77,7 +73,6 @@ import {
generateDepositPermissions,
getTotalPaymentCost,
} from "./pay-merchant.js";
import { getTotalRefreshCost } from "./refresh.js";
import { selectPayCoinsNew } from "../util/coinSelection.js";
/**
@ -85,7 +80,81 @@ import { selectPayCoinsNew } from "../util/coinSelection.js";
*/
const logger = new Logger("deposits.ts");
export async function checkDepositKycStatus(
export async function computeDepositTransactionStatus(
ws: InternalWalletState,
dg: DepositGroupRecord,
): Promise<TransactionStateInfo> {
switch (dg.operationStatus) {
case OperationStatus.Finished: {
return {
txState: TransactionState.Done,
txSubstate: TransactionSubstate.None,
};
}
case OperationStatus.Pending: {
const numTotal = dg.payCoinSelection.coinPubs.length;
let numDeposited = 0;
let numKycRequired = 0;
let numWired = 0;
for (let i = 0; i < numTotal; i++) {
if (dg.depositedPerCoin[i]) {
numDeposited++;
}
switch (dg.transactionPerCoin[i]) {
case TransactionStatus.KycRequired:
numKycRequired++;
break;
case TransactionStatus.Wired:
numWired++;
break;
}
}
if (numKycRequired > 0) {
return {
txState: TransactionState.Pending,
txSubstate: TransactionSubstate.DepositKycRequired,
};
}
if (numDeposited == numTotal) {
return {
txState: TransactionState.Pending,
txSubstate: TransactionSubstate.DepositPendingTrack,
};
}
return {
txState: TransactionState.Pending,
txSubstate: TransactionSubstate.DepositPendingInitial,
};
}
default:
throw Error("unexpected deposit group state");
}
}
export async function suspendDepositGroup(
ws: InternalWalletState,
depositGroupId: string,
): Promise<void> {
throw Error("not implemented");
}
export async function abortDepositGroup(
ws: InternalWalletState,
depositGroupId: string,
): Promise<void> {
throw Error("not implemented");
}
/**
* Check KYC status with the exchange, throw an appropriate exception when KYC is required.
*
* FIXME: Why does this throw an exception when KYC is required?
* Should we not return some proper result record here?
*/
async function checkDepositKycStatus(
ws: InternalWalletState,
exchangeUrl: string,
kycInfo: KycPendingInfo,
@ -119,7 +188,7 @@ export async function checkDepositKycStatus(
}
/**
* @see {processDepositGroup}
* Process a deposit group that is not in its final state yet.
*/
export async function processDepositGroup(
ws: InternalWalletState,
@ -181,7 +250,9 @@ export async function processDepositGroup(
options.cancellationToken?.throwIfCancelled();
const url = new URL(`coins/${perm.coin_pub}/deposit`, perm.exchange_url);
logger.info(`depositing to ${url}`);
const httpResp = await ws.http.postJson(url.href, requestBody, {
const httpResp = await ws.http.fetch(url.href, {
method: "POST",
body: requestBody,
cancellationToken: options.cancellationToken,
});
await readSuccessResponseJsonOrThrow(httpResp, codecForDepositSuccess());
@ -198,7 +269,6 @@ export async function processDepositGroup(
}
| undefined;
let signature: string | undefined;
if (depositGroup.transactionPerCoin[i] !== TransactionStatus.Wired) {
const track = await trackDepositPermission(ws, depositGroup, perm);
@ -347,39 +417,6 @@ async function getExchangeWireFee(
return fee;
}
export async function trackDepositGroup(
ws: InternalWalletState,
req: TrackDepositGroupRequest,
): Promise<TrackDepositGroupResponse> {
const responses: TrackTransaction[] = [];
const depositGroup = await ws.db
.mktx((x) => [x.depositGroups])
.runReadOnly(async (tx) => {
return tx.depositGroups.get(req.depositGroupId);
});
if (!depositGroup) {
throw Error("deposit group not found");
}
const contractData = extractContractData(
depositGroup.contractTermsRaw,
depositGroup.contractTermsHash,
"",
);
const depositPermissions = await generateDepositPermissions(
ws,
depositGroup.payCoinSelection,
contractData,
);
for (const dp of depositPermissions) {
const track = await trackDepositPermission(ws, depositGroup, dp);
responses.push(track);
}
return { responses };
}
async function trackDepositPermission(
ws: InternalWalletState,
depositGroup: DepositGroupRecord,
@ -423,66 +460,10 @@ async function trackDepositPermission(
}
}
export async function getFeeForDeposit(
ws: InternalWalletState,
req: GetFeeForDepositRequest,
): Promise<DepositGroupFees> {
const p = parsePaytoUri(req.depositPaytoUri);
if (!p) {
throw Error("invalid payto URI");
}
const amount = Amounts.parseOrThrow(req.amount);
const exchangeInfos: { url: string; master_pub: string }[] = [];
await ws.db
.mktx((x) => [x.exchanges, x.exchangeDetails])
.runReadOnly(async (tx) => {
const allExchanges = await tx.exchanges.iter().toArray();
for (const e of allExchanges) {
const details = await getExchangeDetails(tx, e.baseUrl);
if (!details || amount.currency !== details.currency) {
continue;
}
exchangeInfos.push({
master_pub: details.masterPublicKey,
url: e.baseUrl,
});
}
});
const payCoinSel = await selectPayCoinsNew(ws, {
auditors: [],
exchanges: Object.values(exchangeInfos).map((v) => ({
exchangeBaseUrl: v.url,
exchangePub: v.master_pub,
})),
wireMethod: p.targetType,
contractTermsAmount: Amounts.parseOrThrow(req.amount),
depositFeeLimit: Amounts.parseOrThrow(req.amount),
wireFeeAmortization: 1,
wireFeeLimit: Amounts.parseOrThrow(req.amount),
prevPayCoins: [],
});
if (payCoinSel.type !== "success") {
throw TalerError.fromDetail(
TalerErrorCode.WALLET_DEPOSIT_GROUP_INSUFFICIENT_BALANCE,
{
insufficientBalanceDetails: payCoinSel.insufficientBalanceDetails,
},
);
}
return await getTotalFeesForDepositAmount(
ws,
p.targetType,
amount,
payCoinSel.coinSel,
);
}
/**
* FIXME: This should be renamed to checkDepositGroup,
* as it doesn't prepare anything
*/
export async function prepareDepositGroup(
ws: InternalWalletState,
req: PrepareDepositRequest,
@ -569,7 +550,7 @@ export async function prepareDepositGroup(
const totalDepositCost = await getTotalPaymentCost(ws, payCoinSel.coinSel);
const effectiveDepositAmount = await getEffectiveDepositAmount(
const effectiveDepositAmount = await getCounterpartyEffectiveDepositAmount(
ws,
p.targetType,
payCoinSel.coinSel,
@ -674,11 +655,12 @@ export async function createDepositGroup(
const depositGroupId = encodeCrock(getRandomBytes(32));
const effectiveDepositAmount = await getEffectiveDepositAmount(
ws,
p.targetType,
payCoinSel.coinSel,
);
const countarpartyEffectiveDepositAmount =
await getCounterpartyEffectiveDepositAmount(
ws,
p.targetType,
payCoinSel.coinSel,
);
const depositGroup: DepositGroupRecord = {
contractTermsHash,
@ -697,7 +679,9 @@ export async function createDepositGroup(
merchantPriv: merchantPair.priv,
merchantPub: merchantPair.pub,
totalPayCost: Amounts.stringify(totalDepositCost),
effectiveDepositAmount: Amounts.stringify(effectiveDepositAmount),
effectiveDepositAmount: Amounts.stringify(
countarpartyEffectiveDepositAmount,
),
wire: {
payto_uri: req.depositPaytoUri,
salt: wireSalt,
@ -733,10 +717,10 @@ export async function createDepositGroup(
}
/**
* Get the amount that will be deposited on the merchant's bank
* account, not considering aggregation.
* Get the amount that will be deposited on the users bank
* account after depositing, not considering aggregation.
*/
export async function getEffectiveDepositAmount(
export async function getCounterpartyEffectiveDepositAmount(
ws: InternalWalletState,
wireType: string,
pcs: PayCoinSelection,
@ -790,83 +774,3 @@ export async function getEffectiveDepositAmount(
});
return Amounts.sub(Amounts.sum(amt).amount, Amounts.sum(fees).amount).amount;
}
/**
* Get the fee amount that will be charged when trying to deposit the
* specified amount using the selected coins and the wire method.
*/
export async function getTotalFeesForDepositAmount(
ws: InternalWalletState,
wireType: string,
total: AmountJson,
pcs: PayCoinSelection,
): Promise<DepositGroupFees> {
const wireFee: AmountJson[] = [];
const coinFee: AmountJson[] = [];
const refreshFee: AmountJson[] = [];
const exchangeSet: Set<string> = new Set();
await ws.db
.mktx((x) => [x.coins, x.denominations, x.exchanges, x.exchangeDetails])
.runReadOnly(async (tx) => {
for (let i = 0; i < pcs.coinPubs.length; i++) {
const coin = await tx.coins.get(pcs.coinPubs[i]);
if (!coin) {
throw Error("can't calculate deposit amount, coin not found");
}
const denom = await ws.getDenomInfo(
ws,
tx,
coin.exchangeBaseUrl,
coin.denomPubHash,
);
if (!denom) {
throw Error("can't find denomination to calculate deposit amount");
}
coinFee.push(Amounts.parseOrThrow(denom.feeDeposit));
exchangeSet.add(coin.exchangeBaseUrl);
const allDenoms = await tx.denominations.indexes.byExchangeBaseUrl
.iter(coin.exchangeBaseUrl)
.filter((x) =>
Amounts.isSameCurrency(
DenominationRecord.getValue(x),
pcs.coinContributions[i],
),
);
const amountLeft = Amounts.sub(
denom.value,
pcs.coinContributions[i],
).amount;
const refreshCost = getTotalRefreshCost(allDenoms, denom, amountLeft);
refreshFee.push(refreshCost);
}
for (const exchangeUrl of exchangeSet.values()) {
const exchangeDetails = await getExchangeDetails(tx, exchangeUrl);
if (!exchangeDetails) {
continue;
}
const fee = exchangeDetails.wireInfo.feesForType[wireType]?.find(
(x) => {
return AbsoluteTime.isBetween(
AbsoluteTime.now(),
AbsoluteTime.fromTimestamp(x.startStamp),
AbsoluteTime.fromTimestamp(x.endStamp),
);
},
)?.wireFee;
if (fee) {
wireFee.push(Amounts.parseOrThrow(fee));
}
}
});
return {
coin: Amounts.stringify(Amounts.sumOrZero(total.currency, coinFee).amount),
wire: Amounts.stringify(Amounts.sumOrZero(total.currency, wireFee).amount),
refresh: Amounts.stringify(
Amounts.sumOrZero(total.currency, refreshFee).amount,
),
};
}

View File

@ -106,7 +106,7 @@ export async function withdrawTestBalance(
): Promise<void> {
const amount = req.amount;
const exchangeBaseUrl = req.exchangeBaseUrl;
const bankAccessApiBaseUrl = req.bankAccessApiBaseUrl ?? req.bankBaseUrl;
const bankAccessApiBaseUrl = req.bankAccessApiBaseUrl;
logger.trace(
`Registered bank user, bank access base url ${bankAccessApiBaseUrl}`,
@ -364,8 +364,7 @@ export async function runIntegrationTest(
logger.info("withdrawing test balance");
await withdrawTestBalance(ws, {
amount: args.amountToWithdraw,
bankBaseUrl: args.bankBaseUrl,
bankAccessApiBaseUrl: args.bankAccessApiBaseUrl ?? args.bankBaseUrl,
bankAccessApiBaseUrl: args.bankAccessApiBaseUrl,
exchangeBaseUrl: args.exchangeBaseUrl,
});
await ws.runUntilDone();
@ -393,8 +392,7 @@ export async function runIntegrationTest(
await withdrawTestBalance(ws, {
amount: Amounts.stringify(withdrawAmountTwo),
bankBaseUrl: args.bankBaseUrl,
bankAccessApiBaseUrl: args.bankAccessApiBaseUrl ?? args.bankBaseUrl,
bankAccessApiBaseUrl: args.bankAccessApiBaseUrl,
exchangeBaseUrl: args.exchangeBaseUrl,
});
@ -457,7 +455,6 @@ export async function runIntegrationTest2(
logger.info("withdrawing test balance");
await withdrawTestBalance(ws, {
amount: Amounts.stringify(amountToWithdraw),
bankBaseUrl: args.bankAccessApiBaseUrl /* FIXME: not necessary */,
bankAccessApiBaseUrl: args.bankAccessApiBaseUrl,
exchangeBaseUrl: args.exchangeBaseUrl,
});
@ -491,7 +488,6 @@ export async function runIntegrationTest2(
await withdrawTestBalance(ws, {
amount: Amounts.stringify(withdrawAmountTwo),
bankBaseUrl: args.bankAccessApiBaseUrl /* FIXME: not necessary */,
bankAccessApiBaseUrl: args.bankAccessApiBaseUrl,
exchangeBaseUrl: args.exchangeBaseUrl,
});

View File

@ -36,6 +36,8 @@ import {
TransactionByIdRequest,
TransactionsRequest,
TransactionsResponse,
TransactionState,
TransactionSubstate,
TransactionType,
WithdrawalType,
} from "@gnu-taler/taler-util";
@ -429,6 +431,8 @@ function buildTransactionForPushPaymentDebit(
): Transaction {
return {
type: TransactionType.PeerPushDebit,
txState: TransactionState.Unknown,
txSubstate: TransactionSubstate.Unknown,
amountEffective: pi.totalCost,
amountRaw: pi.amount,
exchangeBaseUrl: pi.exchangeBaseUrl,
@ -461,6 +465,8 @@ function buildTransactionForPullPaymentDebit(
): Transaction {
return {
type: TransactionType.PeerPullDebit,
txState: TransactionState.Unknown,
txSubstate: TransactionSubstate.Unknown,
amountEffective: pi.coinSel?.totalCost
? pi.coinSel?.totalCost
: Amounts.stringify(pi.contractTerms.amount),
@ -510,6 +516,8 @@ function buildTransactionForPeerPullCredit(
});
return {
type: TransactionType.PeerPullCredit,
txState: TransactionState.Unknown,
txSubstate: TransactionSubstate.Unknown,
amountEffective: Amounts.stringify(wsr.denomsSel.totalCoinValue),
amountRaw: Amounts.stringify(wsr.instructedAmount),
exchangeBaseUrl: wsr.exchangeBaseUrl,
@ -543,6 +551,8 @@ function buildTransactionForPeerPullCredit(
return {
type: TransactionType.PeerPullCredit,
txState: TransactionState.Unknown,
txSubstate: TransactionSubstate.Unknown,
amountEffective: Amounts.stringify(pullCredit.estimatedAmountEffective),
amountRaw: Amounts.stringify(peerContractTerms.amount),
exchangeBaseUrl: pullCredit.exchangeBaseUrl,
@ -580,6 +590,8 @@ function buildTransactionForPeerPushCredit(
return {
type: TransactionType.PeerPushCredit,
txState: TransactionState.Unknown,
txSubstate: TransactionSubstate.Unknown,
amountEffective: Amounts.stringify(wsr.denomsSel.totalCoinValue),
amountRaw: Amounts.stringify(wsr.instructedAmount),
exchangeBaseUrl: wsr.exchangeBaseUrl,
@ -603,6 +615,8 @@ function buildTransactionForPeerPushCredit(
return {
type: TransactionType.PeerPushCredit,
txState: TransactionState.Unknown,
txSubstate: TransactionSubstate.Unknown,
// FIXME: This is wrong, needs to consider fees!
amountEffective: Amounts.stringify(peerContractTerms.amount),
amountRaw: Amounts.stringify(peerContractTerms.amount),
@ -632,6 +646,8 @@ function buildTransactionForBankIntegratedWithdraw(
return {
type: TransactionType.Withdrawal,
txState: TransactionState.Unknown,
txSubstate: TransactionSubstate.Unknown,
amountEffective: Amounts.stringify(wsr.denomsSel.totalCoinValue),
amountRaw: Amounts.stringify(wsr.instructedAmount),
withdrawalDetails: {
@ -677,6 +693,8 @@ function buildTransactionForManualWithdraw(
return {
type: TransactionType.Withdrawal,
txState: TransactionState.Unknown,
txSubstate: TransactionSubstate.Unknown,
amountEffective: Amounts.stringify(
withdrawalGroup.denomsSel.totalCoinValue,
),
@ -727,6 +745,8 @@ function buildTransactionForRefresh(
).amount;
return {
type: TransactionType.Refresh,
txState: TransactionState.Unknown,
txSubstate: TransactionSubstate.Unknown,
refreshReason: refreshGroupRecord.reason,
amountEffective: Amounts.stringify(
Amounts.zeroOfCurrency(refreshGroupRecord.currency),
@ -768,6 +788,8 @@ function buildTransactionForDeposit(
return {
type: TransactionType.Deposit,
txState: TransactionState.Unknown,
txSubstate: TransactionSubstate.Unknown,
amountRaw: Amounts.stringify(dg.effectiveDepositAmount),
amountEffective: Amounts.stringify(dg.totalPayCost),
extendedStatus: dg.timestampFinished
@ -804,6 +826,8 @@ function buildTransactionForTip(
return {
type: TransactionType.Tip,
txState: TransactionState.Unknown,
txSubstate: TransactionSubstate.Unknown,
amountEffective: Amounts.stringify(tipRecord.tipAmountEffective),
amountRaw: Amounts.stringify(tipRecord.tipAmountRaw),
extendedStatus: tipRecord.pickedUpTimestamp
@ -899,6 +923,8 @@ async function buildTransactionForRefund(
return {
type: TransactionType.Refund,
txState: TransactionState.Unknown,
txSubstate: TransactionSubstate.Unknown,
info,
refundedTransactionId: makeTransactionId(
TransactionType.Payment,
@ -1001,6 +1027,8 @@ async function buildTransactionForPurchase(
return {
type: TransactionType.Payment,
txState: TransactionState.Unknown,
txSubstate: TransactionSubstate.Unknown,
amountRaw: Amounts.stringify(contractData.amount),
amountEffective: Amounts.stringify(purchaseRecord.payInfo.totalPayCost),
totalRefundRaw: Amounts.stringify(totalRefund.raw),

View File

@ -61,7 +61,6 @@ import {
GetContractTermsDetailsRequest,
GetExchangeTosRequest,
GetExchangeTosResult,
GetFeeForDepositRequest,
GetWithdrawalDetailsForAmountRequest,
GetWithdrawalDetailsForUriRequest,
InitiatePeerPullCreditRequest,
@ -94,8 +93,6 @@ import {
SetWalletDeviceIdRequest,
TestPayArgs,
TestPayResult,
TrackDepositGroupRequest,
TrackDepositGroupResponse,
Transaction,
TransactionByIdRequest,
TransactionsRequest,
@ -175,8 +172,6 @@ export enum WalletApiOperation {
ExportBackupRecovery = "exportBackupRecovery",
ImportBackupRecovery = "importBackupRecovery",
GetBackupInfo = "getBackupInfo",
TrackDepositGroup = "trackDepositGroup",
GetFeeForDeposit = "getFeeForDeposit",
PrepareDeposit = "prepareDeposit",
GetVersion = "getVersion",
DeleteTransaction = "deleteTransaction",
@ -512,21 +507,6 @@ export type CreateDepositGroupOp = {
response: CreateDepositGroupResponse;
};
/**
* Track the status of a deposit group by querying the exchange.
*/
export type TrackDepositGroupOp = {
op: WalletApiOperation.TrackDepositGroup;
request: TrackDepositGroupRequest;
response: TrackDepositGroupResponse;
};
export type GetFeeForDepositOp = {
op: WalletApiOperation.GetFeeForDeposit;
request: GetFeeForDepositRequest;
response: DepositGroupFees;
};
export type PrepareDepositOp = {
op: WalletApiOperation.PrepareDeposit;
request: PrepareDepositRequest;
@ -928,8 +908,6 @@ export type WalletOperations = {
[WalletApiOperation.SetExchangeTosAccepted]: SetExchangeTosAcceptedOp;
[WalletApiOperation.GetExchangeTos]: GetExchangeTosOp;
[WalletApiOperation.GetExchangeDetailedInfo]: GetExchangeDetailedInfoOp;
[WalletApiOperation.TrackDepositGroup]: TrackDepositGroupOp;
[WalletApiOperation.GetFeeForDeposit]: GetFeeForDepositOp;
[WalletApiOperation.PrepareDeposit]: PrepareDepositOp;
[WalletApiOperation.CreateDepositGroup]: CreateDepositGroupOp;
[WalletApiOperation.SetWalletDeviceId]: SetWalletDeviceIdOp;

View File

@ -48,7 +48,6 @@ import {
codecForGetBalanceDetailRequest,
codecForGetContractTermsDetails,
codecForGetExchangeTosRequest,
codecForGetFeeForDeposit,
codecForGetWithdrawalDetailsForAmountRequest,
codecForGetWithdrawalDetailsForUri,
codecForImportDbRequest,
@ -69,7 +68,6 @@ import {
codecForSetDevModeRequest,
codecForSetWalletDeviceIdRequest,
codecForTestPayArgs,
codecForTrackDepositGroupRequest,
codecForTransactionByIdRequest,
codecForTransactionsRequest,
codecForUserAttentionByIdRequest,
@ -174,10 +172,8 @@ import {
} from "./operations/common.js";
import {
createDepositGroup,
getFeeForDeposit,
prepareDepositGroup,
processDepositGroup,
trackDepositGroup,
} from "./operations/deposits.js";
import {
acceptExchangeTermsOfService,
@ -1030,8 +1026,8 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>(
case WalletApiOperation.WithdrawTestkudos: {
await withdrawTestBalance(ws, {
amount: "TESTKUDOS:10",
bankBaseUrl: "https://bank.test.taler.net/",
bankAccessApiBaseUrl: "https://bank.test.taler.net/",
bankAccessApiBaseUrl:
"https://bank.test.taler.net/demobanks/default/access-api/",
exchangeBaseUrl: "https://exchange.test.taler.net/",
});
return {
@ -1348,10 +1344,6 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>(
const resp = await getBackupInfo(ws);
return resp;
}
case WalletApiOperation.GetFeeForDeposit: {
const req = codecForGetFeeForDeposit().decode(payload);
return await getFeeForDeposit(ws, req);
}
case WalletApiOperation.PrepareDeposit: {
const req = codecForPrepareDepositRequest().decode(payload);
return await prepareDepositGroup(ws, req);
@ -1360,10 +1352,6 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>(
const req = codecForCreateDepositGroupRequest().decode(payload);
return await createDepositGroup(ws, req);
}
case WalletApiOperation.TrackDepositGroup: {
const req = codecForTrackDepositGroupRequest().decode(payload);
return trackDepositGroup(ws, req);
}
case WalletApiOperation.DeleteTransaction: {
const req = codecForDeleteTransactionRequest().decode(payload);
await deleteTransaction(ws, req.transactionId);