commit 5aab7b614273c085d8554b80908ba895a318ce01
parent 587d1ed27e43e95e0ae9ff0b91b6d21824035b04
Author: Antoine A <>
Date: Fri, 29 May 2026 13:59:55 +0200
common: update prepared transfer API
Diffstat:
14 files changed, 170 insertions(+), 123 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -382,14 +382,14 @@ dependencies = [
[[package]]
name = "cc"
-version = "1.2.62"
+version = "1.2.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98"
+checksum = "556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f"
dependencies = [
"find-msvc-tools",
"jobserver",
"libc",
- "shlex 1.3.0",
+ "shlex",
]
[[package]]
@@ -1589,9 +1589,9 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "jiff"
-version = "0.2.27"
+version = "0.2.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "392c70591e8749fe235ddaf513e6f58b26bce3dcc16524cecc8936f75afa161e"
+checksum = "4603d3033e49e2b0e31229fcab20a5d40089c607d975cd9c80551dc69eed9102"
dependencies = [
"jiff-static",
"log",
@@ -1603,9 +1603,9 @@ dependencies = [
[[package]]
name = "jiff-static"
-version = "0.2.27"
+version = "0.2.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "47b605b0c050d845fc355bb11eb3f9a8deddc218ea60c76e61aa1f2adfb2c96a"
+checksum = "782d32378dddf207193ac91cefb848ad41abb58195c95168e1291227a0832b47"
dependencies = [
"proc-macro2",
"quote",
@@ -1801,7 +1801,7 @@ dependencies = [
"regex",
"serde",
"serde_json",
- "shlex 2.0.1",
+ "shlex",
"sqlx",
"taler-api",
"taler-build",
@@ -1996,9 +1996,9 @@ dependencies = [
[[package]]
name = "mio"
-version = "1.2.0"
+version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1"
+checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda"
dependencies = [
"libc",
"log",
@@ -2507,9 +2507,9 @@ dependencies = [
[[package]]
name = "reedline"
-version = "0.47.0"
+version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2066729dce9fecd28d1c6850a159ee68719130f149b22467c362353e16994e90"
+checksum = "201e8e0160cbe7bb5eb2caccf281e178e77fac95115ab31a2c29edc5593603c8"
dependencies = [
"chrono",
"crossterm",
@@ -2957,12 +2957,6 @@ checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77"
[[package]]
name = "shlex"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
-
-[[package]]
-name = "shlex"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
@@ -3047,9 +3041,9 @@ dependencies = [
[[package]]
name = "socket2"
-version = "0.6.3"
+version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e"
+checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51"
dependencies = [
"libc",
"windows-sys 0.61.2",
@@ -3388,7 +3382,7 @@ dependencies = [
[[package]]
name = "taler-api"
version = "1.5.0"
-source = "git+git://git.taler.net/taler-rust.git/#664cd180f65c314bae731743dbd481e4314a8ed7"
+source = "git+git://git.taler.net/taler-rust.git/#9df4ad89b8a4c8acbd06b0ebce398449ba4364df"
dependencies = [
"aws-lc-rs",
"axum",
@@ -3415,12 +3409,12 @@ dependencies = [
[[package]]
name = "taler-build"
version = "1.5.0"
-source = "git+git://git.taler.net/taler-rust.git/#664cd180f65c314bae731743dbd481e4314a8ed7"
+source = "git+git://git.taler.net/taler-rust.git/#9df4ad89b8a4c8acbd06b0ebce398449ba4364df"
[[package]]
name = "taler-common"
version = "1.5.0"
-source = "git+git://git.taler.net/taler-rust.git/#664cd180f65c314bae731743dbd481e4314a8ed7"
+source = "git+git://git.taler.net/taler-rust.git/#9df4ad89b8a4c8acbd06b0ebce398449ba4364df"
dependencies = [
"anyhow",
"aws-lc-rs",
@@ -3449,7 +3443,7 @@ dependencies = [
[[package]]
name = "taler-macros"
version = "1.5.0"
-source = "git+git://git.taler.net/taler-rust.git/#664cd180f65c314bae731743dbd481e4314a8ed7"
+source = "git+git://git.taler.net/taler-rust.git/#9df4ad89b8a4c8acbd06b0ebce398449ba4364df"
dependencies = [
"proc-macro2",
"quote",
@@ -3459,7 +3453,7 @@ dependencies = [
[[package]]
name = "taler-test-utils"
version = "1.5.0"
-source = "git+git://git.taler.net/taler-rust.git/#664cd180f65c314bae731743dbd481e4314a8ed7"
+source = "git+git://git.taler.net/taler-rust.git/#9df4ad89b8a4c8acbd06b0ebce398449ba4364df"
dependencies = [
"aws-lc-rs",
"axum",
@@ -3503,7 +3497,7 @@ dependencies = [
"libeufin-nexus",
"owo-colors",
"reedline",
- "shlex 2.0.1",
+ "shlex",
"taler-common",
"tokio",
"tracing",
@@ -3935,9 +3929,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "uuid"
-version = "1.23.1"
+version = "1.23.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76"
+checksum = "d258b83ceec21034727ecee8c382cfa6c3e133699b0742c64571814fb420c9f7"
dependencies = [
"getrandom 0.4.2",
"js-sys",
diff --git a/Makefile b/Makefile
@@ -57,3 +57,8 @@ deb:
.PHONY: ci
ci:
contrib/ci/run-all-jobs.sh
+
+
+.PHONY: fmt
+fmt:
+ rustfmt-unstable --apply
+\ No newline at end of file
diff --git a/libeufin-bank/src/api/cashout.rs b/libeufin-bank/src/api/cashout.rs
@@ -414,16 +414,14 @@ pub mod test {
let router = ctx.admin_router().await;
let c = &ctx;
routine_pagination::<Cashouts>(
- &router,
- "/accounts/customer/cashouts",
+ &router.suffix("/accounts/customer/cashouts"),
tasks!({
c.cashout("0.1").await;
}),
)
.await;
routine_pagination::<Cashouts>(
- &router,
- "/cashouts",
+ &router.suffix("/cashouts"),
tasks!({
c.cashout("0.1").await;
}),
diff --git a/libeufin-bank/src/api/prepared.rs b/libeufin-bank/src/api/prepared.rs
@@ -25,13 +25,12 @@ use axum::{
response::NoContent,
routing::{get, post},
};
-use compact_str::CompactString;
use jiff::Timestamp;
use taler_api::{
api::{Validation, prepared::simple_subject},
constants::PREPARED_TRANSFER_API_VERSION,
error::failure_code,
- extract::{Path, Req},
+ extract::Req,
};
use taler_common::{
api::prepared::{
@@ -45,12 +44,13 @@ use taler_common::{
use crate::{
api::{BankState, IMPLEMENTATION},
db::prepared::{RegistrationResult, register, unregister},
+ payto::BankPayto,
};
pub fn prepared_api() -> Router<Arc<BankState>> {
Router::new()
.route(
- "/accounts/{username}/taler-prepared-transfer/config",
+ "/taler-prepared-transfer/config",
get(async |State(state): State<Arc<BankState>>| {
Json(PreparedTransferConfig {
name: (),
@@ -62,15 +62,14 @@ pub fn prepared_api() -> Router<Arc<BankState>> {
}),
)
.route(
- "/accounts/{username}/taler-prepared-transfer/registration",
+ "/taler-prepared-transfer/registration",
post(
- async |Path(username): Path<CompactString>,
- State(state): State<Arc<BankState>>,
- Req(req): Req<RegistrationRequest>| {
+ async |State(state): State<Arc<BankState>>, Req(req): Req<RegistrationRequest>| {
req.check(&state.cfg.regional_currency)?;
+ let creditor = BankPayto::try_from(&req.credit_account)?;
match register(
&state.db,
- &username,
+ &creditor,
req.r#type,
&req.account_pub,
&req.authorization_pub,
@@ -95,8 +94,8 @@ pub fn prepared_api() -> Router<Arc<BankState>> {
expiration: TalerTimestamp::Never,
}))
}
- RegistrationResult::UnknownAccount => {
- Err(failure_code(ErrorCode::BANK_UNKNOWN_ACCOUNT))
+ RegistrationResult::UnknownCreditor => {
+ Err(failure_code(ErrorCode::BANK_UNKNOWN_CREDITOR))
}
RegistrationResult::NotExchange => {
Err(failure_code(ErrorCode::BANK_ACCOUNT_IS_NOT_EXCHANGE))
@@ -109,7 +108,7 @@ pub fn prepared_api() -> Router<Arc<BankState>> {
),
)
.route(
- "/accounts/{username}/taler-prepared-transfer/unregistration",
+ "/taler-prepared-transfer/unregistration",
post(
async |State(state): State<Arc<BankState>>, Req(req): Req<Unregistration>| {
req.check(&state.cfg.regional_currency)?;
@@ -144,6 +143,7 @@ mod test {
let key_pair1 = Ed25519KeyPair::generate().unwrap();
let auth_pub1 = EddsaPublicKey::try_from(key_pair1.public_key().as_ref()).unwrap();
let req = json!({
+ "credit_account": ctx.exchange_payto,
"credit_amount": "KUDOS:120",
"type": "reserve",
"alg": "EdDSA",
@@ -152,19 +152,23 @@ mod test {
"authorization_sig": eddsa_sign(&key_pair1, auth_pub1.as_ref()),
"recurrent": false
});
- ctx.post("/accounts/merchant/taler-prepared-transfer/registration")
- .json(&req)
+ ctx.post("/taler-prepared-transfer/registration")
+ .json(json!(req + { "credit_account": ctx.customer_payto }))
.await
.assert_error(ErrorCode::BANK_ACCOUNT_IS_NOT_EXCHANGE);
- ctx.post("/accounts/unknown/taler-prepared-transfer/registration")
- .json(&req)
+ ctx.post("/taler-prepared-transfer/registration")
+ .json(json!(req + { "credit_account": ctx.unknown_payto }))
.await
- .assert_error(ErrorCode::BANK_UNKNOWN_ACCOUNT);
+ .assert_error(ErrorCode::BANK_UNKNOWN_CREDITOR);
ctx.set_max_debt("customer", "1000").await;
+ let admin = ctx.admin_router().await;
registration_routine(
- &ctx.admin_router().await.prefix("/accounts/exchange"),
+ &admin.prefix("/accounts/exchange/taler-wire-gateway"),
+ &admin.prefix("/taler-prepared-transfer"),
&ctx.customer_payto.as_uri(),
+ &ctx.exchange_payto.as_uri(),
+ &ctx.unknown_payto.as_uri(),
async || {
sqlx::query(
"
@@ -208,7 +212,7 @@ mod test {
/*
*
* // Non recurrent no URI
- client.post("/accounts/exchange/taler-prepared-transfer/registration") {
+ client.post("/taler-prepared-transfer/registration") {
json(valid_req) {
"type" to "reserve"
}
@@ -221,7 +225,7 @@ mod test {
assertBalance("exchange", "+KUDOS:1")
}
* // Withdrawal is aborted on completion
- client.post("/accounts/exchange/taler-prepared-transfer/registration") {
+ client.post("/taler-prepared-transfer/registration") {
json(valid_req) {
"type" to "kyc"
}
diff --git a/libeufin-bank/src/api/revenue.rs b/libeufin-bank/src/api/revenue.rs
@@ -83,7 +83,6 @@ pub fn revenue_api() -> Router<Arc<BankState>> {
#[cfg(test)]
mod test {
- use taler_common::types::payto::PaytoImpl as _;
use taler_test_utils::{routine::revenue_routine, server::TestServer, tasks};
use crate::api::test::bank_setup;
@@ -92,9 +91,11 @@ mod test {
async fn revenue() {
let ctx = bank_setup().await;
ctx.set_max_debt("customer", "1000").await;
+ let admin = ctx.admin_router().await;
revenue_routine(
- &ctx.admin_router().await.prefix("/accounts/exchange"),
- &ctx.customer_payto.as_full_uri("Customer"),
+ &admin.prefix("/accounts/exchange/taler-wire-gateway"),
+ &admin.prefix("/accounts/exchange/taler-revenue"),
+ &ctx.customer_payto.as_uri(),
true,
tasks!(),
tasks!(),
diff --git a/libeufin-bank/src/api/tx.rs b/libeufin-bank/src/api/tx.rs
@@ -210,6 +210,7 @@ pub mod test {
use taler_test_utils::{
json,
routine::{Page, routine_history},
+ server::TestServer,
tasks,
};
@@ -529,8 +530,9 @@ pub mod test {
ctx.fill_cashout_info("customer").await;
routine_history::<BankAccountTransactionsResponse>(
- &ctx.admin_router().await,
- "/accounts/customer/transactions",
+ &ctx.admin_router()
+ .await
+ .suffix("/accounts/customer/transactions"),
tasks!(
// Incoming
{ ctx.tx("merchant", "0.1", "customer").await },
diff --git a/libeufin-bank/src/api/wire.rs b/libeufin-bank/src/api/wire.rs
@@ -403,7 +403,7 @@ pub mod test {
},
db::IncomingType,
error_code::ErrorCode,
- types::{amount::amount, payto::PaytoImpl},
+ types::amount::amount,
};
use taler_test_utils::{
json,
@@ -454,7 +454,9 @@ pub mod test {
ctx.set_max_debt("exchange", "1000").await;
transfer_routine(
- &ctx.admin_router().await.prefix("/accounts/exchange"),
+ &ctx.admin_router()
+ .await
+ .prefix("/accounts/exchange/taler-wire-gateway"),
TransferState::success,
&ctx.customer_payto.as_uri(),
)
@@ -558,7 +560,9 @@ pub mod test {
.await;
ctx.set_max_debt("exchange", "1000").await;
out_history_routine(
- &ctx.admin_router().await.prefix("/accounts/exchange"),
+ &ctx.admin_router()
+ .await
+ .prefix("/accounts/exchange/taler-wire-gateway"),
tasks!(
// Transactions using clean add incoming logic
{ ctx.transfer("10", &ctx.customer_payto, None).await },
@@ -605,9 +609,12 @@ pub mod test {
.await;
ctx.set_max_debt("customer", "1000").await;
ctx.set_max_debt("merchant", "1000").await;
+ let admin = ctx.admin_router().await;
in_history_routine(
- &ctx.admin_router().await.prefix("/accounts/exchange"),
+ &admin.prefix("/accounts/exchange/taler-wire-gateway"),
+ &admin.prefix("/taler-prepared-transfer"),
&ctx.customer_payto.as_uri(),
+ &ctx.exchange_payto.as_uri(),
false,
tasks!(
// Reserve transactions using raw bank transaction logic
@@ -689,9 +696,12 @@ pub mod test {
}
}
ctx.set_max_debt("customer", "1000").await;
+ let admin = ctx.admin_router().await;
admin_add_incoming_routine(
- &ctx.admin_router().await.prefix("/accounts/exchange"),
- &ctx.customer_payto.as_full_uri("Customer"),
+ &admin.prefix("/accounts/exchange/taler-wire-gateway"),
+ &admin.prefix("/taler-prepared-transfer"),
+ &ctx.customer_payto.as_uri(),
+ &ctx.exchange_payto.as_uri(),
true,
)
.await;
diff --git a/libeufin-bank/src/db/prepared.rs b/libeufin-bank/src/db/prepared.rs
@@ -32,10 +32,12 @@ use taler_common::{
};
use uuid::Uuid;
+use crate::payto::BankPayto;
+
/** Result of prepared transfer registration */
pub enum RegistrationResult {
Success(Option<Uuid>),
- UnknownAccount,
+ UnknownCreditor,
NotExchange,
ReservePubReuse,
}
@@ -43,7 +45,7 @@ pub enum RegistrationResult {
/** Register a prepared transfer */
pub async fn register(
db: &PgPool,
- username: &str,
+ creditor: &BankPayto,
ty: TransferType,
account_pub: &EddsaPublicKey,
auth_pub: &EddsaPublicKey,
@@ -56,11 +58,11 @@ pub async fn register(
serialized!(
sqlx::query(
"
- SELECT out_unknown_account, out_not_exchange, out_reserve_pub_reuse, out_withdrawal_uuid
+ SELECT out_unknown_creditor, out_not_exchange, out_reserve_pub_reuse, out_withdrawal_uuid
FROM register_prepared_transfers($1,$2::taler_incoming_type,$3,$4,$5,$6,$7,$8,$9)
"
)
- .bind(username)
+ .bind(creditor.canonical())
.bind(ty.as_ref())
.bind(account_pub)
.bind(auth_pub)
@@ -70,8 +72,8 @@ pub async fn register(
.bind_timestamp(timestamp)
.bind(format!("Taler prepared MAP:{auth_pub}"))
.try_map(|r: PgRow| {
- Ok(if r.try_get_flag("out_unknown_account")? {
- RegistrationResult::UnknownAccount
+ Ok(if r.try_get_flag("out_unknown_creditor")? {
+ RegistrationResult::UnknownCreditor
} else if r.try_get_flag("out_not_exchange")? {
RegistrationResult::NotExchange
} else if r.try_get_flag("out_reserve_pub_reuse")? {
diff --git a/libeufin-nexus/src/api.rs b/libeufin-nexus/src/api.rs
@@ -50,7 +50,7 @@ use taler_common::{
error_code::ErrorCode,
types::{
amount::{Amount, Currency},
- payto::{FullIbanPayto, PaytoURI},
+ payto::{FullIbanPayto, IbanPayto, PaytoURI},
timestamp::TalerTimestamp,
},
};
@@ -69,14 +69,14 @@ use crate::db::{
pub struct NexusApi {
pub pool: sqlx::PgPool,
pub currency: Currency,
- pub payto: PaytoURI,
+ pub payto: FullIbanPayto,
pub in_channel: Sender<i64>,
pub taler_in_channel: Sender<i64>,
pub taler_out_channel: Sender<i64>,
}
impl NexusApi {
- pub async fn start(pool: sqlx::PgPool, payto: PaytoURI, currency: Currency) -> Self {
+ pub async fn start(pool: sqlx::PgPool, payto: FullIbanPayto, currency: Currency) -> Self {
let in_channel = Sender::new(0);
let taler_in_channel = Sender::new(0);
let taler_out_channel = Sender::new(0);
@@ -176,7 +176,7 @@ impl WireGateway for NexusApi {
) -> ApiResult<TransferList> {
Ok(TransferList {
transfers: transfer_page(&self.pool, &self.currency, &page, &status).await?,
- debit_account: self.payto.clone(),
+ debit_account: self.payto.as_uri(),
})
}
@@ -190,7 +190,7 @@ impl WireGateway for NexusApi {
self.taler_out_channel.subscribe()
})
.await?,
- debit_account: self.payto.clone(),
+ debit_account: self.payto.as_uri(),
})
}
@@ -200,7 +200,7 @@ impl WireGateway for NexusApi {
self.taler_in_channel.subscribe()
})
.await?,
- credit_account: self.payto.clone(),
+ credit_account: self.payto.as_uri(),
})
}
@@ -249,7 +249,7 @@ impl Revenue for NexusApi {
self.in_channel.subscribe()
})
.await?,
- credit_account: self.payto.clone(),
+ credit_account: self.payto.as_uri(),
})
}
}
@@ -260,6 +260,10 @@ impl PreparedTransfer for NexusApi {
}
async fn registration(&self, req: RegistrationRequest) -> ApiResult<RegistrationResponse> {
+ let creditor = IbanPayto::try_from(&req.credit_account)?;
+ if *creditor != *self.payto {
+ return Err(failure_code(ErrorCode::BANK_UNKNOWN_CREDITOR));
+ }
let reference_number = subject_fmt_qr_bill(req.authorization_pub.as_ref());
match transfer_register(
&self.pool,
@@ -306,13 +310,13 @@ pub mod test {
use taler_common::api::{
prepared::PreparedTransferConfig,
revenue::RevenueConfig,
- wire::{OutgoingHistory, TransferState, WireConfig},
+ wire::{TransferState, WireConfig},
};
use taler_test_utils::{
Router,
db::db_test_setup,
routine::{
- admin_add_incoming_routine, registration_routine, revenue_routine, routine_pagination,
+ admin_add_incoming_routine, out_history_routine, registration_routine, revenue_routine,
transfer_routine,
},
server::TestServer as _,
@@ -323,12 +327,12 @@ pub mod test {
CONFIG_SOURCE,
api::NexusApi,
db::{payment::register_out_tx, test::check_in},
- test::{ACCOUNT, CURR, gen_out_pay},
+ test::{CLIENT, CURR, EXCHANGE, UNKNOWN, gen_out_pay},
};
pub async fn api_setup() -> (Router, PgPool) {
let (_, pool) = db_test_setup(CONFIG_SOURCE).await;
- let api = Arc::new(NexusApi::start(pool.clone(), ACCOUNT.clone(), CURR).await);
+ let api = Arc::new(NexusApi::start(pool.clone(), EXCHANGE.clone(), CURR).await);
let server = Router::new()
.wire_gateway(api.clone(), AuthMethod::None)
.prepared_transfer(api.clone())
@@ -358,7 +362,12 @@ pub mod test {
#[tokio::test]
async fn transfer() {
let (server, _) = api_setup().await;
- transfer_routine(&server, TransferState::pending, &ACCOUNT).await;
+ transfer_routine(
+ &server.prefix("/taler-wire-gateway"),
+ TransferState::pending,
+ &EXCHANGE.as_uri(),
+ )
+ .await;
// TODO
/*db.initiated.batchSubmissionSuccess(1, Instant.now(), "ORDER1")
db.initiated.batchSubmissionFailure(2, Instant.now(), "Failure")
@@ -374,9 +383,8 @@ pub mod test {
#[tokio::test]
async fn outgoing_history() {
let (server, pool) = api_setup().await;
- routine_pagination::<OutgoingHistory>(
- &server,
- "/taler-wire-gateway/history/outgoing",
+ out_history_routine(
+ &server.prefix("/taler-wire-gateway"),
tasks!({
register_out_tx(
&pool,
@@ -386,6 +394,7 @@ pub mod test {
.await
.unwrap();
}),
+ tasks!(),
)
.await;
}
@@ -393,18 +402,41 @@ pub mod test {
#[tokio::test]
async fn admin_add_incoming() {
let (server, _) = api_setup().await;
- admin_add_incoming_routine(&server, &ACCOUNT, true).await;
+ admin_add_incoming_routine(
+ &server.prefix("/taler-wire-gateway"),
+ &server.prefix("/taler-prepared-transfer"),
+ &CLIENT.as_uri(),
+ &EXCHANGE.as_uri(),
+ true,
+ )
+ .await;
}
#[tokio::test]
async fn revenue() {
let (server, _) = api_setup().await;
- revenue_routine(&server, &ACCOUNT, true, tasks!(), tasks!()).await;
+ revenue_routine(
+ &server.prefix("/taler-wire-gateway"),
+ &server.prefix("/taler-revenue"),
+ &CLIENT.as_uri(),
+ true,
+ tasks!(),
+ tasks!(),
+ )
+ .await;
}
#[tokio::test]
async fn registration() {
let (server, pool) = api_setup().await;
- registration_routine(&server, &ACCOUNT, || check_in(&pool)).await;
+ registration_routine(
+ &server.prefix("/taler-wire-gateway"),
+ &server.prefix("/taler-prepared-transfer"),
+ &CLIENT.as_uri(),
+ &EXCHANGE.as_uri(),
+ &UNKNOWN,
+ || check_in(&pool),
+ )
+ .await;
}
}
diff --git a/libeufin-nexus/src/bench.rs b/libeufin-nexus/src/bench.rs
@@ -37,7 +37,7 @@ mod test {
use crate::{
api::test::api_setup,
test::{
- ACCOUNT, incomplete_out, malformed_completeted_in, malformed_in,
+ CLIENT, EXCHANGE, incomplete_out, malformed_completeted_in, malformed_in,
malformed_incomplete_in, malformed_out, prepared_completeted_in, prepared_in,
prepared_incomplete_in, talerable_completeted_in, talerable_in,
talerable_incomplete_in, talerable_out,
@@ -58,37 +58,37 @@ mod test {
})
.collect();
let mut b = Bench::new(&db, iter, amount);
+ let uri = CLIENT.as_uri();
b.table("incoming_transactions(amount, subject, execution_time, debit_payto, uetr, tx_id, acct_svcr_ref)", |f, i| {
let subject = if i % 4 == 0 { CompactString::const_new("\\N")} else {format_compact!("subject {i}")};
- let debtor = ACCOUNT.as_ref().as_str() ;
if i % 3 == 0 {
- writeln!(f, "(20,0)\t{subject}\t0\t{debtor}\t{}\t\\N\t\\N", uuid::Uuid::new_v4())?;
- writeln!(f, "(21,0)\t{subject}\t0\t{debtor}\t\\N\tTX_ID{}\t\\N", i*2)?;
- writeln!(f, "(22,0)\t{subject}\t0\t{debtor}\t\\N\t\\N\tREF{}", i*2)
+ writeln!(f, "(20,0)\t{subject}\t0\t{uri}\t{}\t\\N\t\\N", uuid::Uuid::new_v4())?;
+ writeln!(f, "(21,0)\t{subject}\t0\t{uri}\t\\N\tTX_ID{}\t\\N", i*2)?;
+ writeln!(f, "(22,0)\t{subject}\t0\t{uri}\t\\N\t\\N\tREF{}", i*2)
} else if i%3 == 1 {
- writeln!(f, "(30,0)\t{subject}\t0\t{debtor}\t{}\tTX_ID{}\t\\N", uuid::Uuid::new_v4(), i*2)?;
- writeln!(f, "(31,0)\t{subject}\t0\t{debtor}\t\\N\tTX_ID{}\tREF{}", i*2+1, i*2)?;
- writeln!(f, "(32,0)\t{subject}\t0\t{debtor}\t{}\t\\N\tREF{}", uuid::Uuid::new_v4(), i*2+1)
+ writeln!(f, "(30,0)\t{subject}\t0\t{uri}\t{}\tTX_ID{}\t\\N", uuid::Uuid::new_v4(), i*2)?;
+ writeln!(f, "(31,0)\t{subject}\t0\t{uri}\t\\N\tTX_ID{}\tREF{}", i*2+1, i*2)?;
+ writeln!(f, "(32,0)\t{subject}\t0\t{uri}\t{}\t\\N\tREF{}", uuid::Uuid::new_v4(), i*2+1)
} else {
- writeln!(f, "(40,0)\t{subject}\t0\t{debtor}\t{}\tTX_ID{}\tREF{}", uuid::Uuid::new_v4(), i*2, i*2)?;
- writeln!(f, "(40,0)\t{subject}\t0\t{debtor}\t{}\tTX_ID{}\tREF{}", uuid::Uuid::new_v4(), i*2+1, i*2+1)
+ writeln!(f, "(40,0)\t{subject}\t0\t{uri}\t{}\tTX_ID{}\tREF{}", uuid::Uuid::new_v4(), i*2, i*2)?;
+ writeln!(f, "(40,0)\t{subject}\t0\t{uri}\t{}\tTX_ID{}\tREF{}", uuid::Uuid::new_v4(), i*2+1, i*2+1)
}
}).await;
b.table("outgoing_transactions(amount, subject, execution_time, credit_payto, end_to_end_id, acct_svcr_ref)", |f, i| {
let subject = if i % 4 == 0 { CompactString::const_new("\\N")} else {format_compact!("subject {i}")};
- let creditor =ACCOUNT.as_ref().as_str();
+
if i % 2 == 0 {
- writeln!(f, "(40,0)\t{subject}\t0\t{creditor}\t\\N\tREF{}", i*2)?;
- writeln!(f, "(41,0)\t{subject}\t0\t{creditor}\tE2E_ID{}\t\\N", i*2)
+ writeln!(f, "(40,0)\t{subject}\t0\t{uri}\t\\N\tREF{}", i*2)?;
+ writeln!(f, "(41,0)\t{subject}\t0\t{uri}\tE2E_ID{}\t\\N", i*2)
} else {
- writeln!(f, "(40,0)\t{subject}\t0\t{creditor}\tE2E_ID{}\tREF{}", i*2, i*2)?;
- writeln!(f, "(41,0)\t{subject}\t0\t{creditor}\tE2E_ID{}\tREF{}", i*2+1, i*2+1)
+ writeln!(f, "(40,0)\t{subject}\t0\t{uri}\tE2E_ID{}\tREF{}", i*2, i*2)?;
+ writeln!(f, "(41,0)\t{subject}\t0\t{uri}\tE2E_ID{}\tREF{}", i*2+1, i*2+1)
}
}).await;
b.table("initiated_outgoing_transactions(amount, subject, initiation_time, credit_payto, outgoing_transaction_id, end_to_end_id)", |f, i| {
- writeln!(f, "(42,0)\tsubject\t0\t{}\t{}\tE2E_ID{i}", &*ACCOUNT , i*2)
+ writeln!(f, "(42,0)\tsubject\t0\t{uri}\t{}\tE2E_ID{i}", i*2)
}).await;
b.table("prepared_transfers(type, account_pub, authorization_pub, authorization_sig, recurrent, reference_number, registered_at, incoming_transaction_id)", |f, i| {
let ty = if i%2==0 {"reserve"} else {"kyc"};
@@ -192,7 +192,7 @@ mod test {
"amount": "KUDOS:0.0001",
"exchange_base_url": "http://exchange.example.com/",
"wtid": ShortHashCode::rand(),
- "credit_account": &*ACCOUNT
+ "credit_account": *CLIENT
}))
.await
.assert_ok()
@@ -225,7 +225,7 @@ mod test {
.json(json!({
"amount": "KUDOS:0.0001",
"reserve_pub": EddsaPublicKey::rand(),
- "debit_account": &*ACCOUNT
+ "debit_account": *CLIENT
}))
.await
.assert_ok()
@@ -253,6 +253,7 @@ mod test {
server
.post("/taler-prepared-transfer/registration")
.json(json!({
+ "credit_account": *EXCHANGE,
"credit_amount": "KUDOS:55",
"type": "reserve",
"alg": "EdDSA",
diff --git a/libeufin-nexus/src/lib.rs b/libeufin-nexus/src/lib.rs
@@ -569,8 +569,8 @@ pub async fn run(cfg: Config, cmd: Cmd) -> anyhow::Result<()> {
} else {
let pool = pool(&cfg.cfg).await?;
- let payto = cfg.ebics()?.account.as_uri();
- let api = Arc::new(NexusApi::start(pool, payto, cfg.currency).await);
+ let payto = &cfg.ebics()?.account;
+ let api = Arc::new(NexusApi::start(pool, payto.clone(), cfg.currency).await);
let mut server = Router::new();
if let Some(it) = cfg.wire_cfg {
server = server
diff --git a/libeufin-nexus/src/manual.rs b/libeufin-nexus/src/manual.rs
@@ -44,6 +44,7 @@ use crate::{
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, EnumMeta)]
#[enum_meta(Str)]
+#[allow(non_camel_case_types)]
pub enum Kind {
batch,
tx,
@@ -56,7 +57,6 @@ pub enum ManualCmd {
Export { out: CompactString },
/// Import EBICS camt files
Import { sources: Vec<CompactString> },
- /// Change batches or transactions status
Status {
kind: Kind,
id: CompactString,
diff --git a/libeufin-nexus/src/test.rs b/libeufin-nexus/src/test.rs
@@ -30,7 +30,7 @@ use taler_common::{
types::{
amount::{Amount, Currency},
base32::Base32,
- payto::{FullIbanPayto, IbanPayto, PaytoURI, payto},
+ payto::{FullIbanPayto, PaytoURI, payto},
},
};
@@ -46,8 +46,14 @@ use crate::{
};
pub const CURR: Currency = Currency::KUDOS;
-pub static ACCOUNT: LazyLock<PaytoURI> =
- LazyLock::new(|| payto("payto://iban/CH4189144589712575493?receiver-name=Test"));
+pub static EXCHANGE: LazyLock<FullIbanPayto> = LazyLock::new(|| {
+ FullIbanPayto::from_str("payto://iban/CH4189144589712575493?receiver-name=Exchange").unwrap()
+});
+pub static CLIENT: LazyLock<FullIbanPayto> = LazyLock::new(|| {
+ FullIbanPayto::from_str("payto://iban/DE84500105177118117964?receiver-name=John+Smith").unwrap()
+});
+pub static UNKNOWN: LazyLock<PaytoURI> =
+ LazyLock::new(|| payto("payto://iban/HU60162006491000639900000000?receiver-name=Unknown"));
/** Generates an outgoing payment, given its subject */
pub fn gen_out_pay(subject: impl Into<String>) -> OutTx {
@@ -59,11 +65,7 @@ pub fn gen_out_pay(subject: impl Into<String>) -> OutTx {
},
amount: Amount::new(&CURR, 44, 0),
debit_fee: Amount::zero(&CURR),
- creditor: Some(
- IbanPayto::from_str("payto://iban/CH4189144589712575493?receiver-name=Test")
- .unwrap()
- .as_uri(),
- ),
+ creditor: Some(EXCHANGE.as_uri()),
subject: Some(subject.into()),
execution_time: Timestamp::now(),
}
@@ -77,8 +79,7 @@ pub fn gen_init_pay(
Initiated {
id: 0,
amount: Amount::new(&CURR, 44, 0),
- creditor: FullIbanPayto::from_str("payto://iban/CH4189144589712575493?receiver-name=Test")
- .unwrap(),
+ creditor: EXCHANGE.clone(),
subject: subject.into(),
initiation_time: Timestamp::now(),
e2e_id: end_to_end_id.into(),
@@ -91,11 +92,7 @@ pub fn gen_in_pay(subject: impl Display) -> InTx {
id: InId::new(None, Some(rand_ebics_id()), None),
amount: Amount::new(&CURR, 44, 0),
credit_fee: Amount::zero(&CURR),
- debtor: Some(
- IbanPayto::from_str("payto://iban/DE84500105177118117964?receiver-name=John+Smith")
- .unwrap()
- .as_uri(),
- ),
+ debtor: Some(CLIENT.as_uri()),
subject: Some(subject.to_string()),
execution_time: Timestamp::now(),
}
diff --git a/testbench/Cargo.toml b/testbench/Cargo.toml
@@ -16,7 +16,7 @@ clap.workspace = true
taler-common.workspace = true
libeufin-nexus = { path = "../libeufin-nexus"}
libeufin-ebics = { path = "../libeufin-ebics"}
-reedline = "0.47"
+reedline = "0.48"
shlex = "2.0"
owo-colors = "4.3"
tracing-subscriber = "0.3"