aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2023-05-05 14:56:28 +0200
committerFlorian Dold <florian@dold.me>2023-05-05 14:56:33 +0200
commit9a412260f3b0a53b1508e2db8724a0c58ce080cf (patch)
tree40c495c9ec97ab8e2631076eeec2c8165a561d88
parent990b056071fd0b3879d4366ff3dd625aa3265738 (diff)
adapt to merchant API breaking changes
-rw-r--r--packages/taler-harness/src/harness/harness.ts44
-rw-r--r--packages/taler-harness/src/index.ts2
-rw-r--r--packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts14
-rw-r--r--packages/taler-harness/src/integrationtests/test-tipping.ts18
-rw-r--r--packages/taler-util/src/merchant-api-types.ts32
-rw-r--r--packages/taler-util/src/taler-types.ts67
6 files changed, 130 insertions, 47 deletions
diff --git a/packages/taler-harness/src/harness/harness.ts b/packages/taler-harness/src/harness/harness.ts
index 5c2133064..c08f3fa1d 100644
--- a/packages/taler-harness/src/harness/harness.ts
+++ b/packages/taler-harness/src/harness/harness.ts
@@ -28,6 +28,7 @@ import {
AmountJson,
Amounts,
AmountString,
+ codecForMerchantReserveCreateConfirmation,
Configuration,
CoreApiResponse,
createEddsaKeyPair,
@@ -38,6 +39,7 @@ import {
hash,
j2s,
Logger,
+ MerchantReserveCreateConfirmation,
MerchantTemplateAddDetails,
parsePaytoUri,
stringToBytes,
@@ -81,7 +83,11 @@ import {
RemoteWallet,
WalletNotificationWaiter,
} from "@gnu-taler/taler-wallet-core/remote";
-import { createPlatformHttpLib } from "@gnu-taler/taler-util/http";
+import {
+ createPlatformHttpLib,
+ readSuccessResponseJsonOrErrorCode,
+ readSuccessResponseJsonOrThrow,
+} from "@gnu-taler/taler-util/http";
const logger = new Logger("harness.ts");
@@ -1568,13 +1574,18 @@ export class MerchantApiClient {
async createTippingReserve(
req: CreateMerchantTippingReserveRequest,
- ): Promise<CreateMerchantTippingReserveConfirmation> {
+ ): Promise<MerchantReserveCreateConfirmation> {
const url = new URL("private/reserves", this.baseUrl);
- const resp = await axios.post(url.href, req, {
+ const resp = await this.http.fetch(url.href, {
+ method: "POST",
+ body: req,
headers: this.makeAuthHeader(),
});
- // FIXME: validate
- return resp.data;
+ const respData = readSuccessResponseJsonOrThrow(
+ resp,
+ codecForMerchantReserveCreateConfirmation(),
+ );
+ return respData;
}
async getPrivateInstanceInfo(): Promise<any> {
@@ -1719,21 +1730,6 @@ export namespace MerchantPrivateApi {
};
}
- export async function createTippingReserve(
- merchantService: MerchantServiceInterface,
- instance: string,
- req: CreateMerchantTippingReserveRequest,
- ): Promise<CreateMerchantTippingReserveConfirmation> {
- const reqUrl = new URL(
- `private/reserves`,
- merchantService.makeInstanceBaseUrl(instance),
- );
- // FIXME: Don't use axios!
- const resp = await axios.post(reqUrl.href, req);
- // FIXME: validate
- return resp.data;
- }
-
export async function queryTippingReserves(
merchantService: MerchantServiceInterface,
instance: string,
@@ -1773,14 +1769,6 @@ export interface CreateMerchantTippingReserveRequest {
wire_method: string;
}
-export interface CreateMerchantTippingReserveConfirmation {
- // Public key identifying the reserve
- reserve_pub: string;
-
- // Wire account of the exchange where to transfer the funds
- payto_uri: string;
-}
-
export class MerchantService implements MerchantServiceInterface {
static fromExistingConfig(gc: GlobalTestState, name: string) {
const cfgFilename = gc.testDir + `/merchant-${name}.conf`;
diff --git a/packages/taler-harness/src/index.ts b/packages/taler-harness/src/index.ts
index bd58a7fd6..ec99232f5 100644
--- a/packages/taler-harness/src/index.ts
+++ b/packages/taler-harness/src/index.ts
@@ -213,7 +213,7 @@ deploymentCli
allowHttp: true,
});
- const paytoUri = addPaytoQueryParams(tipReserveResp.payto_uri, {
+ const paytoUri = addPaytoQueryParams(tipReserveResp.accounts[0].payto_uri, {
message: `tip-reserve ${tipReserveResp.reserve_pub}`,
});
diff --git a/packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts b/packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts
index 38cbd6925..c4db7022d 100644
--- a/packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts
+++ b/packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts
@@ -26,6 +26,7 @@ import { defaultCoinConfig } from "../harness/denomStructures.js";
import {
getWireMethodForTest,
GlobalTestState,
+ MerchantApiClient,
MerchantPrivateApi,
WalletCli,
} from "../harness/harness.js";
@@ -55,6 +56,13 @@ export async function runAgeRestrictionsMerchantTest(t: GlobalTestState) {
},
);
+ const merchantClient = new MerchantApiClient(
+ merchant.makeInstanceBaseUrl("default"),
+ {
+ method: "external",
+ },
+ );
+
const walletTwo = new WalletCli(t, "walletTwo");
const walletThree = new WalletCli(t, "walletThree");
@@ -147,9 +155,7 @@ export async function runAgeRestrictionsMerchantTest(t: GlobalTestState) {
// Pay with coin from tipping
{
const mbu = await BankApi.createRandomBankUser(bank);
- const tipReserveResp = await MerchantPrivateApi.createTippingReserve(
- merchant,
- "default",
+ const tipReserveResp = await merchantClient.createTippingReserve(
{
exchange_url: exchange.baseUrl,
initial_balance: "TESTKUDOS:10",
@@ -158,7 +164,7 @@ export async function runAgeRestrictionsMerchantTest(t: GlobalTestState) {
);
t.assertDeepEqual(
- tipReserveResp.payto_uri,
+ tipReserveResp.accounts[0].payto_uri,
exchangeBankAccount.accountPaytoUri,
);
diff --git a/packages/taler-harness/src/integrationtests/test-tipping.ts b/packages/taler-harness/src/integrationtests/test-tipping.ts
index b124fbf0d..bbf729420 100644
--- a/packages/taler-harness/src/integrationtests/test-tipping.ts
+++ b/packages/taler-harness/src/integrationtests/test-tipping.ts
@@ -24,6 +24,7 @@ import {
} from "@gnu-taler/taler-wallet-core";
import {
GlobalTestState,
+ MerchantApiClient,
MerchantPrivateApi,
getWireMethodForTest,
} from "../harness/harness.js";
@@ -40,20 +41,23 @@ export async function runTippingTest(t: GlobalTestState) {
const mbu = await BankApi.createRandomBankUser(bank);
- const tipReserveResp = await MerchantPrivateApi.createTippingReserve(
- merchant,
- "default",
+ const merchantClient = new MerchantApiClient(
+ merchant.makeInstanceBaseUrl("default"),
{
- exchange_url: exchange.baseUrl,
- initial_balance: "TESTKUDOS:10",
- wire_method: getWireMethodForTest(),
+ method: "external",
},
);
+ const tipReserveResp = await merchantClient.createTippingReserve({
+ exchange_url: exchange.baseUrl,
+ initial_balance: "TESTKUDOS:10",
+ wire_method: getWireMethodForTest(),
+ });
+
console.log("tipReserveResp:", tipReserveResp);
t.assertDeepEqual(
- tipReserveResp.payto_uri,
+ tipReserveResp.accounts[0].payto_uri,
exchangeBankAccount.accountPaytoUri,
);
diff --git a/packages/taler-util/src/merchant-api-types.ts b/packages/taler-util/src/merchant-api-types.ts
index 61002191a..d7a5cf576 100644
--- a/packages/taler-util/src/merchant-api-types.ts
+++ b/packages/taler-util/src/merchant-api-types.ts
@@ -44,6 +44,9 @@ import {
TalerProtocolDuration,
codecForTimestamp,
TalerProtocolTimestamp,
+ WireAccount,
+ codecForWireAccount,
+ codecForList,
} from "@gnu-taler/taler-util";
export interface MerchantPostOrderRequest {
@@ -75,11 +78,12 @@ export interface MerchantPostOrderResponse {
token?: ClaimToken;
}
-export const codecForMerchantPostOrderResponse = (): Codec<MerchantPostOrderResponse> =>
- buildCodecForObject<MerchantPostOrderResponse>()
- .property("order_id", codecForString())
- .property("token", codecOptional(codecForString()))
- .build("PostOrderResponse");
+export const codecForMerchantPostOrderResponse =
+ (): Codec<MerchantPostOrderResponse> =>
+ buildCodecForObject<MerchantPostOrderResponse>()
+ .property("order_id", codecForString())
+ .property("token", codecOptional(codecForString()))
+ .build("PostOrderResponse");
export const codecForMerchantRefundDetails = (): Codec<RefundDetails> =>
buildCodecForObject<RefundDetails>()
@@ -351,7 +355,6 @@ export interface MerchantTemplateContractDetails {
}
export interface MerchantTemplateAddDetails {
-
// Template ID to use.
template_id: string;
@@ -365,4 +368,19 @@ export interface MerchantTemplateAddDetails {
// Additional information in a separate template.
template_contract: MerchantTemplateContractDetails;
-} \ No newline at end of file
+}
+
+export interface MerchantReserveCreateConfirmation {
+ // Public key identifying the reserve.
+ reserve_pub: EddsaPublicKeyString;
+
+ // Wire accounts of the exchange where to transfer the funds.
+ accounts: WireAccount[];
+}
+
+export const codecForMerchantReserveCreateConfirmation =
+ (): Codec<MerchantReserveCreateConfirmation> =>
+ buildCodecForObject<MerchantReserveCreateConfirmation>()
+ .property("accounts", codecForList(codecForWireAccount()))
+ .property("reserve_pub", codecForString())
+ .build("MerchantReserveCreateConfirmation");
diff --git a/packages/taler-util/src/taler-types.ts b/packages/taler-util/src/taler-types.ts
index 56184a598..570e64d7c 100644
--- a/packages/taler-util/src/taler-types.ts
+++ b/packages/taler-util/src/taler-types.ts
@@ -2165,3 +2165,70 @@ export const codecForExchangeRefundSuccessResponse =
.property("exchange_pub", codecForString())
.property("exchange_sig", codecForString())
.build("ExchangeRefundSuccessResponse");
+
+export type AccountRestriction =
+ | RegexAccountRestriction
+ | DenyAllAccountRestriction;
+
+export interface DenyAllAccountRestriction {
+ type: "deny";
+}
+
+// Accounts interacting with this type of account
+// restriction must have a payto://-URI matching
+// the given regex.
+export interface RegexAccountRestriction {
+ type: "regex";
+
+ // Regular expression that the payto://-URI of the
+ // partner account must follow. The regular expression
+ // should follow posix-egrep, but without support for character
+ // classes, GNU extensions, back-references or intervals. See
+ // https://www.gnu.org/software/findutils/manual/html_node/find_html/posix_002degrep-regular-expression-syntax.html
+ // for a description of the posix-egrep syntax. Applications
+ // may support regexes with additional features, but exchanges
+ // must not use such regexes.
+ payto_regex: string;
+
+ // Hint for a human to understand the restriction
+ // (that is hopefully easier to comprehend than the regex itself).
+ human_hint: string;
+
+ // Map from IETF BCP 47 language tags to localized
+ // human hints.
+ human_hint_i18n?: InternationalizedString;
+}
+
+export interface WireAccount {
+ // payto:// URI identifying the account and wire method
+ payto_uri: string;
+
+ // URI to convert amounts from or to the currency used by
+ // this wire account of the exchange. Missing if no
+ // conversion is applicable.
+ conversion_url?: string;
+
+ // Restrictions that apply to bank accounts that would send
+ // funds to the exchange (crediting this exchange bank account).
+ // Optional, empty array for unrestricted.
+ credit_restrictions: AccountRestriction[];
+
+ // Restrictions that apply to bank accounts that would receive
+ // funds from the exchange (debiting this exchange bank account).
+ // Optional, empty array for unrestricted.
+ debit_restrictions: AccountRestriction[];
+
+ // Signature using the exchange's offline key over
+ // a TALER_MasterWireDetailsPS
+ // with purpose TALER_SIGNATURE_MASTER_WIRE_DETAILS.
+ master_sig: EddsaSignatureString;
+}
+
+export const codecForWireAccount = (): Codec<WireAccount> =>
+ buildCodecForObject<WireAccount>()
+ .property("conversion_url", codecOptional(codecForString()))
+ .property("credit_restrictions", codecForList(codecForAny()))
+ .property("debit_restrictions", codecForList(codecForAny()))
+ .property("master_sig", codecForString())
+ .property("payto_uri", codecForString())
+ .build("WireAccount");