Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
ee88b63
Add Starknet wallet support and merge upstream/dev
adrienlacombe Mar 18, 2026
2adbad4
fix: replace Starknet logo with correct asset
adrienlacombe Mar 24, 2026
ac7f39d
Migrate Starknet to Rust FFI bridge and update transaction details UI
adrienlacombe Mar 18, 2026
f786415
Fix code quality issues from PR review
adrienlacombe Apr 6, 2026
24de60a
Bump flutter_rust_bridge override to 2.12.0
adrienlacombe Apr 6, 2026
475ab56
Update Starknet interface imports
adrienlacombe Apr 9, 2026
d3b26f4
Complete Starknet wallet and signing flows
adrienlacombe Apr 15, 2026
d153fcb
Improve Starknet fee controls and transaction decoding
adrienlacombe Apr 15, 2026
4425f91
Revert formatting-only Starknet PR changes
adrienlacombe Apr 15, 2026
1a242c1
Run Android APK build on feat/starknet pushes
adrienlacombe Apr 16, 2026
9c25cc1
Harden Android self-hosted runner usage
adrienlacombe Apr 16, 2026
4993139
Fix ephemeral runner bootstrap service
adrienlacombe Apr 16, 2026
f841777
Use private subnet for ephemeral runners
adrienlacombe Apr 16, 2026
1dd543f
Avoid upstream GHCR pushes from fork CI
adrienlacombe Apr 16, 2026
d9b13a6
Keep pulled Android dependency images locally
adrienlacombe Apr 16, 2026
ed92175
Autoscale Android runners on branch pushes
adrienlacombe Apr 16, 2026
2e452ec
Use explicit names for autoscaled runners
adrienlacombe Apr 16, 2026
d652ff3
Add baked Android runner AMI support
adrienlacombe Apr 16, 2026
22d3fbe
Fix Android CI Starknet build inputs
adrienlacombe Apr 16, 2026
f989015
Fix reusable Android workflow syntax
adrienlacombe Apr 16, 2026
80ead9d
Handle missing secrets template in Android CI
adrienlacombe Apr 16, 2026
5f87ada
Fix Android CI secrets fallback formatting
adrienlacombe Apr 16, 2026
7c42d74
Avoid cold-start runner dependency installs
adrienlacombe Apr 16, 2026
413785a
Fix Android CI secrets and Starknet codegen
adrienlacombe Apr 16, 2026
71bfd17
Normalize secret key names in Android CI
adrienlacombe Apr 16, 2026
692a182
Sanitize Android APK artifact filenames
adrienlacombe Apr 16, 2026
2499c1c
Make Android Slack upload optional
adrienlacombe Apr 16, 2026
f2e35b0
Make Android Slack upload optional
adrienlacombe Apr 16, 2026
42351fe
Fix Android PIN setup encryption
adrienlacombe Apr 16, 2026
4e68e9a
Refresh Starknet RPC list and drop per-call fallback
adrienlacombe Apr 17, 2026
0a9fc2a
Speed up Android CI build
adrienlacombe Apr 17, 2026
57b2bff
Cache fork-built docker layers and Rust target dir in CI
adrienlacombe Apr 17, 2026
bb08094
Fix CI: stop shadowing preinstalled rustup
adrienlacombe Apr 17, 2026
89fc9cc
Initialize rustls-platform-verifier for Starknet on Android
adrienlacombe Apr 17, 2026
25aa942
Drop WalletConnect v2 integration for Starknet
adrienlacombe Apr 19, 2026
cf8bd87
Revert .github changes from feat/starknet
adrienlacombe Apr 19, 2026
75e2cfe
Revert fork-specific CI scripts from feat/starknet
adrienlacombe Apr 19, 2026
a18b56f
Drop unrelated changes from feat/starknet
adrienlacombe Apr 19, 2026
28f608d
Strip formatter churn from 3 big Starknet files
adrienlacombe Apr 19, 2026
b8fe391
Strip formatter churn from settings_store + default_settings_migration
adrienlacombe Apr 19, 2026
bf79fd9
Merge remote-tracking branch 'upstream/dev' into feat/starknet
adrienlacombe Apr 20, 2026
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
4 changes: 4 additions & 0 deletions android/app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
-dontwarn com.google.android.play.core.splitcompat.SplitCompatApplication
-dontwarn com.google.android.gms.common.annotation.NoNullnessRewrite

## Starknet JNI + rustls-platform-verifier
-keep, includedescriptorclasses class com.cakewallet.cake_wallet.StarknetRust { *; }
-keep, includedescriptorclasses class org.rustls.platformverifier.** { *; }

# start reown
-dontwarn com.github.luben.zstd.BufferPool
-dontwarn com.github.luben.zstd.ZstdInputStream
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,9 @@
import io.flutter.app.FlutterApplication;

