wallet-core: get rid of duplicated withdrawal info API
This commit is contained in:
parent
da9ec5eb16
commit
6acddd6d70
@ -68,6 +68,7 @@ import { BackupRecovery } from "./backupTypes.js";
|
|||||||
import { PaytoUri } from "./payto.js";
|
import { PaytoUri } from "./payto.js";
|
||||||
import { TalerErrorCode } from "./taler-error-codes.js";
|
import { TalerErrorCode } from "./taler-error-codes.js";
|
||||||
import { AgeCommitmentProof } from "./talerCrypto.js";
|
import { AgeCommitmentProof } from "./talerCrypto.js";
|
||||||
|
import { VersionMatchResult } from "./libtool-version.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Response for the create reserve request to the wallet.
|
* Response for the create reserve request to the wallet.
|
||||||
@ -692,6 +693,7 @@ export interface ExchangeGlobalFees {
|
|||||||
|
|
||||||
signature: string;
|
signature: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const codecForExchangeAccount = (): Codec<ExchangeAccount> =>
|
const codecForExchangeAccount = (): Codec<ExchangeAccount> =>
|
||||||
buildCodecForObject<ExchangeAccount>()
|
buildCodecForObject<ExchangeAccount>()
|
||||||
.property("payto_uri", codecForString())
|
.property("payto_uri", codecForString())
|
||||||
@ -929,6 +931,110 @@ export interface ManualWithdrawalDetails {
|
|||||||
* Ways to pay the exchange.
|
* Ways to pay the exchange.
|
||||||
*/
|
*/
|
||||||
paytoUris: string[];
|
paytoUris: string[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the exchange supports age-restricted coins it will return
|
||||||
|
* the array of ages.
|
||||||
|
*/
|
||||||
|
ageRestrictionOptions?: number[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selected denominations withn some extra info.
|
||||||
|
*/
|
||||||
|
export interface DenomSelectionState {
|
||||||
|
totalCoinValue: AmountJson;
|
||||||
|
totalWithdrawCost: AmountJson;
|
||||||
|
selectedDenoms: {
|
||||||
|
denomPubHash: string;
|
||||||
|
count: number;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information about what will happen doing a withdrawal.
|
||||||
|
*
|
||||||
|
* Sent to the wallet frontend to be rendered and shown to the user.
|
||||||
|
*/
|
||||||
|
export interface ExchangeWithdrawalDetails {
|
||||||
|
exchangePaytoUris: string[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filtered wire info to send to the bank.
|
||||||
|
*/
|
||||||
|
exchangeWireAccounts: string[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selected denominations for withdraw.
|
||||||
|
*/
|
||||||
|
selectedDenoms: DenomSelectionState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does the wallet know about an auditor for
|
||||||
|
* the exchange that the reserve.
|
||||||
|
*/
|
||||||
|
isAudited: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Did the user already accept the current terms of service for the exchange?
|
||||||
|
*/
|
||||||
|
termsOfServiceAccepted: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The exchange is trusted directly.
|
||||||
|
*/
|
||||||
|
isTrusted: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The earliest deposit expiration of the selected coins.
|
||||||
|
*/
|
||||||
|
earliestDepositExpiration: TalerProtocolTimestamp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of currently offered denominations.
|
||||||
|
*/
|
||||||
|
numOfferedDenoms: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public keys of trusted auditors for the currency we're withdrawing.
|
||||||
|
*/
|
||||||
|
trustedAuditorPubs: string[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Result of checking the wallet's version
|
||||||
|
* against the exchange's version.
|
||||||
|
*
|
||||||
|
* Older exchanges don't return version information.
|
||||||
|
*/
|
||||||
|
versionMatch: VersionMatchResult | undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Libtool-style version string for the exchange or "unknown"
|
||||||
|
* for older exchanges.
|
||||||
|
*/
|
||||||
|
exchangeVersion: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Libtool-style version string for the wallet.
|
||||||
|
*/
|
||||||
|
walletVersion: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Amount that will be subtracted from the reserve's balance.
|
||||||
|
*/
|
||||||
|
withdrawalAmountRaw: AmountString;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Amount that will actually be added to the wallet's balance.
|
||||||
|
*/
|
||||||
|
withdrawalAmountEffective: AmountString;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the exchange supports age-restricted coins it will return
|
||||||
|
* the array of ages.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
ageRestrictionOptions?: number[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GetExchangeTosResult {
|
export interface GetExchangeTosResult {
|
||||||
@ -1142,24 +1248,6 @@ export const codecForForgetKnownBankAccounts =
|
|||||||
.property("payto", codecForString())
|
.property("payto", codecForString())
|
||||||
.build("ForgetKnownBankAccountsRequest");
|
.build("ForgetKnownBankAccountsRequest");
|
||||||
|
|
||||||
export interface GetExchangeWithdrawalInfo {
|
|
||||||
exchangeBaseUrl: string;
|
|
||||||
amount: AmountJson;
|
|
||||||
tosAcceptedFormat?: string[];
|
|
||||||
ageRestricted?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const codecForGetExchangeWithdrawalInfo =
|
|
||||||
(): Codec<GetExchangeWithdrawalInfo> =>
|
|
||||||
buildCodecForObject<GetExchangeWithdrawalInfo>()
|
|
||||||
.property("exchangeBaseUrl", codecForString())
|
|
||||||
.property("amount", codecForAmountJson())
|
|
||||||
.property(
|
|
||||||
"tosAcceptedFormat",
|
|
||||||
codecOptional(codecForList(codecForString())),
|
|
||||||
)
|
|
||||||
.build("GetExchangeWithdrawalInfo");
|
|
||||||
|
|
||||||
export interface AbortProposalRequest {
|
export interface AbortProposalRequest {
|
||||||
proposalId: string;
|
proposalId: string;
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,7 @@ import {
|
|||||||
DenominationInfo,
|
DenominationInfo,
|
||||||
GlobalFees,
|
GlobalFees,
|
||||||
ExchangeGlobalFees,
|
ExchangeGlobalFees,
|
||||||
|
DenomSelectionState,
|
||||||
} from "@gnu-taler/taler-util";
|
} from "@gnu-taler/taler-util";
|
||||||
import { RetryInfo, RetryTags } from "./util/retries.js";
|
import { RetryInfo, RetryTags } from "./util/retries.js";
|
||||||
import { Event, IDBDatabase } from "@gnu-taler/idb-bridge";
|
import { Event, IDBDatabase } from "@gnu-taler/idb-bridge";
|
||||||
@ -430,8 +431,11 @@ export interface ExchangeDetailsRecord {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Fees for exchange services
|
* Fees for exchange services
|
||||||
|
*
|
||||||
|
* FIXME: Put in separate object store!
|
||||||
*/
|
*/
|
||||||
globalFees: ExchangeGlobalFees[];
|
globalFees: ExchangeGlobalFees[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signing keys we got from the exchange, can also contain
|
* Signing keys we got from the exchange, can also contain
|
||||||
* older signing keys that are not returned by /keys anymore.
|
* older signing keys that are not returned by /keys anymore.
|
||||||
@ -1280,18 +1284,6 @@ export interface WalletBackupConfState {
|
|||||||
lastBackupNonce?: string;
|
lastBackupNonce?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Selected denominations withn some extra info.
|
|
||||||
*/
|
|
||||||
export interface DenomSelectionState {
|
|
||||||
totalCoinValue: AmountJson;
|
|
||||||
totalWithdrawCost: AmountJson;
|
|
||||||
selectedDenoms: {
|
|
||||||
denomPubHash: string;
|
|
||||||
count: number;
|
|
||||||
}[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export const enum WithdrawalRecordType {
|
export const enum WithdrawalRecordType {
|
||||||
BankManual = "bank-manual",
|
BankManual = "bank-manual",
|
||||||
BankIntegrated = "bank-integrated",
|
BankIntegrated = "bank-integrated",
|
||||||
|
@ -28,6 +28,7 @@ import {
|
|||||||
BackupWgType,
|
BackupWgType,
|
||||||
codecForContractTerms,
|
codecForContractTerms,
|
||||||
DenomKeyType,
|
DenomKeyType,
|
||||||
|
DenomSelectionState,
|
||||||
j2s,
|
j2s,
|
||||||
Logger,
|
Logger,
|
||||||
PayCoinSelection,
|
PayCoinSelection,
|
||||||
@ -43,7 +44,6 @@ import {
|
|||||||
CoinStatus,
|
CoinStatus,
|
||||||
DenominationRecord,
|
DenominationRecord,
|
||||||
DenominationVerificationStatus,
|
DenominationVerificationStatus,
|
||||||
DenomSelectionState,
|
|
||||||
OperationStatus,
|
OperationStatus,
|
||||||
ProposalDownload,
|
ProposalDownload,
|
||||||
PurchaseStatus,
|
PurchaseStatus,
|
||||||
|
@ -37,10 +37,12 @@ import {
|
|||||||
codecForWithdrawOperationStatusResponse,
|
codecForWithdrawOperationStatusResponse,
|
||||||
codecForWithdrawResponse,
|
codecForWithdrawResponse,
|
||||||
DenomKeyType,
|
DenomKeyType,
|
||||||
|
DenomSelectionState,
|
||||||
Duration,
|
Duration,
|
||||||
durationFromSpec,
|
durationFromSpec,
|
||||||
encodeCrock,
|
encodeCrock,
|
||||||
ExchangeListItem,
|
ExchangeListItem,
|
||||||
|
ExchangeWithdrawalDetails,
|
||||||
ExchangeWithdrawRequest,
|
ExchangeWithdrawRequest,
|
||||||
ForcedDenomSel,
|
ForcedDenomSel,
|
||||||
getRandomBytes,
|
getRandomBytes,
|
||||||
@ -67,9 +69,6 @@ import {
|
|||||||
CoinStatus,
|
CoinStatus,
|
||||||
DenominationRecord,
|
DenominationRecord,
|
||||||
DenominationVerificationStatus,
|
DenominationVerificationStatus,
|
||||||
DenomSelectionState,
|
|
||||||
ExchangeDetailsRecord,
|
|
||||||
ExchangeRecord,
|
|
||||||
PlanchetRecord,
|
PlanchetRecord,
|
||||||
WalletStoresV1,
|
WalletStoresV1,
|
||||||
WgInfo,
|
WgInfo,
|
||||||
@ -126,96 +125,6 @@ import {
|
|||||||
*/
|
*/
|
||||||
const logger = new Logger("operations/withdraw.ts");
|
const logger = new Logger("operations/withdraw.ts");
|
||||||
|
|
||||||
/**
|
|
||||||
* Information about what will happen when creating a reserve.
|
|
||||||
*
|
|
||||||
* Sent to the wallet frontend to be rendered and shown to the user.
|
|
||||||
*/
|
|
||||||
export interface ExchangeWithdrawDetails {
|
|
||||||
/**
|
|
||||||
* Exchange that the reserve will be created at.
|
|
||||||
*
|
|
||||||
* FIXME: Should be its own record.
|
|
||||||
*/
|
|
||||||
exchangeInfo: ExchangeRecord;
|
|
||||||
|
|
||||||
exchangeDetails: ExchangeDetailsRecord;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Filtered wire info to send to the bank.
|
|
||||||
*/
|
|
||||||
exchangeWireAccounts: string[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Selected denominations for withdraw.
|
|
||||||
*/
|
|
||||||
selectedDenoms: DenomSelectionState;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Does the wallet know about an auditor for
|
|
||||||
* the exchange that the reserve.
|
|
||||||
*/
|
|
||||||
isAudited: boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Did the user already accept the current terms of service for the exchange?
|
|
||||||
*/
|
|
||||||
termsOfServiceAccepted: boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The exchange is trusted directly.
|
|
||||||
*/
|
|
||||||
isTrusted: boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The earliest deposit expiration of the selected coins.
|
|
||||||
*/
|
|
||||||
earliestDepositExpiration: TalerProtocolTimestamp;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Number of currently offered denominations.
|
|
||||||
*/
|
|
||||||
numOfferedDenoms: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Public keys of trusted auditors for the currency we're withdrawing.
|
|
||||||
*/
|
|
||||||
trustedAuditorPubs: string[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Result of checking the wallet's version
|
|
||||||
* against the exchange's version.
|
|
||||||
*
|
|
||||||
* Older exchanges don't return version information.
|
|
||||||
*/
|
|
||||||
versionMatch: VersionMatchResult | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Libtool-style version string for the exchange or "unknown"
|
|
||||||
* for older exchanges.
|
|
||||||
*/
|
|
||||||
exchangeVersion: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Libtool-style version string for the wallet.
|
|
||||||
*/
|
|
||||||
walletVersion: string;
|
|
||||||
|
|
||||||
withdrawalAmountRaw: AmountString;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Amount that will actually be added to the wallet's balance.
|
|
||||||
*/
|
|
||||||
withdrawalAmountEffective: AmountString;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If the exchange supports age-restricted coins it will return
|
|
||||||
* the array of ages.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
ageRestrictionOptions?: number[];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a denom is withdrawable based on the expiration time,
|
* Check if a denom is withdrawable based on the expiration time,
|
||||||
* revocation and offered state.
|
* revocation and offered state.
|
||||||
@ -1280,7 +1189,7 @@ export async function getExchangeWithdrawalInfo(
|
|||||||
exchangeBaseUrl: string,
|
exchangeBaseUrl: string,
|
||||||
instructedAmount: AmountJson,
|
instructedAmount: AmountJson,
|
||||||
ageRestricted: number | undefined,
|
ageRestricted: number | undefined,
|
||||||
): Promise<ExchangeWithdrawDetails> {
|
): Promise<ExchangeWithdrawalDetails> {
|
||||||
const { exchange, exchangeDetails } =
|
const { exchange, exchangeDetails } =
|
||||||
await ws.exchangeOps.updateExchangeFromUrl(ws, exchangeBaseUrl);
|
await ws.exchangeOps.updateExchangeFromUrl(ws, exchangeBaseUrl);
|
||||||
await updateWithdrawalDenoms(ws, exchangeBaseUrl);
|
await updateWithdrawalDenoms(ws, exchangeBaseUrl);
|
||||||
@ -1378,10 +1287,14 @@ export async function getExchangeWithdrawalInfo(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const ret: ExchangeWithdrawDetails = {
|
const paytoUris = exchangeDetails.wireInfo.accounts.map((x) => x.payto_uri);
|
||||||
|
if (!paytoUris) {
|
||||||
|
throw Error("exchange is in invalid state");
|
||||||
|
}
|
||||||
|
|
||||||
|
const ret: ExchangeWithdrawalDetails = {
|
||||||
earliestDepositExpiration,
|
earliestDepositExpiration,
|
||||||
exchangeInfo: exchange,
|
exchangePaytoUris: paytoUris,
|
||||||
exchangeDetails,
|
|
||||||
exchangeWireAccounts,
|
exchangeWireAccounts,
|
||||||
exchangeVersion: exchangeDetails.protocolVersion || "unknown",
|
exchangeVersion: exchangeDetails.protocolVersion || "unknown",
|
||||||
isAudited,
|
isAudited,
|
||||||
|
@ -47,7 +47,6 @@ import {
|
|||||||
codecForForgetKnownBankAccounts,
|
codecForForgetKnownBankAccounts,
|
||||||
codecForGetContractTermsDetails,
|
codecForGetContractTermsDetails,
|
||||||
codecForGetExchangeTosRequest,
|
codecForGetExchangeTosRequest,
|
||||||
codecForGetExchangeWithdrawalInfo,
|
|
||||||
codecForGetFeeForDeposit,
|
codecForGetFeeForDeposit,
|
||||||
codecForGetWithdrawalDetailsForAmountRequest,
|
codecForGetWithdrawalDetailsForAmountRequest,
|
||||||
codecForGetWithdrawalDetailsForUri,
|
codecForGetWithdrawalDetailsForUri,
|
||||||
@ -112,7 +111,11 @@ import {
|
|||||||
importDb,
|
importDb,
|
||||||
WalletStoresV1,
|
WalletStoresV1,
|
||||||
} from "./db.js";
|
} from "./db.js";
|
||||||
import { applyDevExperiment, maybeInitDevMode, setDevMode } from "./dev-experiments.js";
|
import {
|
||||||
|
applyDevExperiment,
|
||||||
|
maybeInitDevMode,
|
||||||
|
setDevMode,
|
||||||
|
} from "./dev-experiments.js";
|
||||||
import { getErrorDetailFromException, TalerError } from "./errors.js";
|
import { getErrorDetailFromException, TalerError } from "./errors.js";
|
||||||
import {
|
import {
|
||||||
ActiveLongpollInfo,
|
ActiveLongpollInfo,
|
||||||
@ -248,32 +251,6 @@ const builtinExchanges: string[] = ["https://exchange.demo.taler.net/"];
|
|||||||
|
|
||||||
const logger = new Logger("wallet.ts");
|
const logger = new Logger("wallet.ts");
|
||||||
|
|
||||||
async function getWithdrawalDetailsForAmount(
|
|
||||||
ws: InternalWalletState,
|
|
||||||
exchangeBaseUrl: string,
|
|
||||||
amount: AmountJson,
|
|
||||||
restrictAge: number | undefined,
|
|
||||||
): Promise<ManualWithdrawalDetails> {
|
|
||||||
const wi = await getExchangeWithdrawalInfo(
|
|
||||||
ws,
|
|
||||||
exchangeBaseUrl,
|
|
||||||
amount,
|
|
||||||
restrictAge,
|
|
||||||
);
|
|
||||||
const paytoUris = wi.exchangeDetails.wireInfo.accounts.map(
|
|
||||||
(x) => x.payto_uri,
|
|
||||||
);
|
|
||||||
if (!paytoUris) {
|
|
||||||
throw Error("exchange is in invalid state");
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
amountRaw: Amounts.stringify(amount),
|
|
||||||
amountEffective: Amounts.stringify(wi.selectedDenoms.totalCoinValue),
|
|
||||||
paytoUris,
|
|
||||||
tosAccepted: wi.termsOfServiceAccepted,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call the right handler for a pending operation without doing
|
* Call the right handler for a pending operation without doing
|
||||||
* any special error handling.
|
* any special error handling.
|
||||||
@ -1038,16 +1015,6 @@ async function dispatchRequestInternal(
|
|||||||
const req = codecForGetWithdrawalDetailsForUri().decode(payload);
|
const req = codecForGetWithdrawalDetailsForUri().decode(payload);
|
||||||
return await getWithdrawalDetailsForUri(ws, req.talerWithdrawUri);
|
return await getWithdrawalDetailsForUri(ws, req.talerWithdrawUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
case "getExchangeWithdrawalInfo": {
|
|
||||||
const req = codecForGetExchangeWithdrawalInfo().decode(payload);
|
|
||||||
return await getExchangeWithdrawalInfo(
|
|
||||||
ws,
|
|
||||||
req.exchangeBaseUrl,
|
|
||||||
req.amount,
|
|
||||||
req.ageRestricted,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
case "acceptManualWithdrawal": {
|
case "acceptManualWithdrawal": {
|
||||||
const req = codecForAcceptManualWithdrawalRequet().decode(payload);
|
const req = codecForAcceptManualWithdrawalRequet().decode(payload);
|
||||||
const res = await createManualWithdrawal(ws, {
|
const res = await createManualWithdrawal(ws, {
|
||||||
@ -1060,12 +1027,18 @@ async function dispatchRequestInternal(
|
|||||||
case "getWithdrawalDetailsForAmount": {
|
case "getWithdrawalDetailsForAmount": {
|
||||||
const req =
|
const req =
|
||||||
codecForGetWithdrawalDetailsForAmountRequest().decode(payload);
|
codecForGetWithdrawalDetailsForAmountRequest().decode(payload);
|
||||||
return await getWithdrawalDetailsForAmount(
|
const wi = await getExchangeWithdrawalInfo(
|
||||||
ws,
|
ws,
|
||||||
req.exchangeBaseUrl,
|
req.exchangeBaseUrl,
|
||||||
Amounts.parseOrThrow(req.amount),
|
Amounts.parseOrThrow(req.amount),
|
||||||
req.restrictAge,
|
req.restrictAge,
|
||||||
);
|
);
|
||||||
|
return {
|
||||||
|
amountRaw: req.amount,
|
||||||
|
amountEffective: Amounts.stringify(wi.selectedDenoms.totalCoinValue),
|
||||||
|
paytoUris: wi.exchangePaytoUris,
|
||||||
|
tosAccepted: wi.termsOfServiceAccepted,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
case "getBalances": {
|
case "getBalances": {
|
||||||
return await getBalances(ws);
|
return await getBalances(ws);
|
||||||
@ -1255,7 +1228,7 @@ async function dispatchRequestInternal(
|
|||||||
case "withdrawFakebank": {
|
case "withdrawFakebank": {
|
||||||
const req = codecForWithdrawFakebankRequest().decode(payload);
|
const req = codecForWithdrawFakebankRequest().decode(payload);
|
||||||
const amount = Amounts.parseOrThrow(req.amount);
|
const amount = Amounts.parseOrThrow(req.amount);
|
||||||
const details = await getWithdrawalDetailsForAmount(
|
const details = await getExchangeWithdrawalInfo(
|
||||||
ws,
|
ws,
|
||||||
req.exchange,
|
req.exchange,
|
||||||
amount,
|
amount,
|
||||||
@ -1265,7 +1238,7 @@ async function dispatchRequestInternal(
|
|||||||
amount: amount,
|
amount: amount,
|
||||||
exchangeBaseUrl: req.exchange,
|
exchangeBaseUrl: req.exchange,
|
||||||
});
|
});
|
||||||
const paytoUri = details.paytoUris[0];
|
const paytoUri = details.exchangePaytoUris[0];
|
||||||
const pt = parsePaytoUri(paytoUri);
|
const pt = parsePaytoUri(paytoUri);
|
||||||
if (!pt) {
|
if (!pt) {
|
||||||
throw Error("failed to parse payto URI");
|
throw Error("failed to parse payto URI");
|
||||||
|
@ -182,16 +182,15 @@ function exchangeSelectionState(
|
|||||||
* about the withdrawal
|
* about the withdrawal
|
||||||
*/
|
*/
|
||||||
const amountHook = useAsyncAsHook(async () => {
|
const amountHook = useAsyncAsHook(async () => {
|
||||||
const info = await api.getExchangeWithdrawalInfo({
|
const info = await api.getWithdrawalDetailsForAmount({
|
||||||
exchangeBaseUrl: currentExchange.exchangeBaseUrl,
|
exchangeBaseUrl: currentExchange.exchangeBaseUrl,
|
||||||
amount: chosenAmount,
|
amount: Amounts.stringify(chosenAmount),
|
||||||
tosAcceptedFormat: ["text/xml"],
|
restrictAge: ageRestricted,
|
||||||
ageRestricted,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const withdrawAmount = {
|
const withdrawAmount = {
|
||||||
raw: Amounts.parseOrThrow(info.withdrawalAmountRaw),
|
raw: Amounts.parseOrThrow(info.amountRaw),
|
||||||
effective: Amounts.parseOrThrow(info.withdrawalAmountEffective),
|
effective: Amounts.parseOrThrow(info.amountEffective),
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -22,14 +22,11 @@
|
|||||||
import {
|
import {
|
||||||
Amounts,
|
Amounts,
|
||||||
ExchangeFullDetails,
|
ExchangeFullDetails,
|
||||||
ExchangeListItem,
|
|
||||||
GetExchangeTosResult,
|
GetExchangeTosResult,
|
||||||
} from "@gnu-taler/taler-util";
|
} from "@gnu-taler/taler-util";
|
||||||
import { ExchangeWithdrawDetails } from "@gnu-taler/taler-wallet-core";
|
|
||||||
import { expect } from "chai";
|
import { expect } from "chai";
|
||||||
import { mountHook } from "../../test-utils.js";
|
import { mountHook } from "../../test-utils.js";
|
||||||
import { useComponentStateFromURI } from "./state.js";
|
import { useComponentStateFromURI } from "./state.js";
|
||||||
import * as wxApi from "../../wxApi.js";
|
|
||||||
|
|
||||||
const exchanges: ExchangeFullDetails[] = [
|
const exchanges: ExchangeFullDetails[] = [
|
||||||
{
|
{
|
||||||
@ -162,20 +159,11 @@ describe("Withdraw CTA states", () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
listExchanges: async () => ({ exchanges }),
|
listExchanges: async () => ({ exchanges }),
|
||||||
getWithdrawalDetailsForUri: async ({
|
getWithdrawalDetailsForUri: async ({ talerWithdrawUri }: any) => ({
|
||||||
talerWithdrawUri,
|
amount: "ARS:2",
|
||||||
}: any): Promise<ExchangeWithdrawDetails> =>
|
possibleExchanges: exchanges,
|
||||||
({
|
defaultExchangeBaseUrl: exchanges[0].exchangeBaseUrl,
|
||||||
amount: "ARS:2",
|
}),
|
||||||
possibleExchanges: exchanges,
|
|
||||||
defaultExchangeBaseUrl: exchanges[0].exchangeBaseUrl,
|
|
||||||
} as Partial<ExchangeWithdrawDetails> as ExchangeWithdrawDetails),
|
|
||||||
getExchangeWithdrawalInfo:
|
|
||||||
async (): Promise<ExchangeWithdrawDetails> =>
|
|
||||||
({
|
|
||||||
withdrawalAmountRaw: "ARS:2",
|
|
||||||
withdrawalAmountEffective: "ARS:2",
|
|
||||||
} as any),
|
|
||||||
getExchangeTos: async (): Promise<GetExchangeTosResult> => ({
|
getExchangeTos: async (): Promise<GetExchangeTosResult> => ({
|
||||||
contentType: "text",
|
contentType: "text",
|
||||||
content: "just accept",
|
content: "just accept",
|
||||||
@ -255,19 +243,12 @@ describe("Withdraw CTA states", () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
listExchanges: async () => listExchangesResponse,
|
listExchanges: async () => ({ exchanges }),
|
||||||
getWithdrawalDetailsForUri: async ({ talerWithdrawUri }: any) =>
|
getWithdrawalDetailsForUri: async ({ talerWithdrawUri }: any) => ({
|
||||||
({
|
amount: "ARS:2",
|
||||||
amount: "ARS:2",
|
possibleExchanges: exchanges,
|
||||||
possibleExchanges: exchanges,
|
defaultExchangeBaseUrl: exchanges[0].exchangeBaseUrl,
|
||||||
defaultExchangeBaseUrl: exchanges[0].exchangeBaseUrl,
|
}),
|
||||||
} as Partial<ExchangeWithdrawDetails> as ExchangeWithdrawDetails),
|
|
||||||
getExchangeWithdrawalInfo:
|
|
||||||
async (): Promise<ExchangeWithdrawDetails> =>
|
|
||||||
({
|
|
||||||
withdrawalAmountRaw: "ARS:2",
|
|
||||||
withdrawalAmountEffective: "ARS:2",
|
|
||||||
} as any),
|
|
||||||
getExchangeTos: async (): Promise<GetExchangeTosResult> => ({
|
getExchangeTos: async (): Promise<GetExchangeTosResult> => ({
|
||||||
contentType: "text",
|
contentType: "text",
|
||||||
content: "just accept",
|
content: "just accept",
|
||||||
|
@ -51,8 +51,8 @@ import {
|
|||||||
ExchangesListResponse,
|
ExchangesListResponse,
|
||||||
ForgetKnownBankAccountsRequest,
|
ForgetKnownBankAccountsRequest,
|
||||||
GetExchangeTosResult,
|
GetExchangeTosResult,
|
||||||
GetExchangeWithdrawalInfo,
|
|
||||||
GetFeeForDepositRequest,
|
GetFeeForDepositRequest,
|
||||||
|
GetWithdrawalDetailsForAmountRequest,
|
||||||
GetWithdrawalDetailsForUriRequest,
|
GetWithdrawalDetailsForUriRequest,
|
||||||
InitiatePeerPullPaymentRequest,
|
InitiatePeerPullPaymentRequest,
|
||||||
InitiatePeerPullPaymentResponse,
|
InitiatePeerPullPaymentResponse,
|
||||||
@ -60,6 +60,7 @@ import {
|
|||||||
InitiatePeerPushPaymentResponse,
|
InitiatePeerPushPaymentResponse,
|
||||||
KnownBankAccounts,
|
KnownBankAccounts,
|
||||||
Logger,
|
Logger,
|
||||||
|
ManualWithdrawalDetails,
|
||||||
NotificationType,
|
NotificationType,
|
||||||
PaytoUri,
|
PaytoUri,
|
||||||
PrepareDepositRequest,
|
PrepareDepositRequest,
|
||||||
@ -81,7 +82,6 @@ import {
|
|||||||
import {
|
import {
|
||||||
AddBackupProviderRequest,
|
AddBackupProviderRequest,
|
||||||
BackupInfo,
|
BackupInfo,
|
||||||
ExchangeWithdrawDetails,
|
|
||||||
PendingOperationsResponse,
|
PendingOperationsResponse,
|
||||||
RemoveBackupProviderRequest,
|
RemoveBackupProviderRequest,
|
||||||
TalerError,
|
TalerError,
|
||||||
@ -459,14 +459,12 @@ export function getWithdrawalDetailsForUri(
|
|||||||
return callBackend("getWithdrawalDetailsForUri", req);
|
return callBackend("getWithdrawalDetailsForUri", req);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
export function getWithdrawalDetailsForAmount(
|
||||||
* Get diagnostics information
|
req: GetWithdrawalDetailsForAmountRequest,
|
||||||
*/
|
): Promise<ManualWithdrawalDetails> {
|
||||||
export function getExchangeWithdrawalInfo(
|
return callBackend("getWithdrawalDetailsForAmount", req);
|
||||||
req: GetExchangeWithdrawalInfo,
|
|
||||||
): Promise<ExchangeWithdrawDetails> {
|
|
||||||
return callBackend("getExchangeWithdrawalInfo", req);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getExchangeTos(
|
export function getExchangeTos(
|
||||||
exchangeBaseUrl: string,
|
exchangeBaseUrl: string,
|
||||||
acceptedFormat: string[],
|
acceptedFormat: string[],
|
||||||
|
Loading…
Reference in New Issue
Block a user