Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions assets/languages/strings_de.arb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"buyExecutedReference": "Ihre Referenz",
"buyExecutedTitle": "Vielen Dank.",
"buyMinAmount": "Mindestbetrag: ${amount} ${currency}",
"buyPaymentConfirm": "Zahlungsanweisungen per E-Mail anfordern",
"buyPaymentConfirm": "Klicken Sie hier, sobald Sie die Überweisung getätigt haben",
"buyPaymentConfirmFailed": "Es gibt ein technisches Problem. Bitte versuchen Sie es später erneut. Falls der Fehler weiterhin besteht, kontaktieren Sie unseren Support.",
"buyPaymentConfirmFailedAktionariat": "Es gibt ein technisches Problem. Bitte überprüfen Sie Ihr E-Mail-Postfach, möglicherweise fehlt noch eine Bestätigung Ihrer Blockchain-Adresse. Andernfalls versuchen Sie es später erneut. Falls der Fehler weiterhin besteht, kontaktieren Sie unseren Support.",
"buyPaymentInformation": "Zahlungsinformationen",
Expand Down Expand Up @@ -122,7 +122,6 @@
"kycMergeProcessingTitle": "Konten werden zusammengeführt",
"kycPending": "Daten werden geprüft",
"kycPendingDescription": "Ihr folgender Schritt ist gerade noch unter Prüfung: ${step}. Bitte haben Sie noch ein wenig Geduld und schauen Sie zu einem späteren Zeitpunkt nochmal rein.",
"kycRequiredFailureMessage": "Bitte schliessen Sie zuerst Ihre Verifizierung ab.",
"kycSignatureUnsupportedDescription": "Dieses Feature erfordert eine EIP-712-Signatur. Im Debug-Modus (Adresse + Signatur) ist dies technisch nicht möglich. Bitte verwenden Sie eine Software-Wallet oder BitBox, um RealUnit zu nutzen.",
"kycSignatureUnsupportedTitle": "Signatur nicht verfügbar",
"kycUnsupportedStepDescription": "Der aktuelle KYC-Schritt (${step}) kann in dieser App nicht abgeschlossen werden. Bitte kontaktieren Sie den Support.",
Expand Down
3 changes: 1 addition & 2 deletions assets/languages/strings_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"buyExecutedReference": "Your reference",
"buyExecutedTitle": "Thank you.",
"buyMinAmount": "Minimum amount: ${amount} ${currency}",
"buyPaymentConfirm": "Request payment instructions by email",
"buyPaymentConfirm": "Click here once you have made the transfer",
"buyPaymentConfirmFailed": "There is a technical problem. Please try again later. If the error persists, contact our support team.",
"buyPaymentConfirmFailedAktionariat": "There is a technical problem. Please check your email inbox — you may still need to confirm your blockchain address. Otherwise, please try again later. If the error persists, contact our support team.",
"buyPaymentInformation": "Payment information",
Expand Down Expand Up @@ -122,7 +122,6 @@
"kycMergeProcessingTitle": "Merging your accounts",
"kycPending": "Data is being verified",
"kycPendingDescription": "Your next step is currently being reviewed: ${step}. Please be patient and check back later.",
"kycRequiredFailureMessage": "Please complete your identity verification first.",
"kycSignatureUnsupportedDescription": "This feature requires an EIP-712 signature. The Debug mode (address + signature) cannot produce one. Please use a Software Wallet or a BitBox to use RealUnit.",
"kycSignatureUnsupportedTitle": "Signature not available",
"kycUnsupportedStepDescription": "The current KYC step (${step}) cannot be completed in this app. Please contact support.",
Expand Down
6 changes: 3 additions & 3 deletions docs/wallet-modes.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ enum WalletType { software, bitbox, debug }
|---|---|---|---|
| `software` | yes (12-word seed, encrypted at rest) | signs in the background, near-zero user friction | full app — register, link wallet, trade |
| `bitbox` | yes (on the hardware device) | requires confirmation on the connected unlocked BitBox | full app — register, link wallet, trade |
| `debug` | no (address only, plus a stored signature attestation) | **cannot sign** — `DebugWalletAccount.signMessage` throws `UnsupportedError` | read-only browsing of a known address, plus any flow that the API accepts without a fresh signature (`AlreadyRegistered`, `KycRequired`) |
| `debug` | no (address only, plus a stored signature attestation) | **cannot sign** — `DebugWalletAccount.signMessage` throws `UnsupportedError` | read-only browsing of a known address, plus any flow that the API accepts without a fresh signature (`AlreadyRegistered`) |

## Features that require signing

Expand All @@ -37,8 +37,8 @@ current wallet is `WalletType.debug` and the API has routed to either of the
above states, the cubit emits `KycSignatureUnsupportedFailure` instead of
`KycSuccess`, and `KycPageManager` renders `KycSignatureUnsupportedPage`.

`AlreadyRegistered` and `KycRequired` do not invoke the signer, so debug-mode
users flow through them unchanged.
`AlreadyRegistered` does not invoke the signer, so debug-mode
users flow through it unchanged.