public class Application extends FlutterApplication {
@Override
public void onCreate() {
super.onCreate();
StarknetRust.ensureInitialized(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.cakewallet.cake_wallet;

import android.content.Context;

public final class StarknetRust {
private static boolean sInitialized = false;

static {
System.loadLibrary("cw_starknet_rust");
}

private StarknetRust() {}

public static synchronized void ensureInitialized(Context context) {
if (sInitialized) return;
nativeInit(context.getApplicationContext());
sInitialized = true;
}

private static native void nativeInit(Context context);
}
Binary file added assets/images/crypto/starknet.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions assets/new-ui/balance_card_icons/starknet.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions assets/starknet_node_list.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
-
uri: api.cartridge.gg/x/starknet/mainnet
useSSL: true
is_default: true
isEnabledForAutoSwitching: true
-
uri: rpc.starknet.lava.build
useSSL: true
isEnabledForAutoSwitching: true
-
uri: starknet-rpc.publicnode.com
useSSL: true
isEnabledForAutoSwitching: true
-
uri: starknet.drpc.org
useSSL: true
isEnabledForAutoSwitching: true
97 changes: 65 additions & 32 deletions cw_core/lib/crypto_currency.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import 'package:collection/collection.dart';
import 'package:cw_core/format_fixed.dart';
import 'package:cw_core/parse_fixed.dart';

class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implements Currency {
class CryptoCurrency extends EnumerableItem<int>
with Serializable<int>
implements Currency {
const CryptoCurrency({
String title = '',
int raw = -1,
Expand Down Expand Up @@ -128,6 +130,7 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
CryptoCurrency.arbEth,
CryptoCurrency.usdcArb,
CryptoCurrency.usdtArb,
CryptoCurrency.strk,
];

static const havenCurrencies = [
Expand Down Expand Up @@ -169,19 +172,32 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
static const xrp = CryptoCurrency(title: 'XRP', fullName: 'Ripple', raw: 15, name: 'xrp', iconPath: 'assets/images/xrp_icon.png', decimals: 6);
static const xhv = CryptoCurrency(title: 'XHV', fullName: 'Haven Protocol', raw: 16, name: 'xhv', iconPath: 'assets/images/xhv_logo.png', decimals: 12);

static const xag = CryptoCurrency(title: 'XAG', tag: 'XHV', raw: 17, name: 'xag', decimals: 12);
static const xau = CryptoCurrency(title: 'XAU', tag: 'XHV', raw: 18, name: 'xau', decimals: 12);
static const xaud = CryptoCurrency(title: 'XAUD', tag: 'XHV', raw: 19, name: 'xaud', decimals: 12);
static const xbtc = CryptoCurrency(title: 'XBTC', tag: 'XHV', raw: 20, name: 'xbtc', decimals: 12);
static const xcad = CryptoCurrency(title: 'XCAD', tag: 'XHV', raw: 21, name: 'xcad', decimals: 12);
static const xchf = CryptoCurrency(title: 'XCHF', tag: 'XHV', raw: 22, name: 'xchf', decimals: 12);
static const xcny = CryptoCurrency(title: 'XCNY', tag: 'XHV', raw: 23, name: 'xcny', decimals: 12);
static const xeur = CryptoCurrency(title: 'XEUR', tag: 'XHV', raw: 24, name: 'xeur', decimals: 12);
static const xgbp = CryptoCurrency(title: 'XGBP', tag: 'XHV', raw: 25, name: 'xgbp', decimals: 12);
static const xjpy = CryptoCurrency(title: 'XJPY', tag: 'XHV', raw: 26, name: 'xjpy', decimals: 12);
static const xnok = CryptoCurrency(title: 'XNOK', tag: 'XHV', raw: 27, name: 'xnok', decimals: 12);
static const xnzd = CryptoCurrency(title: 'XNZD', tag: 'XHV', raw: 28, name: 'xnzd', decimals: 12);
static const xusd = CryptoCurrency(title: 'XUSD', tag: 'XHV', raw: 29, name: 'xusd', decimals: 12);
static const xag = CryptoCurrency(
title: 'XAG', tag: 'XHV', raw: 17, name: 'xag', decimals: 12);
static const xau = CryptoCurrency(
title: 'XAU', tag: 'XHV', raw: 18, name: 'xau', decimals: 12);
static const xaud = CryptoCurrency(
title: 'XAUD', tag: 'XHV', raw: 19, name: 'xaud', decimals: 12);
static const xbtc = CryptoCurrency(
title: 'XBTC', tag: 'XHV', raw: 20, name: 'xbtc', decimals: 12);
static const xcad = CryptoCurrency(
title: 'XCAD', tag: 'XHV', raw: 21, name: 'xcad', decimals: 12);
static const xchf = CryptoCurrency(
title: 'XCHF', tag: 'XHV', raw: 22, name: 'xchf', decimals: 12);
static const xcny = CryptoCurrency(
title: 'XCNY', tag: 'XHV', raw: 23, name: 'xcny', decimals: 12);
static const xeur = CryptoCurrency(
title: 'XEUR', tag: 'XHV', raw: 24, name: 'xeur', decimals: 12);
static const xgbp = CryptoCurrency(
title: 'XGBP', tag: 'XHV', raw: 25, name: 'xgbp', decimals: 12);
static const xjpy = CryptoCurrency(
title: 'XJPY', tag: 'XHV', raw: 26, name: 'xjpy', decimals: 12);
static const xnok = CryptoCurrency(
title: 'XNOK', tag: 'XHV', raw: 27, name: 'xnok', decimals: 12);
static const xnzd = CryptoCurrency(
title: 'XNZD', tag: 'XHV', raw: 28, name: 'xnzd', decimals: 12);
static const xusd = CryptoCurrency(
title: 'XUSD', tag: 'XHV', raw: 29, name: 'xusd', decimals: 12);

static const ape = CryptoCurrency(title: 'APE', tag: 'ETH', fullName: 'ApeCoin', raw: 30, name: 'ape', iconPath: 'assets/images/ape_icon.png', decimals: 18);
static const avaxc = CryptoCurrency(title: 'AVAX', tag: 'AVAXC', fullName: 'Avalanche', raw: 31, name: 'avaxc', iconPath: 'assets/images/avaxc_icon.png',iconSvgPath: "assets/new-ui/crypto_full_icons/avax.svg", decimals: 9);
Expand Down Expand Up @@ -265,21 +281,31 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
static const usdcArb = CryptoCurrency(title: 'USDC', tag: 'ARB', fullName: 'USDC Coin', raw: 108, name: 'usdcarb', iconPath: 'assets/images/crypto/usdc.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/usdc.svg", decimals: 6);
static const usdtArb = CryptoCurrency(title: 'USDT', tag: 'ARB', fullName: 'USDT Tether', raw: 109, name: 'usdtarb', iconPath: 'assets/images/crypto/tether.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/usdt.svg", decimals: 6);
static const ltcmweb = CryptoCurrency(title: 'LTC', fullName: 'Litecoin MWeb', raw: 110, name: 'ltcmweb', iconPath: 'assets/images/crypto/litecoin.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/litecoin.svg", decimals: 8);
static const strk = CryptoCurrency(title: 'STRK', fullName: 'Starknet', raw: 111, name: 'strk', iconPath: 'assets/images/crypto/starknet.webp', decimals: 18, flatIconPath: "assets/new-ui/balance_card_icons/starknet.svg");

static final Map<int, CryptoCurrency> _rawCurrencyMap =
[...all, ...havenCurrencies, ...zcashCurrencies].fold<Map<int, CryptoCurrency>>(<int, CryptoCurrency>{}, (acc, item) {
static final Map<int, CryptoCurrency> _rawCurrencyMap = [
...all,
...havenCurrencies,
...zcashCurrencies
].fold<Map<int, CryptoCurrency>>(<int, CryptoCurrency>{}, (acc, item) {
acc.addAll({item.raw: item});
return acc;
});

static final Map<String, CryptoCurrency> _nameCurrencyMap =
[...all, ...havenCurrencies, ...zcashCurrencies].fold<Map<String, CryptoCurrency>>(<String, CryptoCurrency>{}, (acc, item) {
static final Map<String, CryptoCurrency> _nameCurrencyMap = [
...all,
...havenCurrencies,
...zcashCurrencies
].fold<Map<String, CryptoCurrency>>(<String, CryptoCurrency>{}, (acc, item) {
acc.addAll({item.name: item});
return acc;
});

static final Map<String, CryptoCurrency> _fullNameCurrencyMap =
[...all, ...havenCurrencies, ...zcashCurrencies].fold<Map<String, CryptoCurrency>>(<String, CryptoCurrency>{}, (acc, item) {
static final Map<String, CryptoCurrency> _fullNameCurrencyMap = [
...all,
...havenCurrencies,
...zcashCurrencies
].fold<Map<String, CryptoCurrency>>(<String, CryptoCurrency>{}, (acc, item) {
if(item.fullName != null){
acc.addAll({item.fullName!.toLowerCase(): item});
}
Expand Down Expand Up @@ -321,10 +347,9 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
return _rawCurrencyMap[raw];
}


// TODO: refactor this
static CryptoCurrency fromString(String name, {CryptoCurrency? walletCurrency}) {

static CryptoCurrency fromString(String name,
{CryptoCurrency? walletCurrency}) {
final schemeMatch = _schemeCurrencyMap[name.toLowerCase()];
if (schemeMatch != null) return schemeMatch;

Expand All @@ -339,7 +364,8 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen

// search by fullName if not found by title:
try {
return CryptoCurrency.all.firstWhere((element) => element.fullName?.toLowerCase() == name);
return CryptoCurrency.all
.firstWhere((element) => element.fullName?.toLowerCase() == name);
} catch (_) {}

if (CryptoCurrency._nameCurrencyMap[name.toLowerCase()] == null) {
Expand All @@ -351,11 +377,14 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
}

static CryptoCurrency fromFullName(String name) {
if (CryptoCurrency._fullNameCurrencyMap[name.split("(").first.trim().toLowerCase()] == null) {
if (CryptoCurrency
._fullNameCurrencyMap[name.split("(").first.trim().toLowerCase()] ==
null) {
final s = 'Unexpected token: $name for CryptoCurrency fromFullName';
throw ArgumentError.value(name, 'Fullname', s);
}
return CryptoCurrency._fullNameCurrencyMap[name.split("(").first.trim().toLowerCase()]!;
return CryptoCurrency
._fullNameCurrencyMap[name.split("(").first.trim().toLowerCase()]!;
}

static CryptoCurrency? safeParseCurrencyFromString(
Expand All @@ -377,12 +406,12 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
return null;
}


// Try for native currency with same title and tag
if (tag == null || tag.isEmpty) {
final match = CryptoCurrency.all.firstWhereOrNull(
(e) =>
e.title.toUpperCase() == raw.toUpperCase() && (e.tag == raw.toUpperCase()),
e.title.toUpperCase() == raw.toUpperCase() &&
(e.tag == raw.toUpperCase()),
);

if (match != null) return match;
Expand All @@ -393,7 +422,8 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
} catch (_) {}

// try cleaned (keep only A–Z/0–9)
final cleaned = raw.trim().toUpperCase().replaceAll(RegExp(r'[^A-Z0-9]'), '');
final cleaned =
raw.trim().toUpperCase().replaceAll(RegExp(r'[^A-Z0-9]'), '');
try {
return CryptoCurrency.fromString(cleaned, walletCurrency: walletCurrency);
} catch (_) {}
Expand Down Expand Up @@ -427,11 +457,14 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
@override
String toString() => title;

bool titleAndTagEqual(CryptoCurrency other) => title == other.title && tag == other.tag;
bool titleAndTagEqual(CryptoCurrency other) =>
title == other.title && tag == other.tag;

/// Format the raw amount into its decimal representation eg. turn Sats into Bitcoin
String formatAmount(BigInt amount, {int? fractionalDigits, bool trimZeros = true}) =>
formatFixed(amount, decimals, fractionalDigits: fractionalDigits, trimZeros: trimZeros);
String formatAmount(BigInt amount,
{int? fractionalDigits, bool trimZeros = true}) =>
formatFixed(amount, decimals,
fractionalDigits: fractionalDigits, trimZeros: trimZeros);

/// Parse the [value] and turn it into the smallest denomination eg. turn Bitcoin into Sats
BigInt parseAmount(String value) => parseFixed(value, decimals);
Expand Down
2 changes: 2 additions & 0 deletions cw_core/lib/currency_for_wallet_type.dart
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ CryptoCurrency walletTypeToCryptoCurrency(WalletType type, {bool isTestnet = fal
return CryptoCurrency.doge;
case WalletType.zcash:
return CryptoCurrency.zec;
case WalletType.starknet:
return CryptoCurrency.strk;
case WalletType.none:
throw Exception(
'Unexpected wallet type: ${type.toString()} for CryptoCurrency walletTypeToCryptoCurrency');
Expand Down
2 changes: 2 additions & 0 deletions cw_core/lib/hardware/hardware_account_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ class HardwareAccountData {
required this.address,
required this.accountIndex,
required this.derivationPath,
this.publicKey,
this.xpub,
this.masterFingerprint,
});

final String address;
final int accountIndex;
final String derivationPath;
final String? publicKey;

// Bitcoin Specific
final Uint8List? masterFingerprint;
Expand Down
3 changes: 2 additions & 1 deletion cw_core/lib/hive_type_ids.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ const HARDWARE_WALLET_TYPE_TYPE_ID = 19;
const MWEB_UTXO_TYPE_ID = 20;
const HAVEN_SEED_STORE_TYPE_ID = 21;
const ZANO_ASSET_TYPE_ID = 22;
const PAYJOIN_SESSION_TYPE_ID = 23;
const PAYJOIN_SESSION_TYPE_ID = 23;
const STARKNET_TOKEN_TYPE_ID = 24;
Loading