Skip to content
Merged
24 changes: 24 additions & 0 deletions assets/languages/strings_de.arb
Original file line number Diff line number Diff line change
@@ -1,12 +1,29 @@
{
"address": "Address",
"amount_in": "Betrag in",
"available": "Verfügbar",
"balance": "Guthaben",
"bic": "BIC",
"bitbox": "BitBox",
"blockchain": "Blockchain",
"buy": "Kaufen",
"buy_executed_description": "Sobald Ihre Überweisung eingegangen ist, übertragen wir die REALU-Token in Ihre Wallet. Über den Fortschritt Ihrer Transaktion informieren wir Sie per E-Mail.",
"buy_executed_title": "Vielen Dank.",
"buy_payment_confirm": "Klicken Sie hier, sobald Sie die Überweisung getätigt haben",
"buy_payment_information": "Zahlungsinformationen",
"buy_payment_information_description": "Bitte überweise den Kaufbetrag mit diesen Angaben über deine Bankanwendung. Der Verwendungszweck ist wichtig!",
"buy_payment_information_loading": "Lade Zahlungsinformationen",
"buy_payment_information_not_available": "Keine Zahlungsinformationen verfügbar",
"buy_payment_not_possible": "Kauf momentan nicht möglich.",
"buy_payment_not_possible_description": "Es scheint ein Berechtigungsproblem vorzuliegen. Kontaktieren Sie bitte den Support für weitere Informationen.",
"buy_realu": "REALU kaufen",
"close": "Schließen",
"collect_interest": "Auszahlen",
"confirm": "Ausführen",
"connect_with": "Mit ${wallet} verbinden",
"contact_support": "Support kontaktieren",
"copy_seed": "Seed kopieren",
"country": "Land",
"create_wallet": "Neue Wallet erstellen",
"create_wallet_confirm": "Ich habe es gesichert",
"create_wallet_recovery_key_subtitle": "Dies ist Ihr einzigartiger und privater Seed und der einzige Weg, um Ihre Wallet im Falle eines Verlusts oder einer Fehlfunktion wiederherzustellen. Teilen Sie diese Wörter nie. Jeder der diesen Seed kennt hat Zugang zu ihrem Wallet.",
Expand All @@ -25,12 +42,15 @@
"from_clipboard": "Vom Clipboard",
"hardware_wallet": "Hardware Wallet",
"hardware_wallet_subtitle": "Verwahren Sie Ihre RealUnit Aktientoken auf diesem separaten, physischen Gerät (einer \"Hardware Wallet\") aus der Schweiz.",
"iban": "IBAN",
"import_wallet": "Importieren",
"interest_to_be_collected": "Zu vereinnahmende Zinsen",
"invest": "Investieren",
"kyc_status": "KYC Status",
"language_english": "Englisch",
"language_german": "Deutsch",
"location": "Ort",
"name": "Name",
"next": "Weiter",
"onboarding_completed_subtitle": "Investiere in reale Werte und behalte die volle Kontrolle — rund um die Uhr.",
"onboarding_completed_title": "Ihre Wallet ist bereit",
Expand All @@ -39,6 +59,7 @@
"pay": "Bezahlen",
"pay_scan": "Zahlen • Scan",
"portfolio": "Bestand",
"postcode_abr": "PLZ",
"privacy_policy": "Datenschutzerklärung",
"realunit_ag": "RealUnit AG",
"realunit_stockprice": "RealUnit Aktienkurs",
Expand Down Expand Up @@ -68,6 +89,7 @@
"seed": "Seed",
"select_network": "Netzwerk auswählen",
"select_token": "Token auswählen",
"sell": "Verkaufen",
"send": "Senden",
"settings": "Einstellungen",
"settings_currency": "Währung",
Expand All @@ -93,6 +115,8 @@
"user_data": "Nutzerdaten",
"welcome_disclaimer": "Indem Sie fortfahren akzeptieren Sie unsere",
"withdraw": "Auszahlen",
"you_pay": "Du bezahlst",
"you_receive": "Du erhältst",
"your_deuro_cash_and_savings_wallet": "Dein dEURO Cash\n& Spar Wallet",
"your_seed": "Dein dEURO-Seed",
"your_seed_disclaimer": "Dies ist Ihr einzigartiger und privater Seed und der einzige Weg, um Ihre Wallet im Falle eines Verlusts oder einer Fehlfunktion wiederherzustellen."
Expand Down
24 changes: 24 additions & 0 deletions assets/languages/strings_en.arb
Original file line number Diff line number Diff line change
@@ -1,12 +1,29 @@
{
"address": "Adresse",
"amount_in": "Amount in",
"available": "Available",
"balance": "Balance",
"bic": "BIC",
"bitbox": "BitBox",
"blockchain": "Blockchain",
"buy": "Buy",
"buy_executed_description": "As soon as your transfer has been received, we will transfer the REALU tokens to your wallet. We will inform you about the progress of your transaction by email.",
"buy_executed_title": "Thank you.",
"buy_payment_confirm": "Click here once you have made the transfer.",
"buy_payment_information": "Payment information",
"buy_payment_information_description": "Please transfer the purchase amount using your banking app with these details. The purpose of payment is important!",
"buy_payment_information_loading": "Load payment information",
"buy_payment_information_not_available": "No payment information available",
"buy_payment_not_possible": "Purchase currently not possible.",
"buy_payment_not_possible_description": "There appears to be a permission issue. Please contact support for further information.",
"buy_realu": "Buy REALU",
"close": "Close",
"collect_interest": "Collect",
"confirm": "Confirm",
"connect_with": "Connect with ${wallet}",
"contact_support": "Contact support",
"copy_seed": "Copy seed",
"country": "Country",
"create_wallet": "Create new Wallet",
"create_wallet_confirm": "I’ve written it down",
"create_wallet_recovery_key_subtitle": "The 12 words below are your recovery phrase. You can use them to restore your wallet if your device is lost or replaced. Never share these words. Anyone who knows them can access your funds.",
Expand All @@ -25,12 +42,15 @@
"from_clipboard": "From Clipboard",
"hardware_wallet": "Hardware Wallet",
"hardware_wallet_subtitle": "Store your RealUnit stock tokens on this separate, physical device (a \"hardware wallet\") from Switzerland.",
"iban": "IBAN",
"import_wallet": "Import",
"interest_to_be_collected": "Interest to be collected",
"invest": "Invest",
"kyc_status": "KYC status",
"language_english": "English",
"language_german": "German",
"location": "Location",
"name": "Name",
"next": "Continue",
"onboarding_completed_subtitle": "Invest in real assets and maintain full control — around the clock.",
"onboarding_completed_title": "Your wallet is ready",
Expand All @@ -39,6 +59,7 @@
"pay": "Pay",
"pay_scan": "Pay • Scan",
"portfolio": "Portfolio",
"postcode_abr": "Post code",
"privacy_policy": "privacy policy",
"realunit_ag": "RealUnit AG",
"realunit_stockprice": "RealUnit Stockprice",
Expand Down Expand Up @@ -68,6 +89,7 @@
"seed": "Seed",
"select_network": "Select network",
"select_token": "Select Token",
"sell": "Sell",
"send": "Send",
"settings": "Settings",
"settings_currency": "Currency",
Expand All @@ -93,6 +115,8 @@
"user_data": "User data",
"welcome_disclaimer": "By continuing you agree to our",
"withdraw": "Withdraw",
"you_pay": "You pay",
"you_receive": "You receive",
"your_deuro_cash_and_savings_wallet": "Your dEURO Cash\n& Savings Wallet",
"your_seed": "Your dEURO-seed",
"your_seed_disclaimer": "This is your unique and private seed and it is the only way to recover your wallet in case of loss or malfunction."
Expand Down
7 changes: 7 additions & 0 deletions lib/di.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import 'package:realunit_wallet/packages/repository/transaction_repository.dart'
import 'package:realunit_wallet/packages/repository/wallet_repository.dart';
import 'package:realunit_wallet/packages/service/app_store.dart';
import 'package:realunit_wallet/packages/service/balance_service.dart';
import 'package:realunit_wallet/packages/service/dfx/dfx_allowlist_service.dart';
import 'package:realunit_wallet/packages/service/dfx/dfx_bank_details_service.dart';
import 'package:realunit_wallet/packages/service/dfx/dfx_brokerbot_service.dart';
import 'package:realunit_wallet/packages/service/dfx/dfx_price_service.dart';
import 'package:realunit_wallet/packages/service/dfx/dfx_service.dart';
import 'package:realunit_wallet/packages/service/settings_service.dart';
Expand Down Expand Up @@ -90,6 +93,10 @@ void setupServices() {

getIt.registerFactory(() => OpenCryptoPayService());
getIt.registerFactory(() => DFXPriceService(getIt<AppStore>()));
getIt.registerFactory(() => DfxAllowlistService(getIt<AppStore>()));
getIt.registerFactory(() => DfxBankDetailsService(getIt<AppStore>()));
getIt.registerFactory(() => DfxBrokerbotService(getIt<AppStore>()));

getIt.registerFactory(() => SettingsService(getIt<SettingsRepository>()));
getIt.registerFactory(
() => DFXService(getIt<AppStore>(), getIt<SettingsRepository>(), getIt<AssetRepository>()));
Expand Down
22 changes: 22 additions & 0 deletions lib/packages/service/dfx/dfx_allowlist_service.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import 'dart:convert';

import 'package:realunit_wallet/packages/service/app_store.dart';
import 'package:realunit_wallet/packages/service/dfx/models/dfx_allowlist_status.dart';

class DfxAllowlistService {
static const _baseUrl = "https://dev.api.dfx.swiss/v1/realunit";
final AppStore _appStore;

DfxAllowlistService(this._appStore);

Future<DfxAllowlistStatus> checkAllowlist() async {
final url = Uri.parse("$_baseUrl/allowlist/${_appStore.primaryAddress}");
final response = await _appStore.httpClient.get(url);

if (response.statusCode != 200) {
throw Exception("Allowlist request failed: ${response.body}");
}

return DfxAllowlistStatus.fromJson(jsonDecode(response.body));
}
}
23 changes: 23 additions & 0 deletions lib/packages/service/dfx/dfx_bank_details_service.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import 'dart:convert';

import 'package:realunit_wallet/packages/service/app_store.dart';
import 'package:realunit_wallet/packages/service/dfx/models/dfx_bank_details.dart';

class DfxBankDetailsService {
static const _baseUrl = "https://dev.api.dfx.swiss/v1/realunit";
final AppStore _appStore;

DfxBankDetailsService(this._appStore);

Future<BankDetails> getBankDetails() async {
final url = Uri.parse("$_baseUrl/bank");
final response = await _appStore.httpClient.get(url);

if (response.statusCode != 200) {
throw Exception("Bank details request failed: ${response.body}");
}

final json = jsonDecode(response.body);
return BankDetails.fromJson(json);
}
}
36 changes: 36 additions & 0 deletions lib/packages/service/dfx/dfx_brokerbot_service.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import 'dart:convert';

import 'package:realunit_wallet/packages/service/app_store.dart';
import 'package:realunit_wallet/packages/service/dfx/models/brokerbot/dfx_buy_price_dto.dart';
import 'package:realunit_wallet/packages/service/dfx/models/brokerbot/dfx_shares_dto.dart';

class DfxBrokerbotService {
static const _baseUrl = "https://dev.api.dfx.swiss/v1/realunit/brokerbot";
final AppStore _appStore;

DfxBrokerbotService(this._appStore);

/// Convert REALU shares → CHF
Future<BrokerbotBuyPriceDto> getBuyPrice(int shares) async {
final url = Uri.parse("$_baseUrl/buyPrice?shares=$shares");
final res = await _appStore.httpClient.get(url);

if (res.statusCode != 200) {
throw Exception("BuyPrice request failed: ${res.body}");
}

return BrokerbotBuyPriceDto.fromJson(jsonDecode(res.body));
}

/// Convert CHF → REALU shares
Future<BrokerbotSharesDto> getShares(double amount) async {
final url = Uri.parse("$_baseUrl/shares?amount=$amount");
final res = await _appStore.httpClient.get(url);

if (res.statusCode != 200) {
throw Exception("Shares request failed: ${res.body}");
}

return BrokerbotSharesDto.fromJson(jsonDecode(res.body));
}
}
22 changes: 22 additions & 0 deletions lib/packages/service/dfx/models/brokerbot/dfx_buy_price_dto.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
class BrokerbotBuyPriceDto {
final double totalCost;
final double pricePerShare;

BrokerbotBuyPriceDto({
required this.totalCost,
required this.pricePerShare,
});

factory BrokerbotBuyPriceDto.fromJson(Map<String, dynamic> json) {
double parseDouble(dynamic value) {
if (value == null) return 0.0;
final s = value.toString().replaceAll(',', '.').trim();
return double.tryParse(s) ?? 0.0;
}

return BrokerbotBuyPriceDto(
totalCost: parseDouble(json['totalPrice']),
pricePerShare: parseDouble(json['pricePerShare']),
);
}
}
16 changes: 16 additions & 0 deletions lib/packages/service/dfx/models/brokerbot/dfx_shares_dto.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class BrokerbotSharesDto {
final int shares;
final double pricePerShare;

BrokerbotSharesDto({
required this.shares,
required this.pricePerShare,
});

factory BrokerbotSharesDto.fromJson(Map<String, dynamic> json) {
return BrokerbotSharesDto(
shares: int.parse(json['shares'].toString()),
pricePerShare: double.parse(json['pricePerShare'].toString()),
);
}
}
28 changes: 28 additions & 0 deletions lib/packages/service/dfx/models/dfx_allowlist_status.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
class DfxAllowlistStatus {
final String address;

/// Address needs to be registered as RealUnit customer to be able to receive.
final bool canReceive;

/// Address is suspended, buying is not possible.
final bool isForbidden;

/// Privileged address.
final bool isPowerlisted;

DfxAllowlistStatus({
required this.address,
required this.canReceive,
required this.isForbidden,
required this.isPowerlisted,
});

factory DfxAllowlistStatus.fromJson(Map<String, dynamic> json) {
return DfxAllowlistStatus(
address: json['address'] as String,
canReceive: json['canReceive'] as bool,
isForbidden: json['isForbidden'] as bool,
isPowerlisted: json['isPowerlisted'] as bool,
);
}
}
26 changes: 26 additions & 0 deletions lib/packages/service/dfx/models/dfx_bank_details.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
class BankDetails {
final String recipient;
final String address;
final String iban;
final String bic;
final String bankName;
final String currency;

const BankDetails({
required this.recipient,
required this.address,
required this.iban,
required this.bic,
required this.bankName,
required this.currency,
});

factory BankDetails.fromJson(Map<String, dynamic> json) => BankDetails(
recipient: json['recipient'],
address: json['address'],
iban: json['iban'],
bic: json['bic'],
bankName: json['bankName'],
currency: json['currency'],
);
}
2 changes: 1 addition & 1 deletion lib/packages/utils/default_assets.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'package:realunit_wallet/models/asset.dart';

const realUnitAsset = Asset(chainId: 1, address: '0x553C7f9C780316FC1D34b8e14ac2465Ab22a090B', name: 'RealUnit Aktientoken', symbol: 'REALU', decimals: 0);
const realUnitAsset = Asset(chainId: 1, address: '0x553C7f9C780316FC1D34b8e14ac2465Ab22a090B', name: 'RealUnit Token', symbol: 'REALU', decimals: 0);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does this change come from?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the name from RealUnit Aktientoken to RealUnit Token

const dEUROAsset = Asset(chainId: 1, address: '0xbA3f535bbCcCcA2A154b573Ca6c5A49BAAE0a3ea', name: 'dEuro', symbol: 'dEURO', decimals: 18);
const dEUROBaseAsset = Asset(chainId: 8453, address: '0x1B5F7fA46ED0F487F049C42f374cA4827d65A264', name: 'dEuro (Base)', symbol: 'dEURO', decimals: 18);
const dEUROOptimismAsset = Asset(chainId: 10, address: '0x1B5F7fA46ED0F487F049C42f374cA4827d65A264', name: 'dEuro (Optimism)', symbol: 'dEURO', decimals: 18);
Expand Down
2 changes: 2 additions & 0 deletions lib/router.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:realunit_wallet/models/blockchain.dart';
import 'package:realunit_wallet/packages/open_crypto_pay/models.dart';
import 'package:realunit_wallet/packages/service/app_store.dart';
import 'package:realunit_wallet/packages/service/dfx/dfx_price_service.dart';
import 'package:realunit_wallet/screens/buy/buy_page.dart';
import 'package:realunit_wallet/screens/create_wallet/create_wallet_page.dart';
import 'package:realunit_wallet/screens/dashboard/dashboard_page.dart';
import 'package:realunit_wallet/screens/home/home.dart';
Expand Down Expand Up @@ -43,6 +44,7 @@ void setupRouter() {
GoRoute(
path: "/dashboard",
builder: (context, state) => DashboardPage(getIt<AppStore>(), getIt<DFXPriceService>())),
GoRoute(path: BuyPage.routeName, builder: (context, state) => BuyPage()),
GoRoute(path: "/receive", builder: (context, state) => ReceivePage(isBottomSheet: false)),
GoRoute(
path: "/send",
Expand Down
Loading