diff options
author | Florian Dold <florian@dold.me> | 2023-05-05 14:56:28 +0200 |
---|---|---|
committer | Florian Dold <florian@dold.me> | 2023-05-05 14:56:33 +0200 |
commit | 9a412260f3b0a53b1508e2db8724a0c58ce080cf (patch) | |
tree | 40c495c9ec97ab8e2631076eeec2c8165a561d88 | |
parent | 990b056071fd0b3879d4366ff3dd625aa3265738 (diff) |
adapt to merchant API breaking changes
-rw-r--r-- | packages/taler-harness/src/harness/harness.ts | 44 | ||||
-rw-r--r-- | packages/taler-harness/src/index.ts | 2 | ||||
-rw-r--r-- | packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts | 14 | ||||
-rw-r--r-- | packages/taler-harness/src/integrationtests/test-tipping.ts | 18 | ||||
-rw-r--r-- | packages/taler-util/src/merchant-api-types.ts | 32 | ||||
-rw-r--r-- | packages/taler-util/src/taler-types.ts | 67 |
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"); |