transaction_intent_signer 1.0.0
transaction_intent_signer: ^1.0.0 copied to clipboard
Pure Dart utilities for transaction intent challenges, operation terms hashing, optional liveness-aware summaries, and audit-friendly signed assertions.
transaction_intent_signer #
Pure Dart package for building audit-friendly transaction intent confirmation flows.
It helps developers create intent sessions, hash transaction or loan terms, bind them to a server nonce and confirmation challenge, attach optional liveness-aware interaction summaries, and produce signed audit assertions for high-risk mobile banking and remote lending workflows.
The package creates audit-friendly technical artifacts that can support transaction intent verification workflows. It does not make identity, fraud, credit, legal, or compliance decisions.
What this package does #
- Creates transaction intent models
- Hashes operation / loan terms using deterministic canonical JSON
- Builds transaction-specific confirmation challenges
- Models authenticator confirmation results
- Attaches optional liveness-aware interaction summaries
- Produces signed audit assertions
- Provides demo signing and verification utilities
- Exports audit-friendly JSON artifacts
What this package does not do #
- KYC / AML
- Identity verification
- Biometric authentication
- Fraud prevention or fraud scoring
- Credit decisioning
- Loan origination
- Payment processing
- Legal e-signature compliance
- Production WebAuthn server implementation
Why transaction intent confirmation matters #
High-risk mobile actions — confirming a loan offer, authorizing a large transfer, changing a recovery phone, or adding a new payee — benefit from a clear technical trail that binds:
- the exact operation terms,
- a server-issued challenge / nonce,
- an authenticator confirmation outcome,
- optional interaction-derived signals,
into a reviewable artifact for backend audit and dispute workflows.
This package is developer infrastructure. It helps you construct and verify those technical artifacts. It does not replace bank risk engines, compliance programs, or legal review.
Primary reference use case: remote lending #
The primary reference use case for README examples is remote lending / mobile lending infrastructure for smaller financial organizations:
- community banks
- credit unions
- CDFIs
- small fintech lenders
Typical lending confirmation scenarios:
| Scenario | TransactionIntentType |
|---|---|
| Confirm loan offer | confirmLoanOffer |
| Confirm disbursement | confirmDisbursement |
| Provide e-consent | provideEConsent |
The same architecture also supports broader high-risk mobile banking actions:
| Scenario | TransactionIntentType |
|---|---|
| Authorize large transfer | authorizeLargeTransfer |
| Change recovery phone | changeRecoveryPhone |
| Change security settings | changeSecuritySettings |
| Add new payee | addNewPayee |
| Institution-defined action | custom (+ metadata) |
Architecture overview #
Host App / Bank App
↓
TransactionIntent
↓
Canonical operation terms hash
↓
IntentChallenge + server nonce
↓
AuthenticatorConfirmation
↓
Optional LivenessInteractionSummary
↓
SignedAuditAssertion
↓
Bank backend / audit trail / dispute review
The backend creates a transaction-specific challenge that binds the operation hash, session nonce, and intent metadata. The authenticator signs the challenge, and the server verifies the resulting assertion. This package models those artifacts in pure Dart; it does not implement production WebAuthn server logic.
Installation #
dependencies:
transaction_intent_signer: ^1.0.0
dart pub get
This is a pure Dart package. There is no Flutter dependency.
Quick start #
import 'package:transaction_intent_signer/transaction_intent_signer.dart';
final intent = TransactionIntent(
intentId: 'intent_123',
operationId: 'loan_offer_789',
operationType: TransactionIntentType.confirmLoanOffer,
customerReference: 'customer_456',
institutionReference: 'community_bank_demo',
operationTerms: {
'loanAmount': 15000,
'currency': 'USD',
'apr': 12.5,
'termMonths': 36,
'monthlyPayment': 501.23,
},
createdAt: DateTime.now().toUtc(),
);
const hasher = OperationTermsHasher();
final termsHash = hasher.sha256Canonical(intent.operationTerms);
final challenge = IntentChallengeBuilder().build(
intent: intent,
operationTermsHash: termsHash,
serverNonce: 'server_nonce_abc',
expiresIn: const Duration(minutes: 10),
);
final confirmation = AuthenticatorConfirmation.simulated();
final assertion = AuditAssertionBuilder(
signer: DemoHmacSigner('demo-only-secret'),
).build(
intent: intent,
challenge: challenge,
authenticatorConfirmation: confirmation,
assertionMetadata: const AssertionMetadata(
producer: 'backend',
channel: 'mobile_app',
correlationId: 'corr_demo_001',
),
);
final result = AuditAssertionVerifier(
verifier: DemoHmacVerifier('demo-only-secret'),
).verify(assertion, challenge: challenge);
print(result.isValid);
print(result.failureCode.wireName);
print(prettyJson(assertion.toJson()));
// Optional exploratory compact transport encoding (not full RFC 7515 JWS):
final compact = const CompactAssertionEnvelope().encode(assertion);
print(compact.split('.').length); // 3
Demo signing is provided for reference and testing only. Production systems must use secure server-side key management and institution-specific compliance controls.
Loan offer confirmation example #
final intent = TransactionIntent(
intentId: 'intent_loan_001',
operationId: 'loan_offer_789',
operationType: TransactionIntentType.confirmLoanOffer,
customerReference: 'customer_456',
institutionReference: 'credit_union_demo',
operationTerms: const {
'loanAmount': 15000,
'currency': 'USD',
'apr': 12.5,
'termMonths': 36,
'monthlyPayment': 501.23,
'productCode': 'PERSONAL_INSTALLMENT',
},
createdAt: DateTime.now().toUtc(),
metadata: const IntentMetadata(channel: 'mobile_app'),
);
Any change to hashed terms (amount, APR, schedule, disclosures hash, etc.) changes operationTermsHash.
Large transfer confirmation example #
final intent = TransactionIntent(
intentId: 'intent_xfer_001',
operationId: 'transfer_551',
operationType: TransactionIntentType.authorizeLargeTransfer,
customerReference: 'customer_789',
institutionReference: 'community_bank_demo',
operationTerms: const {
'amount': 25000,
'currency': 'USD',
'fromAccount': 'checking_1001',
'toAccount': 'external_9988',
'recipientName': 'Vendor LLC',
},
createdAt: DateTime.now().toUtc(),
);
Optional liveness-aware summary #
LivenessInteractionSummary is a plain Dart model. The host app can populate it from any source, including derived signals from flutter_liveness_actions or another vendor SDK.
This package does not depend on Flutter or on flutter_liveness_actions.
const liveness = LivenessInteractionSummary(
facePresent: true,
singleFace: true,
challengeCompleted: true,
challengeType: 'turn_head_left',
durationMs: 4200,
averageProcessingMs: 38,
// Safe defaults:
// rawImagesStored: false
// rawImagesUploaded: false
// derivedSignalsOnly: true
);
final assertion = AuditAssertionBuilder(
signer: DemoHmacSigner('demo-only-secret'),
).build(
intent: intent,
challenge: challenge,
authenticatorConfirmation: confirmation,
livenessInteractionSummary: liveness,
);
Default privacy flags are intentionally conservative:
rawImagesStored: falserawImagesUploaded: falsederivedSignalsOnly: truemediaStoredByThisPackage: false(always, in the assertion privacy block)
Signed audit assertion example JSON #
{
"assertionId": "assert_demo_001",
"intentId": "intent_loan_demo_001",
"operationId": "loan_offer_789",
"operationType": "confirm_loan_offer",
"institutionReference": "community_bank_demo",
"customerReference": "customer_456",
"operationTermsHash": {
"algorithm": "sha256",
"canonicalization": "canonical_json_v1",
"value": "sha256:…"
},
"challengeId": "chal_demo_001",
"serverNonceReference": "srv_nonce_demo_9f3a",
"authenticatorConfirmation": {
"userPresence": true,
"userVerification": true,
"authenticatorType": "simulated_passkey",
"confirmedAt": "2026-08-07T12:02:00.000Z"
},
"livenessInteractionSummary": {
"facePresent": true,
"singleFace": true,
"challengeCompleted": true,
"rawImagesStored": false,
"rawImagesUploaded": false,
"derivedSignalsOnly": true
},
"createdAt": "2026-08-07T12:02:30.000Z",
"status": "created",
"privacy": {
"rawImagesStored": false,
"rawImagesUploaded": false,
"derivedSignalsOnly": true,
"mediaStoredByThisPackage": false
},
"identityProofing": "not_performed_by_this_package",
"creditDecision": "not_performed",
"fraudDecision": "not_performed",
"eSignatureCompliance": "not_claimed",
"signatureAlgorithm": "demo_hmac_sha256",
"signature": "hmac-sha256:…"
}
Security and compliance boundaries #
Please read:
Conservative summary:
- This package helps bind operation details to a confirmation artifact and build a technical audit trail.
- It does not detect all fraud, replace bank risk engines, prove legal consent by itself, or verify identity.
- Demo HMAC signing is for reference/testing only.
Integration with flutter_liveness_actions #
Host Flutter apps can map derived liveness signals into LivenessInteractionSummary
without coupling this package to Flutter:
final summary = LivenessSummaryMapper.fromFlutterLivenessActionsLike(
faceDetected: livenessEvent.facePresent,
faceCount: livenessEvent.singleFace ? 1 : 2,
challengePassed: livenessEvent.challengeCompleted,
actionType: livenessEvent.challengeType,
sessionDurationMs: livenessEvent.durationMs,
avgFrameProcessingMs: livenessEvent.averageProcessingMs?.toDouble(),
);
Or run the illustrative adapter example:
dart run example/liveness_mapping_example.dart
See doc/INTEGRATION_GUIDE.md and doc/INTEGRATION_EXAMPLES.md.
Mobile reference helpers (0.4.0) #
Pure Dart helpers for a Flutter demo host — no Flutter dependency in this package:
final session = DemoConfirmationSession.draft(
sessionId: 'sess_1',
intent: intent,
flowLabel: 'remote_lending',
);
final share = const AssertionShareHelper().export(
assertion,
format: AssertionShareFormat.prettyJson,
);
final dashboard = DemoDashboardSnapshot.fromAssertions([assertion]);
print(prettyJson(dashboard.toJson(), options: PrettyJsonOptions.sharePanel));
See doc/MOBILE_REFERENCE.md and run:
dart run example/mobile_reference_example.dart
Documentation #
- Architecture
- Public API review
- SemVer policy
- Assertion schema
- Audit trails
- Threat model
- Integration guide
- Integration examples
- Mobile reference support
- Demo dashboard schema
- Technical review
- Publishing checklist
- WebAuthn boundaries
- Roadmap
- Contributing
Roadmap #
See doc/ROADMAP.md. 1.0.0 is the first stable SemVer release.
License #
MIT License. See LICENSE.