remove some type literal and pretty
This commit is contained in:
parent
d97f440f25
commit
444c5427f4
@ -243,7 +243,9 @@ export interface TalerCryptoInterface {
|
|||||||
|
|
||||||
signRefund(req: SignRefundRequest): Promise<SignRefundResponse>;
|
signRefund(req: SignRefundRequest): Promise<SignRefundResponse>;
|
||||||
|
|
||||||
signDeletePurse(req: SignDeletePurseRequest): Promise<SignDeletePurseResponse>;
|
signDeletePurse(
|
||||||
|
req: SignDeletePurseRequest,
|
||||||
|
): Promise<SignDeletePurseResponse>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1695,7 +1697,7 @@ export const nativeCryptoR: TalerCryptoInterfaceR = {
|
|||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
sig: sigResp.sig,
|
sig: sigResp.sig,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -271,7 +271,6 @@ export interface SignRefundResponse {
|
|||||||
sig: string;
|
sig: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface SignDeletePurseRequest {
|
export interface SignDeletePurseRequest {
|
||||||
pursePriv: string;
|
pursePriv: string;
|
||||||
}
|
}
|
||||||
|
@ -120,13 +120,7 @@ export interface TopupReserveWithDemobankArgs {
|
|||||||
export async function topupReserveWithDemobank(
|
export async function topupReserveWithDemobank(
|
||||||
args: TopupReserveWithDemobankArgs,
|
args: TopupReserveWithDemobankArgs,
|
||||||
) {
|
) {
|
||||||
const {
|
const { http, bankAccessApiBaseUrl, amount, exchangeInfo, reservePub } = args;
|
||||||
http,
|
|
||||||
bankAccessApiBaseUrl,
|
|
||||||
amount,
|
|
||||||
exchangeInfo,
|
|
||||||
reservePub,
|
|
||||||
} = args;
|
|
||||||
const bankHandle: BankServiceHandle = {
|
const bankHandle: BankServiceHandle = {
|
||||||
bankAccessApiBaseUrl: bankAccessApiBaseUrl,
|
bankAccessApiBaseUrl: bankAccessApiBaseUrl,
|
||||||
http,
|
http,
|
||||||
|
@ -62,11 +62,7 @@ import { InternalWalletState } from "../../internal-wallet-state.js";
|
|||||||
import { assertUnreachable } from "../../util/assertUnreachable.js";
|
import { assertUnreachable } from "../../util/assertUnreachable.js";
|
||||||
import { checkLogicInvariant } from "../../util/invariants.js";
|
import { checkLogicInvariant } from "../../util/invariants.js";
|
||||||
import { GetReadOnlyAccess, GetReadWriteAccess } from "../../util/query.js";
|
import { GetReadOnlyAccess, GetReadWriteAccess } from "../../util/query.js";
|
||||||
import {
|
import { makeCoinAvailable, makeTombstoneId, TombstoneTag } from "../common.js";
|
||||||
makeCoinAvailable,
|
|
||||||
makeTombstoneId,
|
|
||||||
TombstoneTag,
|
|
||||||
} from "../common.js";
|
|
||||||
import { getExchangeDetails } from "../exchanges.js";
|
import { getExchangeDetails } from "../exchanges.js";
|
||||||
import { extractContractData } from "../pay-merchant.js";
|
import { extractContractData } from "../pay-merchant.js";
|
||||||
import { provideBackupState } from "./state.js";
|
import { provideBackupState } from "./state.js";
|
||||||
|
@ -464,7 +464,7 @@ export type ParsedTombstone =
|
|||||||
tag: TombstoneTag.DeleteWithdrawalGroup;
|
tag: TombstoneTag.DeleteWithdrawalGroup;
|
||||||
withdrawalGroupId: string;
|
withdrawalGroupId: string;
|
||||||
}
|
}
|
||||||
| { tag: TombstoneTag.DeleteRefund; refundGroupId: string }
|
| { tag: TombstoneTag.DeleteRefund; refundGroupId: string };
|
||||||
|
|
||||||
export function constructTombstone(p: ParsedTombstone): TombstoneIdStr {
|
export function constructTombstone(p: ParsedTombstone): TombstoneIdStr {
|
||||||
switch (p.tag) {
|
switch (p.tag) {
|
||||||
|
@ -495,8 +495,7 @@ async function waitForRefreshOnDepositGroup(
|
|||||||
if (refreshGroup.operationStatus === RefreshOperationStatus.Finished) {
|
if (refreshGroup.operationStatus === RefreshOperationStatus.Finished) {
|
||||||
newOpState = DepositOperationStatus.Aborted;
|
newOpState = DepositOperationStatus.Aborted;
|
||||||
} else if (
|
} else if (
|
||||||
refreshGroup.operationStatus ===
|
refreshGroup.operationStatus === RefreshOperationStatus.Failed
|
||||||
RefreshOperationStatus.Failed
|
|
||||||
) {
|
) {
|
||||||
newOpState = DepositOperationStatus.Aborted;
|
newOpState = DepositOperationStatus.Aborted;
|
||||||
}
|
}
|
||||||
|
@ -208,14 +208,13 @@ async function longpollKycStatus(
|
|||||||
const transitionInfo = await ws.db
|
const transitionInfo = await ws.db
|
||||||
.mktx((x) => [x.peerPullPaymentInitiations])
|
.mktx((x) => [x.peerPullPaymentInitiations])
|
||||||
.runReadWrite(async (tx) => {
|
.runReadWrite(async (tx) => {
|
||||||
const peerIni = await tx.peerPullPaymentInitiations.get(
|
const peerIni = await tx.peerPullPaymentInitiations.get(pursePub);
|
||||||
pursePub,
|
|
||||||
);
|
|
||||||
if (!peerIni) {
|
if (!peerIni) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
peerIni.status !== PeerPullPaymentInitiationStatus.PendingMergeKycRequired
|
peerIni.status !==
|
||||||
|
PeerPullPaymentInitiationStatus.PendingMergeKycRequired
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -254,10 +253,7 @@ async function processPeerPullCreditAbortingDeletePurse(
|
|||||||
const sigResp = await ws.cryptoApi.signDeletePurse({
|
const sigResp = await ws.cryptoApi.signDeletePurse({
|
||||||
pursePriv,
|
pursePriv,
|
||||||
});
|
});
|
||||||
const purseUrl = new URL(
|
const purseUrl = new URL(`purses/${pursePub}`, peerPullIni.exchangeBaseUrl);
|
||||||
`purses/${pursePub}`,
|
|
||||||
peerPullIni.exchangeBaseUrl,
|
|
||||||
);
|
|
||||||
const resp = await ws.http.fetch(purseUrl.href, {
|
const resp = await ws.http.fetch(purseUrl.href, {
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
headers: {
|
headers: {
|
||||||
@ -517,9 +513,7 @@ async function processPeerPullCreditKycRequired(
|
|||||||
const { transitionInfo, result } = await ws.db
|
const { transitionInfo, result } = await ws.db
|
||||||
.mktx((x) => [x.peerPullPaymentInitiations])
|
.mktx((x) => [x.peerPullPaymentInitiations])
|
||||||
.runReadWrite(async (tx) => {
|
.runReadWrite(async (tx) => {
|
||||||
const peerInc = await tx.peerPullPaymentInitiations.get(
|
const peerInc = await tx.peerPullPaymentInitiations.get(pursePub);
|
||||||
pursePub,
|
|
||||||
);
|
|
||||||
if (!peerInc) {
|
if (!peerInc) {
|
||||||
return {
|
return {
|
||||||
transitionInfo: undefined,
|
transitionInfo: undefined,
|
||||||
@ -532,7 +526,8 @@ async function processPeerPullCreditKycRequired(
|
|||||||
requirementRow: kycPending.requirement_row,
|
requirementRow: kycPending.requirement_row,
|
||||||
};
|
};
|
||||||
peerInc.kycUrl = kycStatus.kyc_url;
|
peerInc.kycUrl = kycStatus.kyc_url;
|
||||||
peerInc.status = PeerPullPaymentInitiationStatus.PendingMergeKycRequired;
|
peerInc.status =
|
||||||
|
PeerPullPaymentInitiationStatus.PendingMergeKycRequired;
|
||||||
const newTxState = computePeerPullCreditTransactionState(peerInc);
|
const newTxState = computePeerPullCreditTransactionState(peerInc);
|
||||||
await tx.peerPullPaymentInitiations.put(peerInc);
|
await tx.peerPullPaymentInitiations.put(peerInc);
|
||||||
// We'll remove this eventually! New clients should rely on the
|
// We'll remove this eventually! New clients should rely on the
|
||||||
|
@ -45,14 +45,24 @@ import {
|
|||||||
PreparePayResultType,
|
PreparePayResultType,
|
||||||
} from "@gnu-taler/taler-util";
|
} from "@gnu-taler/taler-util";
|
||||||
import { InternalWalletState } from "../internal-wallet-state.js";
|
import { InternalWalletState } from "../internal-wallet-state.js";
|
||||||
import { confirmPay, preparePayForUri, startRefundQueryForUri } from "./pay-merchant.js";
|
import {
|
||||||
|
confirmPay,
|
||||||
|
preparePayForUri,
|
||||||
|
startRefundQueryForUri,
|
||||||
|
} from "./pay-merchant.js";
|
||||||
import { getBalances } from "./balance.js";
|
import { getBalances } from "./balance.js";
|
||||||
import { checkLogicInvariant } from "../util/invariants.js";
|
import { checkLogicInvariant } from "../util/invariants.js";
|
||||||
import { acceptWithdrawalFromUri } from "./withdraw.js";
|
import { acceptWithdrawalFromUri } from "./withdraw.js";
|
||||||
import { updateExchangeFromUrl } from "./exchanges.js";
|
import { updateExchangeFromUrl } from "./exchanges.js";
|
||||||
import { initiatePeerPullPayment } from "./pay-peer-pull-credit.js";
|
import { initiatePeerPullPayment } from "./pay-peer-pull-credit.js";
|
||||||
import { preparePeerPullDebit, confirmPeerPullDebit } from "./pay-peer-pull-debit.js";
|
import {
|
||||||
import { preparePeerPushCredit, confirmPeerPushCredit } from "./pay-peer-push-credit.js";
|
preparePeerPullDebit,
|
||||||
|
confirmPeerPullDebit,
|
||||||
|
} from "./pay-peer-pull-debit.js";
|
||||||
|
import {
|
||||||
|
preparePeerPushCredit,
|
||||||
|
confirmPeerPushCredit,
|
||||||
|
} from "./pay-peer-push-credit.js";
|
||||||
import { initiatePeerPushDebit } from "./pay-peer-push-debit.js";
|
import { initiatePeerPushDebit } from "./pay-peer-push-debit.js";
|
||||||
|
|
||||||
const logger = new Logger("operations/testing.ts");
|
const logger = new Logger("operations/testing.ts");
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
import test, { ExecutionContext } from "ava";
|
import test, { ExecutionContext } from "ava";
|
||||||
import {
|
import {
|
||||||
|
AmountMode,
|
||||||
|
OperationType,
|
||||||
calculatePlanFormAvailableCoins,
|
calculatePlanFormAvailableCoins,
|
||||||
selectCoinForOperation,
|
selectCoinForOperation,
|
||||||
} from "./coinSelection.js";
|
} from "./coinSelection.js";
|
||||||
@ -24,6 +26,7 @@ import {
|
|||||||
AmountJson,
|
AmountJson,
|
||||||
Amounts,
|
Amounts,
|
||||||
Duration,
|
Duration,
|
||||||
|
TransactionAmountMode,
|
||||||
TransactionType,
|
TransactionType,
|
||||||
} from "@gnu-taler/taler-util";
|
} from "@gnu-taler/taler-util";
|
||||||
|
|
||||||
@ -67,10 +70,15 @@ test("get effective 2", (t) => {
|
|||||||
[kudos(2), 5],
|
[kudos(2), 5],
|
||||||
[kudos(5), 5],
|
[kudos(5), 5],
|
||||||
];
|
];
|
||||||
const result = selectCoinForOperation("credit", kudos(2), "net", {
|
const result = selectCoinForOperation(
|
||||||
list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
|
OperationType.Credit,
|
||||||
exchanges: {},
|
kudos(2),
|
||||||
});
|
AmountMode.Net,
|
||||||
|
{
|
||||||
|
list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
|
||||||
|
exchanges: {},
|
||||||
|
},
|
||||||
|
);
|
||||||
expect(t, result.coins).deep.equal(["KUDOS:2"]);
|
expect(t, result.coins).deep.equal(["KUDOS:2"]);
|
||||||
t.assert(result.refresh === undefined);
|
t.assert(result.refresh === undefined);
|
||||||
});
|
});
|
||||||
@ -80,10 +88,15 @@ test("get raw 4", (t) => {
|
|||||||
[kudos(2), 5],
|
[kudos(2), 5],
|
||||||
[kudos(5), 5],
|
[kudos(5), 5],
|
||||||
];
|
];
|
||||||
const result = selectCoinForOperation("credit", kudos(4), "gross", {
|
const result = selectCoinForOperation(
|
||||||
list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
|
OperationType.Credit,
|
||||||
exchanges: {},
|
kudos(4),
|
||||||
});
|
AmountMode.Gross,
|
||||||
|
{
|
||||||
|
list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
|
||||||
|
exchanges: {},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
expect(t, result.coins).deep.equal(["KUDOS:2", "KUDOS:2"]);
|
expect(t, result.coins).deep.equal(["KUDOS:2", "KUDOS:2"]);
|
||||||
t.assert(result.refresh === undefined);
|
t.assert(result.refresh === undefined);
|
||||||
@ -94,10 +107,15 @@ test("send effective 6", (t) => {
|
|||||||
[kudos(2), 5],
|
[kudos(2), 5],
|
||||||
[kudos(5), 5],
|
[kudos(5), 5],
|
||||||
];
|
];
|
||||||
const result = selectCoinForOperation("debit", kudos(6), "gross", {
|
const result = selectCoinForOperation(
|
||||||
list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
|
OperationType.Debit,
|
||||||
exchanges: {},
|
kudos(6),
|
||||||
});
|
AmountMode.Gross,
|
||||||
|
{
|
||||||
|
list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
|
||||||
|
exchanges: {},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
expect(t, result.coins).deep.equal(["KUDOS:5"]);
|
expect(t, result.coins).deep.equal(["KUDOS:5"]);
|
||||||
t.assert(result.refresh?.selected === "KUDOS:2");
|
t.assert(result.refresh?.selected === "KUDOS:2");
|
||||||
@ -108,10 +126,15 @@ test("send raw 6", (t) => {
|
|||||||
[kudos(2), 5],
|
[kudos(2), 5],
|
||||||
[kudos(5), 5],
|
[kudos(5), 5],
|
||||||
];
|
];
|
||||||
const result = selectCoinForOperation("debit", kudos(6), "gross", {
|
const result = selectCoinForOperation(
|
||||||
list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
|
OperationType.Debit,
|
||||||
exchanges: {},
|
kudos(6),
|
||||||
});
|
AmountMode.Gross,
|
||||||
|
{
|
||||||
|
list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
|
||||||
|
exchanges: {},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
expect(t, result.coins).deep.equal(["KUDOS:5"]);
|
expect(t, result.coins).deep.equal(["KUDOS:5"]);
|
||||||
t.assert(result.refresh?.selected === "KUDOS:2");
|
t.assert(result.refresh?.selected === "KUDOS:2");
|
||||||
@ -122,10 +145,15 @@ test("send raw 20 (not enough)", (t) => {
|
|||||||
[kudos(2), 1],
|
[kudos(2), 1],
|
||||||
[kudos(5), 2],
|
[kudos(5), 2],
|
||||||
];
|
];
|
||||||
const result = selectCoinForOperation("debit", kudos(20), "gross", {
|
const result = selectCoinForOperation(
|
||||||
list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
|
OperationType.Debit,
|
||||||
exchanges: {},
|
kudos(20),
|
||||||
});
|
AmountMode.Gross,
|
||||||
|
{
|
||||||
|
list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
|
||||||
|
exchanges: {},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
expect(t, result.coins).deep.equal(["KUDOS:5", "KUDOS:5", "KUDOS:2"]);
|
expect(t, result.coins).deep.equal(["KUDOS:5", "KUDOS:5", "KUDOS:2"]);
|
||||||
t.assert(result.refresh === undefined);
|
t.assert(result.refresh === undefined);
|
||||||
@ -147,7 +175,7 @@ test("deposit effective 2 ", (t) => {
|
|||||||
const result = calculatePlanFormAvailableCoins(
|
const result = calculatePlanFormAvailableCoins(
|
||||||
TransactionType.Deposit,
|
TransactionType.Deposit,
|
||||||
kudos(2),
|
kudos(2),
|
||||||
"effective",
|
TransactionAmountMode.Effective,
|
||||||
{
|
{
|
||||||
list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
|
list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
|
||||||
exchanges: {
|
exchanges: {
|
||||||
@ -173,7 +201,7 @@ test("deposit raw 2 ", (t) => {
|
|||||||
const result = calculatePlanFormAvailableCoins(
|
const result = calculatePlanFormAvailableCoins(
|
||||||
TransactionType.Deposit,
|
TransactionType.Deposit,
|
||||||
kudos(2),
|
kudos(2),
|
||||||
"raw",
|
TransactionAmountMode.Raw,
|
||||||
{
|
{
|
||||||
list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
|
list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
|
||||||
exchanges: {
|
exchanges: {
|
||||||
@ -199,7 +227,7 @@ test("withdraw raw 21 ", (t) => {
|
|||||||
const result = calculatePlanFormAvailableCoins(
|
const result = calculatePlanFormAvailableCoins(
|
||||||
TransactionType.Withdrawal,
|
TransactionType.Withdrawal,
|
||||||
kudos(21),
|
kudos(21),
|
||||||
"raw",
|
TransactionAmountMode.Raw,
|
||||||
{
|
{
|
||||||
list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
|
list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
|
||||||
exchanges: {
|
exchanges: {
|
||||||
|
@ -46,6 +46,7 @@ import {
|
|||||||
PayCoinSelection,
|
PayCoinSelection,
|
||||||
PayMerchantInsufficientBalanceDetails,
|
PayMerchantInsufficientBalanceDetails,
|
||||||
strcmp,
|
strcmp,
|
||||||
|
TransactionAmountMode,
|
||||||
TransactionType,
|
TransactionType,
|
||||||
} from "@gnu-taler/taler-util";
|
} from "@gnu-taler/taler-util";
|
||||||
import {
|
import {
|
||||||
@ -818,7 +819,7 @@ function getCoinsFilter(req: GetPlanForOperationRequest): CoinsFilter {
|
|||||||
export function calculatePlanFormAvailableCoins(
|
export function calculatePlanFormAvailableCoins(
|
||||||
transactionType: TransactionType,
|
transactionType: TransactionType,
|
||||||
amount: AmountJson,
|
amount: AmountJson,
|
||||||
mode: "effective" | "raw",
|
mode: TransactionAmountMode,
|
||||||
availableCoins: AvailableCoins,
|
availableCoins: AvailableCoins,
|
||||||
) {
|
) {
|
||||||
const operationType = getOperationType(transactionType);
|
const operationType = getOperationType(transactionType);
|
||||||
@ -828,7 +829,9 @@ export function calculatePlanFormAvailableCoins(
|
|||||||
usableCoins = selectCoinForOperation(
|
usableCoins = selectCoinForOperation(
|
||||||
operationType,
|
operationType,
|
||||||
amount,
|
amount,
|
||||||
mode === "effective" ? "net" : "gross",
|
mode === TransactionAmountMode.Effective
|
||||||
|
? AmountMode.Net
|
||||||
|
: AmountMode.Gross,
|
||||||
availableCoins,
|
availableCoins,
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
@ -839,11 +842,11 @@ export function calculatePlanFormAvailableCoins(
|
|||||||
//are from that exchange
|
//are from that exchange
|
||||||
const wireFee = Object.values(availableCoins.exchanges)[0].wireFee!;
|
const wireFee = Object.values(availableCoins.exchanges)[0].wireFee!;
|
||||||
|
|
||||||
if (mode === "effective") {
|
if (mode === TransactionAmountMode.Effective) {
|
||||||
usableCoins = selectCoinForOperation(
|
usableCoins = selectCoinForOperation(
|
||||||
operationType,
|
operationType,
|
||||||
amount,
|
amount,
|
||||||
"gross",
|
AmountMode.Gross,
|
||||||
availableCoins,
|
availableCoins,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -857,7 +860,7 @@ export function calculatePlanFormAvailableCoins(
|
|||||||
usableCoins = selectCoinForOperation(
|
usableCoins = selectCoinForOperation(
|
||||||
operationType,
|
operationType,
|
||||||
adjustedAmount,
|
adjustedAmount,
|
||||||
"net",
|
AmountMode.Net,
|
||||||
availableCoins,
|
availableCoins,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -913,6 +916,27 @@ export async function getPlanForOperation(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the operation going to be plan subtracts
|
||||||
|
* or adds amount in the wallet db
|
||||||
|
*/
|
||||||
|
export enum OperationType {
|
||||||
|
Credit = "credit",
|
||||||
|
Debit = "debit",
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How the amount should be interpreted
|
||||||
|
* net = without fee
|
||||||
|
* gross = with fee
|
||||||
|
*
|
||||||
|
* Net value is always lower than gross
|
||||||
|
*/
|
||||||
|
export enum AmountMode {
|
||||||
|
Net = "net",
|
||||||
|
Gross = "gross",
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param op defined which fee are we taking into consideration: deposits or withdraw
|
* @param op defined which fee are we taking into consideration: deposits or withdraw
|
||||||
@ -922,9 +946,9 @@ export async function getPlanForOperation(
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function selectCoinForOperation(
|
export function selectCoinForOperation(
|
||||||
op: "debit" | "credit",
|
op: OperationType,
|
||||||
limit: AmountJson,
|
limit: AmountJson,
|
||||||
mode: "net" | "gross",
|
mode: AmountMode,
|
||||||
coins: AvailableCoins,
|
coins: AvailableCoins,
|
||||||
): SelectedCoins {
|
): SelectedCoins {
|
||||||
const result: SelectedCoins = {
|
const result: SelectedCoins = {
|
||||||
@ -951,8 +975,11 @@ export function selectCoinForOperation(
|
|||||||
iterateDenoms: while (denomIdx < coins.list.length) {
|
iterateDenoms: while (denomIdx < coins.list.length) {
|
||||||
const denom = coins.list[denomIdx];
|
const denom = coins.list[denomIdx];
|
||||||
let total =
|
let total =
|
||||||
op === "credit" ? Number.MAX_SAFE_INTEGER : denom.totalAvailable ?? 0;
|
op === OperationType.Credit
|
||||||
const opFee = op === "credit" ? denom.denomWithdraw : denom.denomDeposit;
|
? Number.MAX_SAFE_INTEGER
|
||||||
|
: denom.totalAvailable ?? 0;
|
||||||
|
const opFee =
|
||||||
|
op === OperationType.Credit ? denom.denomWithdraw : denom.denomDeposit;
|
||||||
const contribution = Amounts.sub(denom.value, opFee).amount;
|
const contribution = Amounts.sub(denom.value, opFee).amount;
|
||||||
|
|
||||||
if (Amounts.isZero(contribution)) {
|
if (Amounts.isZero(contribution)) {
|
||||||
@ -969,7 +996,7 @@ export function selectCoinForOperation(
|
|||||||
contribution,
|
contribution,
|
||||||
).amount;
|
).amount;
|
||||||
|
|
||||||
const progress = mode === "gross" ? nextValue : nextContribution;
|
const progress = mode === AmountMode.Gross ? nextValue : nextContribution;
|
||||||
|
|
||||||
if (Amounts.cmp(progress, limit) === 1) {
|
if (Amounts.cmp(progress, limit) === 1) {
|
||||||
//the current coin is more than we need, try next denom
|
//the current coin is more than we need, try next denom
|
||||||
@ -1008,14 +1035,15 @@ export function selectCoinForOperation(
|
|||||||
// we made it
|
// we made it
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (op === "credit") {
|
if (op === OperationType.Credit) {
|
||||||
//doing withdraw there is no way to cover the gap
|
//doing withdraw there is no way to cover the gap
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
//tried all the coins but there is a gap
|
//tried all the coins but there is a gap
|
||||||
//doing deposit we can try refreshing coins
|
//doing deposit we can try refreshing coins
|
||||||
|
|
||||||
const total = mode === "gross" ? result.totalValue : result.totalContribution;
|
const total =
|
||||||
|
mode === AmountMode.Gross ? result.totalValue : result.totalContribution;
|
||||||
const gap = Amounts.sub(limit, total).amount;
|
const gap = Amounts.sub(limit, total).amount;
|
||||||
|
|
||||||
//about recursive calls
|
//about recursive calls
|
||||||
@ -1027,7 +1055,7 @@ export function selectCoinForOperation(
|
|||||||
refreshIteration: while (refreshIdx < coins.list.length) {
|
refreshIteration: while (refreshIdx < coins.list.length) {
|
||||||
const d = coins.list[refreshIdx];
|
const d = coins.list[refreshIdx];
|
||||||
const denomContribution =
|
const denomContribution =
|
||||||
mode === "gross"
|
mode === AmountMode.Gross
|
||||||
? Amounts.sub(d.value, d.denomRefresh).amount
|
? Amounts.sub(d.value, d.denomRefresh).amount
|
||||||
: Amounts.sub(d.value, d.denomDeposit, d.denomRefresh).amount;
|
: Amounts.sub(d.value, d.denomDeposit, d.denomRefresh).amount;
|
||||||
|
|
||||||
@ -1038,7 +1066,7 @@ export function selectCoinForOperation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const changeCost = selectCoinForOperation(
|
const changeCost = selectCoinForOperation(
|
||||||
"credit",
|
OperationType.Credit,
|
||||||
changeAfterDeposit,
|
changeAfterDeposit,
|
||||||
mode,
|
mode,
|
||||||
coins,
|
coins,
|
||||||
@ -1067,7 +1095,7 @@ export function selectCoinForOperation(
|
|||||||
refreshIdx++;
|
refreshIdx++;
|
||||||
}
|
}
|
||||||
if (choice) {
|
if (choice) {
|
||||||
if (mode === "gross") {
|
if (mode === AmountMode.Gross) {
|
||||||
result.totalValue = Amounts.add(result.totalValue, gap).amount;
|
result.totalValue = Amounts.add(result.totalValue, gap).amount;
|
||||||
result.totalContribution = Amounts.add(
|
result.totalContribution = Amounts.add(
|
||||||
result.totalContribution,
|
result.totalContribution,
|
||||||
@ -1096,9 +1124,9 @@ export function selectCoinForOperation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
type CompareCoinsFunction = (d1: CoinInfo, d2: CoinInfo) => -1 | 0 | 1;
|
type CompareCoinsFunction = (d1: CoinInfo, d2: CoinInfo) => -1 | 0 | 1;
|
||||||
function buildRankingForCoins(op: "debit" | "credit"): CompareCoinsFunction {
|
function buildRankingForCoins(op: OperationType): CompareCoinsFunction {
|
||||||
function getFee(d: CoinInfo) {
|
function getFee(d: CoinInfo) {
|
||||||
return op === "credit" ? d.denomWithdraw : d.denomDeposit;
|
return op === OperationType.Credit ? d.denomWithdraw : d.denomDeposit;
|
||||||
}
|
}
|
||||||
//different exchanges may have different wireFee
|
//different exchanges may have different wireFee
|
||||||
//ranking should take the relative contribution in the exchange
|
//ranking should take the relative contribution in the exchange
|
||||||
@ -1116,28 +1144,32 @@ function buildRankingForCoins(op: "debit" | "credit"): CompareCoinsFunction {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOperationType(txType: TransactionType): "credit" | "debit" {
|
function getOperationType(txType: TransactionType): OperationType {
|
||||||
const operationType =
|
const operationType =
|
||||||
txType === TransactionType.Withdrawal
|
txType === TransactionType.Withdrawal
|
||||||
? ("credit" as const)
|
? OperationType.Credit
|
||||||
: txType === TransactionType.Deposit
|
: txType === TransactionType.Deposit
|
||||||
? ("debit" as const)
|
? OperationType.Debit
|
||||||
: undefined;
|
: undefined;
|
||||||
if (!operationType) {
|
if (!operationType) {
|
||||||
throw Error(`operation type ${txType} not supported`);
|
throw Error(`operation type ${txType} not yet supported`);
|
||||||
}
|
}
|
||||||
return operationType;
|
return operationType;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAmountsWithFee(
|
function getAmountsWithFee(
|
||||||
op: "debit" | "credit",
|
op: OperationType,
|
||||||
value: AmountJson,
|
value: AmountJson,
|
||||||
contribution: AmountJson,
|
contribution: AmountJson,
|
||||||
details: any,
|
details: any,
|
||||||
): GetPlanForOperationResponse {
|
): GetPlanForOperationResponse {
|
||||||
return {
|
return {
|
||||||
rawAmount: Amounts.stringify(op === "credit" ? value : contribution),
|
rawAmount: Amounts.stringify(
|
||||||
effectiveAmount: Amounts.stringify(op === "credit" ? contribution : value),
|
op === OperationType.Credit ? value : contribution,
|
||||||
|
),
|
||||||
|
effectiveAmount: Amounts.stringify(
|
||||||
|
op === OperationType.Credit ? contribution : value,
|
||||||
|
),
|
||||||
details,
|
details,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -1202,7 +1234,7 @@ interface CoinsFilter {
|
|||||||
*/
|
*/
|
||||||
async function getAvailableCoins(
|
async function getAvailableCoins(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
op: "credit" | "debit",
|
op: OperationType,
|
||||||
currency: string,
|
currency: string,
|
||||||
filters: CoinsFilter = {},
|
filters: CoinsFilter = {},
|
||||||
): Promise<AvailableCoins> {
|
): Promise<AvailableCoins> {
|
||||||
@ -1286,7 +1318,7 @@ async function getAvailableCoins(
|
|||||||
let creditDeadline = AbsoluteTime.never();
|
let creditDeadline = AbsoluteTime.never();
|
||||||
let debitDeadline = AbsoluteTime.never();
|
let debitDeadline = AbsoluteTime.never();
|
||||||
//4.- filter coins restricted by age
|
//4.- filter coins restricted by age
|
||||||
if (op === "credit") {
|
if (op === OperationType.Credit) {
|
||||||
const ds = await tx.denominations.indexes.byExchangeBaseUrl.getAll(
|
const ds = await tx.denominations.indexes.byExchangeBaseUrl.getAll(
|
||||||
exchangeBaseUrl,
|
exchangeBaseUrl,
|
||||||
);
|
);
|
||||||
|
@ -458,7 +458,9 @@ export function isWithdrawableDenom(
|
|||||||
): boolean {
|
): boolean {
|
||||||
const now = AbsoluteTime.now();
|
const now = AbsoluteTime.now();
|
||||||
const start = AbsoluteTime.fromProtocolTimestamp(d.stampStart);
|
const start = AbsoluteTime.fromProtocolTimestamp(d.stampStart);
|
||||||
const withdrawExpire = AbsoluteTime.fromProtocolTimestamp(d.stampExpireWithdraw);
|
const withdrawExpire = AbsoluteTime.fromProtocolTimestamp(
|
||||||
|
d.stampExpireWithdraw,
|
||||||
|
);
|
||||||
const started = AbsoluteTime.cmp(now, start) >= 0;
|
const started = AbsoluteTime.cmp(now, start) >= 0;
|
||||||
let lastPossibleWithdraw: AbsoluteTime;
|
let lastPossibleWithdraw: AbsoluteTime;
|
||||||
if (denomselAllowLate) {
|
if (denomselAllowLate) {
|
||||||
|
Loading…
Reference in New Issue
Block a user