report manual withdrawals properly in transaction list
This commit is contained in:
parent
c6d80b0128
commit
75c5c59316
@ -53,7 +53,6 @@ import {
|
|||||||
processWithdrawGroup,
|
processWithdrawGroup,
|
||||||
getBankWithdrawalInfo,
|
getBankWithdrawalInfo,
|
||||||
denomSelectionInfoToState,
|
denomSelectionInfoToState,
|
||||||
getWithdrawDenomList,
|
|
||||||
} from "./withdraw";
|
} from "./withdraw";
|
||||||
import {
|
import {
|
||||||
guardOperationException,
|
guardOperationException,
|
||||||
@ -106,22 +105,25 @@ export async function createReserve(
|
|||||||
let bankInfo: ReserveBankInfo | undefined;
|
let bankInfo: ReserveBankInfo | undefined;
|
||||||
|
|
||||||
if (req.bankWithdrawStatusUrl) {
|
if (req.bankWithdrawStatusUrl) {
|
||||||
|
bankInfo = {
|
||||||
|
statusUrl: req.bankWithdrawStatusUrl,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const initialWithdrawalGroupId = encodeCrock(getRandomBytes(32));
|
||||||
|
|
||||||
const denomSelInfo = await selectWithdrawalDenoms(
|
const denomSelInfo = await selectWithdrawalDenoms(
|
||||||
ws,
|
ws,
|
||||||
canonExchange,
|
canonExchange,
|
||||||
req.amount,
|
req.amount,
|
||||||
);
|
);
|
||||||
const denomSel = denomSelectionInfoToState(denomSelInfo);
|
const initialDenomSel = denomSelectionInfoToState(denomSelInfo);
|
||||||
bankInfo = {
|
|
||||||
statusUrl: req.bankWithdrawStatusUrl,
|
|
||||||
amount: req.amount,
|
|
||||||
bankWithdrawalGroupId: encodeCrock(getRandomBytes(32)),
|
|
||||||
withdrawalStarted: false,
|
|
||||||
denomSel,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const reserveRecord: ReserveRecord = {
|
const reserveRecord: ReserveRecord = {
|
||||||
|
instructedAmount: req.amount,
|
||||||
|
initialWithdrawalGroupId,
|
||||||
|
initialDenomSel,
|
||||||
|
initialWithdrawalStarted: false,
|
||||||
timestampCreated: now,
|
timestampCreated: now,
|
||||||
exchangeBaseUrl: canonExchange,
|
exchangeBaseUrl: canonExchange,
|
||||||
reservePriv: keypair.priv,
|
reservePriv: keypair.priv,
|
||||||
@ -750,10 +752,9 @@ async function depleteReserve(
|
|||||||
|
|
||||||
let withdrawalGroupId: string;
|
let withdrawalGroupId: string;
|
||||||
|
|
||||||
const bankInfo = newReserve.bankInfo;
|
if (!newReserve.initialWithdrawalStarted) {
|
||||||
if (bankInfo && !bankInfo.withdrawalStarted) {
|
withdrawalGroupId = newReserve.initialWithdrawalGroupId;
|
||||||
withdrawalGroupId = bankInfo.bankWithdrawalGroupId;
|
newReserve.initialWithdrawalStarted = true;
|
||||||
bankInfo.withdrawalStarted = true;
|
|
||||||
} else {
|
} else {
|
||||||
withdrawalGroupId = encodeCrock(randomBytes(32));
|
withdrawalGroupId = encodeCrock(randomBytes(32));
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,10 @@ import {
|
|||||||
Transaction,
|
Transaction,
|
||||||
TransactionType,
|
TransactionType,
|
||||||
PaymentStatus,
|
PaymentStatus,
|
||||||
|
WithdrawalType,
|
||||||
|
WithdrawalDetails,
|
||||||
} from "../types/transactions";
|
} from "../types/transactions";
|
||||||
|
import { WithdrawalDetailsResponse } from "../types/walletTypes";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an event ID from the type and the primary key for the event.
|
* Create an event ID from the type and the primary key for the event.
|
||||||
@ -156,6 +159,7 @@ export async function getTransactions(
|
|||||||
Stores.reserveUpdatedEvents,
|
Stores.reserveUpdatedEvents,
|
||||||
Stores.recoupGroups,
|
Stores.recoupGroups,
|
||||||
],
|
],
|
||||||
|
// Report withdrawals that are currently in progress.
|
||||||
async (tx) => {
|
async (tx) => {
|
||||||
tx.iter(Stores.withdrawalGroups).forEachAsync(async (wsr) => {
|
tx.iter(Stores.withdrawalGroups).forEachAsync(async (wsr) => {
|
||||||
if (
|
if (
|
||||||
@ -171,23 +175,42 @@ export async function getTransactions(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let amountRaw: AmountJson | undefined = undefined;
|
switch (wsr.source.type) {
|
||||||
|
case WithdrawalSourceType.Reserve: {
|
||||||
if (wsr.source.type === WithdrawalSourceType.Reserve) {
|
|
||||||
const r = await tx.get(Stores.reserves, wsr.source.reservePub);
|
const r = await tx.get(Stores.reserves, wsr.source.reservePub);
|
||||||
if (r?.bankInfo?.amount) {
|
if (!r) {
|
||||||
amountRaw = r.bankInfo.amount;
|
break;
|
||||||
}
|
}
|
||||||
}
|
let amountRaw: AmountJson | undefined = undefined;
|
||||||
if (!amountRaw) {
|
if (wsr.withdrawalGroupId === r.initialWithdrawalGroupId) {
|
||||||
|
amountRaw = r.instructedAmount;
|
||||||
|
} else {
|
||||||
amountRaw = wsr.denomsSel.totalWithdrawCost;
|
amountRaw = wsr.denomsSel.totalWithdrawCost;
|
||||||
}
|
}
|
||||||
|
let withdrawalDetails: WithdrawalDetails;
|
||||||
|
if (r.bankInfo) {
|
||||||
|
withdrawalDetails = {
|
||||||
|
type: WithdrawalType.TalerBankIntegrationApi,
|
||||||
|
confirmed: true,
|
||||||
|
bankConfirmationUrl: r.bankInfo.confirmUrl,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
const exchange = await tx.get(Stores.exchanges, r.exchangeBaseUrl);
|
||||||
|
if (!exchange) {
|
||||||
|
// FIXME: report somehow
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
withdrawalDetails = {
|
||||||
|
type: WithdrawalType.ManualTransfer,
|
||||||
|
reservePublicKey: r.reservePub,
|
||||||
|
exchangePaytoUris: exchange.wireInfo?.accounts.map((x) => x.payto_uri) ?? [],
|
||||||
|
};
|
||||||
|
}
|
||||||
transactions.push({
|
transactions.push({
|
||||||
type: TransactionType.Withdrawal,
|
type: TransactionType.Withdrawal,
|
||||||
amountEffective: Amounts.stringify(wsr.denomsSel.totalCoinValue),
|
amountEffective: Amounts.stringify(wsr.denomsSel.totalCoinValue),
|
||||||
amountRaw: Amounts.stringify(amountRaw),
|
amountRaw: Amounts.stringify(amountRaw),
|
||||||
confirmed: true,
|
withdrawalDetails,
|
||||||
exchangeBaseUrl: wsr.exchangeBaseUrl,
|
exchangeBaseUrl: wsr.exchangeBaseUrl,
|
||||||
pending: !wsr.timestampFinish,
|
pending: !wsr.timestampFinish,
|
||||||
timestamp: wsr.timestampStart,
|
timestamp: wsr.timestampStart,
|
||||||
@ -196,9 +219,18 @@ export async function getTransactions(
|
|||||||
wsr.withdrawalGroupId,
|
wsr.withdrawalGroupId,
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Tips are reported via their own event
|
||||||
|
break;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
tx.iter(Stores.reserves).forEach((r) => {
|
// Report pending withdrawals based on reserves that
|
||||||
|
// were created, but where the actual withdrawal group has
|
||||||
|
// not started yet.
|
||||||
|
tx.iter(Stores.reserves).forEachAsync(async (r) => {
|
||||||
if (shouldSkipCurrency(transactionsRequest, r.currency)) {
|
if (shouldSkipCurrency(transactionsRequest, r.currency)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -213,23 +245,41 @@ export async function getTransactions(
|
|||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!r.bankInfo) {
|
if (r.initialWithdrawalStarted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
let withdrawalDetails: WithdrawalDetails;
|
||||||
|
if (r.bankInfo) {
|
||||||
|
withdrawalDetails = {
|
||||||
|
type: WithdrawalType.TalerBankIntegrationApi,
|
||||||
|
confirmed: false,
|
||||||
|
bankConfirmationUrl: r.bankInfo.confirmUrl,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const exchange = await tx.get(Stores.exchanges, r.exchangeBaseUrl);
|
||||||
|
if (!exchange) {
|
||||||
|
// FIXME: report somehow
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
withdrawalDetails = {
|
||||||
|
type: WithdrawalType.ManualTransfer,
|
||||||
|
reservePublicKey: r.reservePub,
|
||||||
|
exchangePaytoUris: exchange.wireInfo?.accounts.map((x) => x.payto_uri) ?? [],
|
||||||
|
};
|
||||||
|
}
|
||||||
transactions.push({
|
transactions.push({
|
||||||
type: TransactionType.Withdrawal,
|
type: TransactionType.Withdrawal,
|
||||||
confirmed: false,
|
amountRaw: Amounts.stringify(r.instructedAmount),
|
||||||
amountRaw: Amounts.stringify(r.bankInfo.amount),
|
|
||||||
amountEffective: Amounts.stringify(
|
amountEffective: Amounts.stringify(
|
||||||
r.bankInfo.denomSel.totalCoinValue,
|
r.initialDenomSel.totalCoinValue,
|
||||||
),
|
),
|
||||||
exchangeBaseUrl: r.exchangeBaseUrl,
|
exchangeBaseUrl: r.exchangeBaseUrl,
|
||||||
pending: true,
|
pending: true,
|
||||||
timestamp: r.timestampCreated,
|
timestamp: r.timestampCreated,
|
||||||
bankConfirmationUrl: r.bankInfo.confirmUrl,
|
withdrawalDetails: withdrawalDetails,
|
||||||
transactionId: makeEventId(
|
transactionId: makeEventId(
|
||||||
TransactionType.Withdrawal,
|
TransactionType.Withdrawal,
|
||||||
r.bankInfo.bankWithdrawalGroupId,
|
r.initialWithdrawalGroupId,
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -32,7 +32,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
BankWithdrawDetails,
|
BankWithdrawDetails,
|
||||||
ExchangeWithdrawDetails,
|
ExchangeWithdrawDetails,
|
||||||
WithdrawDetails,
|
WithdrawalDetailsResponse,
|
||||||
OperationError,
|
OperationError,
|
||||||
} from "../types/walletTypes";
|
} from "../types/walletTypes";
|
||||||
import {
|
import {
|
||||||
@ -708,7 +708,7 @@ export async function getWithdrawDetailsForUri(
|
|||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
talerWithdrawUri: string,
|
talerWithdrawUri: string,
|
||||||
maybeSelectedExchange?: string,
|
maybeSelectedExchange?: string,
|
||||||
): Promise<WithdrawDetails> {
|
): Promise<WithdrawalDetailsResponse> {
|
||||||
const info = await getBankWithdrawalInfo(ws, talerWithdrawUri);
|
const info = await getBankWithdrawalInfo(ws, talerWithdrawUri);
|
||||||
let rci: ExchangeWithdrawDetails | undefined = undefined;
|
let rci: ExchangeWithdrawDetails | undefined = undefined;
|
||||||
if (maybeSelectedExchange) {
|
if (maybeSelectedExchange) {
|
||||||
|
@ -221,10 +221,6 @@ export interface ReserveHistoryRecord {
|
|||||||
export interface ReserveBankInfo {
|
export interface ReserveBankInfo {
|
||||||
statusUrl: string;
|
statusUrl: string;
|
||||||
confirmUrl?: string;
|
confirmUrl?: string;
|
||||||
amount: AmountJson;
|
|
||||||
bankWithdrawalGroupId: string;
|
|
||||||
withdrawalStarted: boolean;
|
|
||||||
denomSel: DenomSelectionState;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -285,12 +281,28 @@ export interface ReserveRecord {
|
|||||||
*/
|
*/
|
||||||
exchangeWire: string;
|
exchangeWire: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Amount that was sent by the user to fund the reserve.
|
||||||
|
*/
|
||||||
|
instructedAmount: AmountJson;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extra state for when this is a withdrawal involving
|
* Extra state for when this is a withdrawal involving
|
||||||
* a Taler-integrated bank.
|
* a Taler-integrated bank.
|
||||||
*/
|
*/
|
||||||
bankInfo?: ReserveBankInfo;
|
bankInfo?: ReserveBankInfo;
|
||||||
|
|
||||||
|
initialWithdrawalGroupId: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Did we start the first withdrawal for this reserve?
|
||||||
|
*
|
||||||
|
* We only report a pending withdrawal for the reserve before
|
||||||
|
* the first withdrawal has started.
|
||||||
|
*/
|
||||||
|
initialWithdrawalStarted: boolean;
|
||||||
|
initialDenomSel: DenomSelectionState;
|
||||||
|
|
||||||
reserveStatus: ReserveRecordStatus;
|
reserveStatus: ReserveRecordStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1436,6 +1448,13 @@ export interface DenomSelectionState {
|
|||||||
}[];
|
}[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Group of withdrawal operations that need to be executed.
|
||||||
|
* (Either for a normal withdrawal or from a tip.)
|
||||||
|
*
|
||||||
|
* The withdrawal group record is only created after we know
|
||||||
|
* the coin selection we want to withdraw.
|
||||||
|
*/
|
||||||
export interface WithdrawalGroupRecord {
|
export interface WithdrawalGroupRecord {
|
||||||
withdrawalGroupId: string;
|
withdrawalGroupId: string;
|
||||||
|
|
||||||
|
@ -105,18 +105,35 @@ export const enum TransactionType {
|
|||||||
Tip = "tip",
|
Tip = "tip",
|
||||||
}
|
}
|
||||||
|
|
||||||
// This should only be used for actual withdrawals
|
export const enum WithdrawalType {
|
||||||
// and not for tips that have their own transactions type.
|
TalerBankIntegrationApi = "taler-bank-integration-api",
|
||||||
interface TransactionWithdrawal extends TransactionCommon {
|
ManualTransfer = "manual-transfer",
|
||||||
type: TransactionType.Withdrawal;
|
}
|
||||||
|
|
||||||
|
export type WithdrawalDetails =
|
||||||
|
| WithdrawalDetailsForManualTransfer
|
||||||
|
| WithdrawalDetailsForTalerBankIntegrationApi;
|
||||||
|
|
||||||
|
interface WithdrawalDetailsForManualTransfer {
|
||||||
|
type: WithdrawalType.ManualTransfer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exchange of the withdrawal.
|
* Public key of the reserve that needs to be funded
|
||||||
|
* manually.
|
||||||
*/
|
*/
|
||||||
exchangeBaseUrl?: string;
|
reservePublicKey: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* true if the bank has confirmed the withdrawal, false if not.
|
* Payto URIs that the exchange supports.
|
||||||
|
*/
|
||||||
|
exchangePaytoUris: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface WithdrawalDetailsForTalerBankIntegrationApi {
|
||||||
|
type: WithdrawalType.TalerBankIntegrationApi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set to true if the bank has confirmed the withdrawal, false if not.
|
||||||
* An unconfirmed withdrawal usually requires user-input and should be highlighted in the UI.
|
* An unconfirmed withdrawal usually requires user-input and should be highlighted in the UI.
|
||||||
* See also bankConfirmationUrl below.
|
* See also bankConfirmationUrl below.
|
||||||
*/
|
*/
|
||||||
@ -127,6 +144,17 @@ interface TransactionWithdrawal extends TransactionCommon {
|
|||||||
* initiated confirmation.
|
* initiated confirmation.
|
||||||
*/
|
*/
|
||||||
bankConfirmationUrl?: string;
|
bankConfirmationUrl?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This should only be used for actual withdrawals
|
||||||
|
// and not for tips that have their own transactions type.
|
||||||
|
interface TransactionWithdrawal extends TransactionCommon {
|
||||||
|
type: TransactionType.Withdrawal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exchange of the withdrawal.
|
||||||
|
*/
|
||||||
|
exchangeBaseUrl: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Amount that got subtracted from the reserve balance.
|
* Amount that got subtracted from the reserve balance.
|
||||||
@ -137,6 +165,8 @@ interface TransactionWithdrawal extends TransactionCommon {
|
|||||||
* Amount that actually was (or will be) added to the wallet's balance.
|
* Amount that actually was (or will be) added to the wallet's balance.
|
||||||
*/
|
*/
|
||||||
amountEffective: AmountString;
|
amountEffective: AmountString;
|
||||||
|
|
||||||
|
withdrawalDetails: WithdrawalDetails;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum PaymentStatus {
|
export const enum PaymentStatus {
|
||||||
|
@ -146,7 +146,7 @@ export interface ExchangeWithdrawDetails {
|
|||||||
walletVersion: string;
|
walletVersion: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WithdrawDetails {
|
export interface WithdrawalDetailsResponse {
|
||||||
bankWithdrawDetails: BankWithdrawDetails;
|
bankWithdrawDetails: BankWithdrawDetails;
|
||||||
exchangeWithdrawDetails: ExchangeWithdrawDetails | undefined;
|
exchangeWithdrawDetails: ExchangeWithdrawDetails | undefined;
|
||||||
}
|
}
|
||||||
|
@ -64,10 +64,9 @@ import {
|
|||||||
TipStatus,
|
TipStatus,
|
||||||
WalletBalance,
|
WalletBalance,
|
||||||
PreparePayResult,
|
PreparePayResult,
|
||||||
WithdrawDetails,
|
WithdrawalDetailsResponse,
|
||||||
AcceptWithdrawalResponse,
|
AcceptWithdrawalResponse,
|
||||||
PurchaseDetails,
|
PurchaseDetails,
|
||||||
ExchangeWithdrawDetails as ExchangeWithdrawalDetails,
|
|
||||||
RefreshReason,
|
RefreshReason,
|
||||||
ExchangeListItem,
|
ExchangeListItem,
|
||||||
ExchangesListRespose,
|
ExchangesListRespose,
|
||||||
@ -477,7 +476,7 @@ export class Wallet {
|
|||||||
async getWithdrawDetailsForUri(
|
async getWithdrawDetailsForUri(
|
||||||
talerWithdrawUri: string,
|
talerWithdrawUri: string,
|
||||||
maybeSelectedExchange?: string,
|
maybeSelectedExchange?: string,
|
||||||
): Promise<WithdrawDetails> {
|
): Promise<WithdrawalDetailsResponse> {
|
||||||
return getWithdrawDetailsForUri(
|
return getWithdrawDetailsForUri(
|
||||||
this.ws,
|
this.ws,
|
||||||
talerWithdrawUri,
|
talerWithdrawUri,
|
||||||
|
@ -146,7 +146,7 @@ export interface MessageMap {
|
|||||||
talerWithdrawUri: string;
|
talerWithdrawUri: string;
|
||||||
maybeSelectedExchange: string | undefined;
|
maybeSelectedExchange: string | undefined;
|
||||||
};
|
};
|
||||||
response: walletTypes.WithdrawDetails;
|
response: walletTypes.WithdrawalDetailsResponse;
|
||||||
};
|
};
|
||||||
"accept-withdrawal": {
|
"accept-withdrawal": {
|
||||||
request: { talerWithdrawUri: string; selectedExchange: string };
|
request: { talerWithdrawUri: string; selectedExchange: string };
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
import * as i18n from "../i18n";
|
import * as i18n from "../i18n";
|
||||||
|
|
||||||
import { WithdrawDetails } from "../../types/walletTypes";
|
import { WithdrawalDetailsResponse } from "../../types/walletTypes";
|
||||||
|
|
||||||
import { WithdrawDetailView, renderAmount } from "../renderHtml";
|
import { WithdrawDetailView, renderAmount } from "../renderHtml";
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ import {
|
|||||||
} from "../wxApi";
|
} from "../wxApi";
|
||||||
|
|
||||||
function WithdrawalDialog(props: { talerWithdrawUri: string }): JSX.Element {
|
function WithdrawalDialog(props: { talerWithdrawUri: string }): JSX.Element {
|
||||||
const [details, setDetails] = useState<WithdrawDetails | undefined>();
|
const [details, setDetails] = useState<WithdrawalDetailsResponse | undefined>();
|
||||||
const [selectedExchange, setSelectedExchange] = useState<
|
const [selectedExchange, setSelectedExchange] = useState<
|
||||||
string | undefined
|
string | undefined
|
||||||
>();
|
>();
|
||||||
@ -56,7 +56,7 @@ function WithdrawalDialog(props: { talerWithdrawUri: string }): JSX.Element {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchData = async (): Promise<void> => {
|
const fetchData = async (): Promise<void> => {
|
||||||
console.log("getting from", talerWithdrawUri);
|
console.log("getting from", talerWithdrawUri);
|
||||||
let d: WithdrawDetails | undefined = undefined;
|
let d: WithdrawalDetailsResponse | undefined = undefined;
|
||||||
try {
|
try {
|
||||||
d = await getWithdrawDetails(talerWithdrawUri, selectedExchange);
|
d = await getWithdrawDetails(talerWithdrawUri, selectedExchange);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -38,7 +38,7 @@ import {
|
|||||||
WalletBalance,
|
WalletBalance,
|
||||||
PurchaseDetails,
|
PurchaseDetails,
|
||||||
WalletDiagnostics,
|
WalletDiagnostics,
|
||||||
WithdrawDetails,
|
WithdrawalDetailsResponse,
|
||||||
PreparePayResult,
|
PreparePayResult,
|
||||||
AcceptWithdrawalResponse,
|
AcceptWithdrawalResponse,
|
||||||
ExtendedPermissionsResponse,
|
ExtendedPermissionsResponse,
|
||||||
@ -283,7 +283,7 @@ export function benchmarkCrypto(repetitions: number): Promise<BenchmarkResult> {
|
|||||||
export function getWithdrawDetails(
|
export function getWithdrawDetails(
|
||||||
talerWithdrawUri: string,
|
talerWithdrawUri: string,
|
||||||
maybeSelectedExchange: string | undefined,
|
maybeSelectedExchange: string | undefined,
|
||||||
): Promise<WithdrawDetails> {
|
): Promise<WithdrawalDetailsResponse> {
|
||||||
return callBackend("get-withdraw-details", {
|
return callBackend("get-withdraw-details", {
|
||||||
talerWithdrawUri,
|
talerWithdrawUri,
|
||||||
maybeSelectedExchange,
|
maybeSelectedExchange,
|
||||||
|
Loading…
Reference in New Issue
Block a user