withdraw exchange URI
This commit is contained in:
parent
4b61945f6b
commit
74579ac2f2
@ -22,10 +22,12 @@ import {
|
|||||||
parseRefundUri,
|
parseRefundUri,
|
||||||
parseRestoreUri,
|
parseRestoreUri,
|
||||||
parseTipUri,
|
parseTipUri,
|
||||||
|
parseWithdrawExchangeUri,
|
||||||
parseWithdrawUri,
|
parseWithdrawUri,
|
||||||
stringifyPayPushUri,
|
stringifyPayPushUri,
|
||||||
stringifyPayUri,
|
stringifyPayUri,
|
||||||
stringifyRestoreUri,
|
stringifyRestoreUri,
|
||||||
|
stringifyWithdrawExchange,
|
||||||
} from "./taleruri.js";
|
} from "./taleruri.js";
|
||||||
|
|
||||||
test("taler pay url parsing: wrong scheme", (t) => {
|
test("taler pay url parsing: wrong scheme", (t) => {
|
||||||
@ -329,3 +331,42 @@ test("taler restore URI (stringify)", (t) => {
|
|||||||
"taler://restore/GJKG23V4ZBHEH45YRK7TWQE8ZTY7JWTY5094TQJSRZN5DSDBX8E0/http%3A%2F%2Fprov1.example.com%2F,https%3A%2F%2Fprov2.example.com%3A234%2F",
|
"taler://restore/GJKG23V4ZBHEH45YRK7TWQE8ZTY7JWTY5094TQJSRZN5DSDBX8E0/http%3A%2F%2Fprov1.example.com%2F,https%3A%2F%2Fprov2.example.com%3A234%2F",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("taler withdraw exchange URI (parse)", (t) => {
|
||||||
|
const r1 = parseWithdrawExchangeUri(
|
||||||
|
"taler://withdraw-exchange/exchange.demo.taler.net/someroot/GJKG23V4ZBHEH45YRK7TWQE8ZTY7JWTY5094TQJSRZN5DSDBX8E0?a=KUDOS%3A2",
|
||||||
|
);
|
||||||
|
if (!r1) {
|
||||||
|
t.fail();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
t.deepEqual(
|
||||||
|
r1.exchangePub,
|
||||||
|
"GJKG23V4ZBHEH45YRK7TWQE8ZTY7JWTY5094TQJSRZN5DSDBX8E0",
|
||||||
|
);
|
||||||
|
t.deepEqual(r1.exchangeBaseUrl, "https://exchange.demo.taler.net/someroot/");
|
||||||
|
t.deepEqual(r1.amount, "KUDOS:2");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("taler withdraw exchange URI (stringify)", (t) => {
|
||||||
|
const url = stringifyWithdrawExchange({
|
||||||
|
exchangeBaseUrl: "https://exchange.demo.taler.net",
|
||||||
|
exchangePub: "GJKG23V4ZBHEH45YRK7TWQE8ZTY7JWTY5094TQJSRZN5DSDBX8E0",
|
||||||
|
});
|
||||||
|
t.deepEqual(
|
||||||
|
url,
|
||||||
|
"taler://withdraw-exchange/exchange.demo.taler.net/GJKG23V4ZBHEH45YRK7TWQE8ZTY7JWTY5094TQJSRZN5DSDBX8E0",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("taler withdraw exchange URI with amount (stringify)", (t) => {
|
||||||
|
const url = stringifyWithdrawExchange({
|
||||||
|
exchangeBaseUrl: "https://exchange.demo.taler.net",
|
||||||
|
exchangePub: "GJKG23V4ZBHEH45YRK7TWQE8ZTY7JWTY5094TQJSRZN5DSDBX8E0",
|
||||||
|
amount: "KUDOS:19",
|
||||||
|
});
|
||||||
|
t.deepEqual(
|
||||||
|
url,
|
||||||
|
"taler://withdraw-exchange/exchange.demo.taler.net/GJKG23V4ZBHEH45YRK7TWQE8ZTY7JWTY5094TQJSRZN5DSDBX8E0?a=KUDOS%3A19",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { canonicalizeBaseUrl } from "./helpers.js";
|
import { canonicalizeBaseUrl } from "./helpers.js";
|
||||||
|
import { AmountString } from "./taler-types.js";
|
||||||
import { URLSearchParams, URL } from "./url.js";
|
import { URLSearchParams, URL } from "./url.js";
|
||||||
|
|
||||||
export type TalerUri =
|
export type TalerUri =
|
||||||
@ -28,6 +29,7 @@ export type TalerUri =
|
|||||||
| TipUriResult
|
| TipUriResult
|
||||||
| WithdrawUriResult
|
| WithdrawUriResult
|
||||||
| ExchangeUri
|
| ExchangeUri
|
||||||
|
| WithdrawExchangeUri
|
||||||
| AuditorUri;
|
| AuditorUri;
|
||||||
|
|
||||||
export interface PayUriResult {
|
export interface PayUriResult {
|
||||||
@ -99,6 +101,13 @@ export interface BackupRestoreUri {
|
|||||||
providers: Array<string>;
|
providers: Array<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface WithdrawExchangeUri {
|
||||||
|
type: TalerUriAction.WithdrawExchange;
|
||||||
|
exchangeBaseUrl: string;
|
||||||
|
exchangePub: string;
|
||||||
|
amount?: AmountString;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a taler[+http]://withdraw URI.
|
* Parse a taler[+http]://withdraw URI.
|
||||||
* Return undefined if not passed a valid URI.
|
* Return undefined if not passed a valid URI.
|
||||||
@ -166,6 +175,7 @@ export enum TalerUriAction {
|
|||||||
Auditor = "auditor",
|
Auditor = "auditor",
|
||||||
Restore = "restore",
|
Restore = "restore",
|
||||||
DevExperiment = "dev-experiment",
|
DevExperiment = "dev-experiment",
|
||||||
|
WithdrawExchange = "withdraw-exchange",
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TalerUriProtoInfo {
|
interface TalerUriProtoInfo {
|
||||||
@ -207,6 +217,7 @@ const parsers: { [A in TalerUriAction]: Parser } = {
|
|||||||
[TalerUriAction.DevExperiment]: parseDevExperimentUri,
|
[TalerUriAction.DevExperiment]: parseDevExperimentUri,
|
||||||
[TalerUriAction.Exchange]: parseExchangeUri,
|
[TalerUriAction.Exchange]: parseExchangeUri,
|
||||||
[TalerUriAction.Auditor]: parseAuditorUri,
|
[TalerUriAction.Auditor]: parseAuditorUri,
|
||||||
|
[TalerUriAction.WithdrawExchange]: parseWithdrawExchangeUri,
|
||||||
};
|
};
|
||||||
|
|
||||||
export function parseTalerUri(string: string): TalerUri | undefined {
|
export function parseTalerUri(string: string): TalerUri | undefined {
|
||||||
@ -253,6 +264,9 @@ export function stringifyTalerUri(uri: TalerUri): string {
|
|||||||
case TalerUriAction.Exchange: {
|
case TalerUriAction.Exchange: {
|
||||||
return stringifyExchangeUri(uri);
|
return stringifyExchangeUri(uri);
|
||||||
}
|
}
|
||||||
|
case TalerUriAction.WithdrawExchange: {
|
||||||
|
return stringifyWithdrawExchange(uri);
|
||||||
|
}
|
||||||
case TalerUriAction.Auditor: {
|
case TalerUriAction.Auditor: {
|
||||||
return stringifyAuditorUri(uri);
|
return stringifyAuditorUri(uri);
|
||||||
}
|
}
|
||||||
@ -432,6 +446,37 @@ export function parseExchangeUri(s: string): ExchangeUri | undefined {
|
|||||||
exchangePub,
|
exchangePub,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function parseWithdrawExchangeUri(
|
||||||
|
s: string,
|
||||||
|
): WithdrawExchangeUri | undefined {
|
||||||
|
const pi = parseProtoInfo(s, "withdraw-exchange");
|
||||||
|
if (!pi) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const c = pi?.rest.split("?");
|
||||||
|
const parts = c[0].split("/");
|
||||||
|
if (parts.length < 2) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const host = parts[0].toLowerCase();
|
||||||
|
const exchangePub = parts[parts.length - 1];
|
||||||
|
const pathSegments = parts.slice(1, parts.length - 1);
|
||||||
|
const hostAndSegments = [host, ...pathSegments].join("/");
|
||||||
|
const exchangeBaseUrl = canonicalizeBaseUrl(
|
||||||
|
`${pi.innerProto}://${hostAndSegments}/`,
|
||||||
|
);
|
||||||
|
const q = new URLSearchParams(c[1] ?? "");
|
||||||
|
const amount = q.get("a") ?? undefined;
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: TalerUriAction.WithdrawExchange,
|
||||||
|
exchangeBaseUrl,
|
||||||
|
exchangePub,
|
||||||
|
amount,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function parseAuditorUri(s: string): AuditorUri | undefined {
|
export function parseAuditorUri(s: string): AuditorUri | undefined {
|
||||||
const pi = parseProtoInfo(s, "auditor");
|
const pi = parseProtoInfo(s, "auditor");
|
||||||
if (!pi) {
|
if (!pi) {
|
||||||
@ -622,6 +667,17 @@ export function stringifyRestoreUri({
|
|||||||
return `taler://restore/${walletRootPriv}/${list}`;
|
return `taler://restore/${walletRootPriv}/${list}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function stringifyWithdrawExchange({
|
||||||
|
exchangeBaseUrl,
|
||||||
|
exchangePub,
|
||||||
|
amount,
|
||||||
|
}: Omit<WithdrawExchangeUri, "type">): string {
|
||||||
|
const { proto, path, query } = getUrlInfo(exchangeBaseUrl, {
|
||||||
|
a: amount,
|
||||||
|
});
|
||||||
|
return `${proto}://withdraw-exchange/${path}${exchangePub}${query}`;
|
||||||
|
}
|
||||||
|
|
||||||
export function stringifyDevExperimentUri({
|
export function stringifyDevExperimentUri({
|
||||||
devExperimentId,
|
devExperimentId,
|
||||||
}: Omit<DevExperimentUri, "type">): string {
|
}: Omit<DevExperimentUri, "type">): string {
|
||||||
|
Loading…
Reference in New Issue
Block a user