## Why this gate is local

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class RealUnitRegistrationInfoDto {
/// `KycCubit._runCheckKyc` — see CONTRIBUTING.md "API as Decision
/// Authority". `userData` is populated for `addWallet` (prior payload)
/// and `newRegistration` (KYC pre-fill); `null` for `alreadyRegistered`
/// (no UX needed) and `kycRequired` (edge case).
/// (no UX needed).
final RealUnitRegistrationState state;
final RealUnitUserDataDto? realUnitUserDataDto;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,7 @@ enum RealUnitRegistrationState {

/// No prior Aktionariat registration on this account. The app shows
/// the full registration form, pre-filled from `userData` when present.
newRegistration(jsonName: 'NewRegistration'),

/// Edge case — KYC not done yet. Reachable from the wallet-status
/// endpoint only when something is very wrong; surfaced as
/// `KycUnsupportedStepFailure`.
kycRequired(jsonName: 'KycRequired');
newRegistration(jsonName: 'NewRegistration');

final String jsonName;
const RealUnitRegistrationState({required this.jsonName});
Expand Down
3 changes: 0 additions & 3 deletions lib/screens/kyc/cubits/kyc/kyc_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,6 @@ class KycCubit extends Cubit<KycState> {
),
);
return;
case RealUnitRegistrationState.kycRequired:
emit(const KycRequiredFailure());
return;
}

// Account-merge invitation is still surfaced from the step list because
Expand Down
9 changes: 0 additions & 9 deletions lib/screens/kyc/cubits/kyc/kyc_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -92,15 +92,6 @@ class KycFailure extends KycState {
List<Object?> get props => [message];
}

/// Emitted when `getRegistrationInfo()` reports `kycRequired` — i.e. the
/// wallet cannot be added without first completing the identity verification
/// flow. Distinct from `KycUnsupportedStepFailure` so the user sees a
/// tailored "complete your verification" message instead of the generic
/// "step (-) cannot be completed" fallback.
class KycRequiredFailure extends KycState {
const KycRequiredFailure();
}

/// Emitted when the wallet currently in use cannot produce EIP-712 signatures
/// (today: the address+signature debug wallet) and the API has routed the
/// user to a state (`NewRegistration` / `AddWallet`) that would require one.
Expand Down
3 changes: 0 additions & 3 deletions lib/screens/kyc/kyc_page_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,6 @@ class KycViewManager extends StatelessWidget {
builder: (context, state) => switch (state) {
KycLoading() => const KycLoadingPage(),
KycFailure(:final message) => KycFailurePage(message: message),
KycRequiredFailure() => KycFailurePage(
message: S.of(context).kycRequiredFailureMessage,
),
KycSignatureUnsupportedFailure() => const KycSignatureUnsupportedPage(),
KycUnsupportedStepFailure(:final stepName) => KycFailurePage(
message: S.of(context).kycUnsupportedStepDescription(stepName?.value ?? '-'),
Expand Down
Binary file modified test/goldens/screens/home/goldens/macos/home_page_loaded.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 0 additions & 10 deletions test/packages/service/dfx/models/aggregate_dtos_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -206,16 +206,6 @@ void main() {
expect(dto.realUnitUserDataDto, isNotNull);
});

test('parses KycRequired with null userData (edge case)', () {
final dto = RealUnitRegistrationInfoDto.fromJson({
'state': 'KycRequired',
'userData': null,
});

expect(dto.state, RealUnitRegistrationState.kycRequired);
expect(dto.realUnitUserDataDto, isNull);
});

test('throws ArgumentError on unknown state', () {
expect(
() => RealUnitRegistrationInfoDto.fromJson({
Expand Down
29 changes: 2 additions & 27 deletions test/screens/kyc/cubits/kyc/kyc_cubit_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -279,37 +279,12 @@ void main() {
],
);

// `KycRequired` gets its own dedicated state so the failure page can show
// a tailored "complete your verification" message instead of the generic
// "step (-) cannot be completed" fallback.
blocTest<KycCubit, KycState>(
'emits KycRequiredFailure when wallet status reports KycRequired',
setUp: () {
when(() => kycService.getKycStatus()).thenAnswer(
(_) async => _kycStatus(level: KycLevel.level20),
);
when(() => kycService.getUser()).thenAnswer((_) async => _user());
when(() => registrationService.getRegistrationInfo()).thenAnswer(
(_) async => _walletStatus(RealUnitRegistrationState.kycRequired),
);
},
build: buildCubit,
act: (cubit) async {
cubit.markLegalDisclaimerAccepted();
await cubit.checkKyc();
},
expect: () => [
const KycLoading(),
const KycRequiredFailure(),
],
);

// Wallet-mode signing-capability gate: the address+signature debug
// wallet cannot produce an EIP-712 signature. The cubit must surface
// `KycSignatureUnsupportedFailure` BEFORE emitting `KycSuccess` for any
// state that would require signing (`NewRegistration` / `AddWallet`).
// States that don't require signing (`AlreadyRegistered`, `KycRequired`)
// still flow through normally.
// States that don't require signing (`AlreadyRegistered`) still flow
// through normally.
blocTest<KycCubit, KycState>(
'emits KycSignatureUnsupportedFailure when debug wallet + NewRegistration',
setUp: () {
Expand Down
Loading