Smart Byte (1 crate, 2127 LOC, 35 tests)
smart-byte-atproto ATProto (Bluesky federation) adapter.
PLC + did:web resolution; XRPC client; CARv1 encode/decode
with CIDv1 (dag-cbor + raw, SHA-256); sketch MST with
order-independent BLAKE3 root; Repo + UnsignedCommit /
SignedCommit (Ed25519 over CBOR); firehose transport
trait + in-memory impl; AT URI ↔ smart-byte AID bridge
with SAID commitment.
OpenPay (1 crate, 2397 LOC, 44 tests)
op-openbanking UK OBIE R/W v3.1.10/3.1.11, Berlin Group NextGenPSD2
XS2A v1.3.13, STET PSD2 v1.7, Australia CDR Banking v1.31,
FDX v5/v6, SGFinDex shapes. AISP / PISP / PIIS / VRP
traits. FAPI 1.0 Advanced (PS256/ES256, mTLS, RFC 8705
certificate binding, JWK registration). Operators wire
their own JWS signer + HTTP transport — keeps the crate
KMS-agnostic.
EOC (1 crate, 2179 LOC, 32 tests)
eoc-distributed Distributed-inference scheduling. Worker trait with
Capability + Accelerator (CPU/GPU/TPU/NPU/Mixed) +
Load.busyness()/projected_micro_joules()/projected_g_co2e().
RoundRobin / LeastBusy / LatencyWeighted / JouleWeighted
(default) / CarbonWeighted routers. Work-stealing
scheduler. vLLM-style continuous batching with KV-block
budget. Ray-Serve-style auto-scaler with cooldown.
KV-cache-aware sticky-session routing.
Co-Authored-By: Claude Opus 4.7 <[email protected]>
101 lines
3.3 KiB
Rust
101 lines
3.3 KiB
Rust
//! STET PSD2 API binding (France).
|
|
//!
|
|
//! Reference: *STET PSD2 API Documentation Part 1* v1.7. STET is the
|
|
//! French PSD2 dialect — adopted by BNP Paribas, Crédit Agricole,
|
|
//! Société Générale, BPCE, La Banque Postale. The dialect is
|
|
//! structurally similar to Berlin Group but uses different endpoint
|
|
//! and field names.
|
|
//!
|
|
//! STET v1.7 does **not** include a VRP profile. Operators needing
|
|
//! recurring debits use SEPA Direct Debit instead.
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
/// STET endpoint families. Mapped to `/v1/{stet-endpoint-segment}`.
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub enum StetEndpointKind {
|
|
/// `accounts` — AISP root.
|
|
Accounts,
|
|
/// `balances` — balance reads for a known account.
|
|
Balances,
|
|
/// `transactions` — transaction history.
|
|
Transactions,
|
|
/// `payment-requests` — PISP (single immediate or future-dated).
|
|
PaymentRequests,
|
|
/// `funds-confirmations` — CBPII / CoF.
|
|
FundsConfirmations,
|
|
/// `trusted-beneficiaries` — read of the PSU's trusted beneficiary
|
|
/// list, used by STET for the SCA-exemption white-list flow.
|
|
TrustedBeneficiaries,
|
|
}
|
|
|
|
impl StetEndpointKind {
|
|
/// Path segment used under `/v1/...`.
|
|
#[must_use]
|
|
pub const fn as_segment(self) -> &'static str {
|
|
match self {
|
|
Self::Accounts => "accounts",
|
|
Self::Balances => "balances",
|
|
Self::Transactions => "transactions",
|
|
Self::PaymentRequests => "payment-requests",
|
|
Self::FundsConfirmations => "funds-confirmations",
|
|
Self::TrustedBeneficiaries => "trusted-beneficiaries",
|
|
}
|
|
}
|
|
}
|
|
|
|
/// STET consent. STET pins consent semantics tightly to the PSU's
|
|
/// `psuId` (the customer-bank-issued identifier passed in the
|
|
/// `PSU-ID` header). The TPP cannot create a consent without prior
|
|
/// PSU authentication.
|
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub struct StetConsent {
|
|
/// `psuId` of the customer the consent applies to.
|
|
pub psu_id: String,
|
|
/// IBANs the consent covers (empty for `global` consents on
|
|
/// AISP-only flows where the ASPSP returns the list).
|
|
pub ibans: Vec<String>,
|
|
/// Expiry per STET `validUntil`.
|
|
pub valid_until: time::Date,
|
|
}
|
|
|
|
/// STET service handle.
|
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub struct StetService {
|
|
/// ASPSP base URL.
|
|
pub aspsp_base_url: String,
|
|
}
|
|
|
|
impl StetService {
|
|
/// Build a `/v1/{segment}` URL.
|
|
#[must_use]
|
|
pub fn endpoint(&self, kind: StetEndpointKind) -> String {
|
|
let trimmed = self.aspsp_base_url.trim_end_matches('/');
|
|
format!("{}/v1/{}", trimmed, kind.as_segment())
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn endpoint_segments_are_kebab_case() {
|
|
assert_eq!(StetEndpointKind::PaymentRequests.as_segment(), "payment-requests");
|
|
assert_eq!(
|
|
StetEndpointKind::FundsConfirmations.as_segment(),
|
|
"funds-confirmations"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn endpoint_url_constructs() {
|
|
let svc = StetService {
|
|
aspsp_base_url: "https://api.banque.example".into(),
|
|
};
|
|
assert_eq!(
|
|
svc.endpoint(StetEndpointKind::Accounts),
|
|
"https://api.banque.example/v1/accounts"
|
|
);
|
|
}
|
|
}
|