Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
45bb288
fix: show token ticker in DesktopAuthSend prompt
sneurlax Mar 1, 2026
dd8be53
fix: ordinals by looking up tx info directly
sneurlax Mar 1, 2026
dceae42
fix: use tor for ordinal image preview
sneurlax Mar 1, 2026
8b82eb1
fix: checkBlockUTXO only checking the specific UTXO output
sneurlax Mar 1, 2026
42e8cec
fix: witness field parsing in particl updateTransactions
sneurlax Mar 1, 2026
7cb913c
fix: particl transactionVersion property to return 160
sneurlax Mar 1, 2026
933d268
fix: temp input script index in particl buildTransaction
sneurlax Mar 1, 2026
ed5a671
fix(mwc): serialize openWallet FFI calls with mutex
sneurlax Mar 1, 2026
00b95a0
fix: check isOnline before offlineMode in Xelis exit()
sneurlax Mar 1, 2026
63aa9ef
feat: add prepareOrdinalSend to ordinals interface
sneurlax Mar 3, 2026
c18ff61
feat: add ordinal send dialogs with desktop variants
sneurlax Mar 3, 2026
5a9ebe2
feat: wire up send button in mobile ordinal details
sneurlax Mar 3, 2026
54d21e9
feat: wire up send button in desktop ordinal details
sneurlax Mar 3, 2026
e673f61
feat: add ordinal spend warning to confirm transaction view
sneurlax Mar 3, 2026
1e5cf6e
feat: never peg ordinals into MWEB
sneurlax Mar 3, 2026
b3d5017
fix: Particl wallet P2PKH signing and checkBlockUTXO cast
sneurlax Mar 3, 2026
ea7c0d5
feat: update cypherstack/bitcoindart to point to fix/particl off master
sneurlax Mar 3, 2026
6fca0f1
feat: use token ticker in confirm send dialog if it's available
sneurlax Mar 3, 2026
b66fbd9
fix(mwc): write .api_secret for default node authentication
sneurlax Mar 3, 2026
de5f097
refactor(mwc): merge flutter_libmwc#fix/global-chain-type-race
sneurlax Mar 3, 2026
ce46d2f
fix: show error screen instead of black screen when second instance l…
sneurlax Mar 3, 2026
f4ff1fd
fix: show themed error screen when second instance tries to start
sneurlax Mar 3, 2026
825acf1
fix: PayNym following list serialization bug
sneurlax Mar 2, 2026
a4b97e8
fix: _getLastAutoBackup() reading from wrong Hive key
sneurlax Mar 2, 2026
bf91d82
Merge branch 'fix/ordinals' into vacay
sneurlax Mar 6, 2026
170bec8
fix(solana): fix incorrect default Solana token mint addresses
sneurlax Mar 19, 2026
337a24f
fix(solana): fix Solana token tx parsing to handle plain "transfer" type
sneurlax Mar 19, 2026
b22b047
feat(shopinbit): add ShopInBit API data models
sneurlax Feb 23, 2026
14983c1
feat(shopinbit): add ShopInBit API client and service layer
sneurlax Feb 24, 2026
afe46d6
feat(shopinbit): add ShopInBit data models and DB schema
sneurlax Feb 24, 2026
fad4d54
feat(shopinbit): add Services and Gift Cards content pages with routes
sneurlax Mar 20, 2026
c9f7808
feat(shopinbit): add ShopInBit order creation flow (steps 1-4)
sneurlax Feb 25, 2026
f3f6f42
feat(shopinbit): add ShopInBit ticket management views
sneurlax Feb 26, 2026
61d7311
feat(shopinbit): add ShopInBit offer review and shipping address views
sneurlax Feb 26, 2026
ef51421
feat(shopinbit): add ShopInBit confirm send views
sneurlax Feb 26, 2026
4958bfd
fix(particl): override bitcoindart in order to resolve dependency issue
sneurlax Mar 24, 2026
2b9ca8c
docs: update docs re: new lld dep since flutter 3.38
sneurlax Mar 24, 2026
5dd79a4
Merge branch 'fix/particl' into vacay
sneurlax Mar 24, 2026
eb46365
Merge remote-tracking branch 'origin/feat/handle-multiple-instances' …
sneurlax Mar 24, 2026
f58eccf
Merge remote-tracking branch 'origin/fix/mwc' into vacay
sneurlax Mar 24, 2026
757cccc
Merge remote-tracking branch 'origin/fix/xelis' into vacay
sneurlax Mar 24, 2026
248f0b1
Merge remote-tracking branch 'origin/fix/paynym-following-serializati…
sneurlax Mar 24, 2026
bdf2e73
Merge remote-tracking branch 'origin/fix/306-auto-backup-prefs-key' i…
sneurlax Mar 24, 2026
85cf8ae
Merge branch 'fix/solana-tokens' into vacay
sneurlax Mar 24, 2026
3627613
Merge remote-tracking branch 'origin/fix/desktop-auth-send-token-tick…
sneurlax Mar 24, 2026
f8a49f8
feat: allow toast clickthru: replace route-based toast w passive Overlay
sneurlax Apr 6, 2026
98d8136
Merge branch 'feat/clickthru-toast' into vacay
sneurlax Apr 6, 2026
5b1c8e5
feat(shopinbit): add Services main menu item on desktop
sneurlax Apr 6, 2026
0582da4
feat(shopinbit): add ShopInBit More menu item on mobile
sneurlax Mar 18, 2026
46e3553
feat(shopinbit): add ShopInBit payment and send-from views
sneurlax Feb 28, 2026
b01e678
feat(shopinbit): add ShopInBit debug tools to hidden settings
sneurlax Feb 28, 2026
0f3090a
feat(shopinbit): add ShopInBit settings page
sneurlax Feb 28, 2026
fa75f9c
feat(shopinbit): better ShopInBit settings page on mobile
sneurlax Feb 28, 2026
2b94ddc
fix(shopinbit): fix ShopInbit USDT payments
sneurlax Feb 28, 2026
14d970f
fix(shopinbit): ShopInBit confirm/send navigation and display fixes
sneurlax Mar 1, 2026
038e108
fix: remove tokenTicker param from DesktopAuthSend call
sneurlax Mar 1, 2026
b92a842
fix(shopinbit): don't pass auth for countries endpoint
sneurlax Mar 18, 2026
bbf566e
feat(shopinbit): create DesktopServicesView container
sneurlax Apr 6, 2026
45e391c
feat(shopinbit): register DesktopServicesView route and wire into home
sneurlax Apr 6, 2026
46efe4e
fix(shopinbit): disable cakepay for now
sneurlax Apr 6, 2026
9f2f447
fix(shopinbit): fix nav
sneurlax Apr 7, 2026
56c53fb
fix(shopinbit): various shopinbit ui fixes
sneurlax Apr 7, 2026
69e3b8a
Merge branch 'feat/shopinbit' into vacay
sneurlax Apr 8, 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
2 changes: 1 addition & 1 deletion crypto_plugins/flutter_libmwc
4 changes: 2 additions & 2 deletions docs/building.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386 lib32z1 libbz2-
### Build dependencies
Install basic dependencies
```
sudo apt-get install libssl-dev curl unzip automake build-essential file pkg-config git python3 libtool libtinfo6 cmake libgit2-dev clang libncurses5-dev libncursesw5-dev zlib1g-dev llvm g++ gcc gperf libopencv-dev python3-typogrify xsltproc valac gobject-introspection meson
sudo apt-get install libssl-dev curl unzip automake build-essential file pkg-config git python3 libtool libtinfo6 cmake libgit2-dev clang libncurses5-dev libncursesw5-dev zlib1g-dev llvm lld g++ gcc gperf libopencv-dev python3-typogrify xsltproc valac gobject-introspection meson
```

For Ubuntu 20.04,
Expand Down Expand Up @@ -75,7 +75,7 @@ rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-andro

Linux desktop specific dependencies:
```
sudo apt-get install clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev meson python3-pip libgirepository1.0-dev valac xsltproc docbook-xsl
sudo apt-get install clang cmake lld ninja-build pkg-config libgtk-3-dev liblzma-dev meson python3-pip libgirepository1.0-dev valac xsltproc docbook-xsl
pip3 install --upgrade meson==0.64.1 markdown==3.4.1 markupsafe==2.1.1 jinja2==3.1.2 pygments==2.13.0 toml==0.10.2 typogrify==2.0.7 tomli==2.0.1
```

Expand Down
27 changes: 27 additions & 0 deletions lib/db/isar/main_db.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class MainDB {
TokenWalletInfoSchema,
FrostWalletInfoSchema,
WalletSolanaTokenInfoSchema,
ShopInBitTicketSchema,
],
directory: (await StackFileSystem.applicationIsarDirectory()).path,
// inspector: kDebugMode,
Expand Down Expand Up @@ -645,4 +646,30 @@ class MainDB {
isar.writeTxn(() async {
await isar.solContracts.putAll(tokens);
});

// ========== ShopInBit tickets ===============================================

List<ShopInBitTicket> getShopInBitTickets() {
return isar.shopInBitTickets.where().sortByCreatedAtDesc().findAllSync();
}

Future<int> putShopInBitTicket(ShopInBitTicket ticket) async {
try {
return await isar.writeTxn(() async {
return await isar.shopInBitTickets.put(ticket);
});
} catch (e) {
throw MainDBException("failed putShopInBitTicket", e);
}
}

Future<bool> deleteShopInBitTicket(String ticketId) async {
try {
return await isar.writeTxn(() async {
return await isar.shopInBitTickets.deleteByTicketId(ticketId);
});
} catch (e) {
throw MainDBException("failed deleteShopInBitTicket: $ticketId", e);
}
}
}
38 changes: 38 additions & 0 deletions lib/dto/ordinals/inscription_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,44 @@ class InscriptionData {
);
}

/// Parse the response from an ord server's /inscription/{id} endpoint.
/// [contentUrl] should be pre-built as `$baseUrl/content/$inscriptionId`.
factory InscriptionData.fromOrdJson(
Map<String, dynamic> json,
String contentUrl,
) {
final inscriptionId = json['inscription_id'] as String;
final satpoint = json['satpoint'] as String? ?? '';
// satpoint format: "txid:vout:offset"
final satpointParts = satpoint.split(':');
if (satpointParts.length < 2 || satpointParts[0].isEmpty) {
throw FormatException(
'Invalid satpoint for inscription $inscriptionId: "$satpoint"',
);
}
final output = '${satpointParts[0]}:${satpointParts[1]}';
final offset = satpointParts.length >= 3
? int.tryParse(satpointParts[2]) ?? 0
: 0;

return InscriptionData(
inscriptionId: inscriptionId,
inscriptionNumber: json['inscription_number'] as int? ?? 0,
address: json['address'] as String? ?? '',
preview: contentUrl,
content: contentUrl,
contentLength: json['content_length'] as int? ?? 0,
contentType: json['content_type'] as String? ?? '',
contentBody: '',
timestamp: json['timestamp'] as int? ?? 0,
genesisTransaction: inscriptionId.split('i').first,
location: satpoint,
output: output,
outputValue: json['output_value'] as int? ?? 0,
offset: offset,
);
}

@override
String toString() {
return 'InscriptionData {'
Expand Down
54 changes: 52 additions & 2 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import 'models/models.dart';
import 'models/node_model.dart';
import 'models/notification_model.dart';
import 'models/trade_wallet_lookup.dart';
import 'pages/already_running_view.dart';
import 'pages/campfire_migrate_view.dart';
import 'pages/home_view/home_view.dart';
import 'pages/intro_view.dart';
Expand Down Expand Up @@ -178,8 +179,57 @@ void main(List<String> args) async {
(await StackFileSystem.applicationHiveDirectory()).path,
);

await DB.instance.hive.openBox<dynamic>(DB.boxNameDBInfo);
await DB.instance.hive.openBox<dynamic>(DB.boxNamePrefs);
try {
await DB.instance.hive.openBox<dynamic>(DB.boxNameDBInfo);
await DB.instance.hive.openBox<dynamic>(DB.boxNamePrefs);
} on FileSystemException catch (e) {
if (e.osError?.errorCode == 11 || e.message.contains('lock failed')) {
// Another instance already holds the Hive database lock.
// Try to bootstrap just enough of the theme system (Isar is independent
// of Hive) so the error screen looks like a real Stack Wallet screen.
Widget errorApp;
try {
await StackFileSystem.initThemesDir();
await MainDB.instance.initMainDB();
ThemeService.instance.init(MainDB.instance);
errorApp = const ProviderScope(child: AlreadyRunningApp());
} catch (_) {
// Isar is also unavailable (e.g., another error). Fall back to a
// minimal but still Inter-font styled screen.
errorApp = MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(fontFamily: GoogleFonts.inter().fontFamily),
home: Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
AppConfig.appName,
textAlign: TextAlign.center,
style: GoogleFonts.inter(
fontSize: 20,
fontWeight: FontWeight.w600,
),
),
const SizedBox(height: 8),
Text(
'is already running.\n'
'Close the other window and try again.',
textAlign: TextAlign.center,
style: GoogleFonts.inter(fontSize: 16),
),
],
),
),
),
);
}
runApp(errorApp);
return;
}
rethrow;
}
await Prefs.instance.init();

await Logging.instance.initialize(
Expand Down
1 change: 1 addition & 0 deletions lib/models/isar/models/isar_models.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ export 'blockchain_data/utxo.dart';
export 'ethereum/eth_contract.dart';
export 'log.dart';
export 'solana/sol_contract.dart';
export 'shopinbit_ticket.dart';
export 'transaction_note.dart';
export '../../../wallets/isar/models/wallet_solana_token_info.dart';
41 changes: 41 additions & 0 deletions lib/models/isar/models/shopinbit_ticket.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import 'package:isar_community/isar.dart';

import '../../shopinbit/shopinbit_order_model.dart';

part 'shopinbit_ticket.g.dart';

@collection
class ShopInBitTicket {
Id id = Isar.autoIncrement;

@Index(unique: true, replace: true)
late String ticketId;

late String displayName;
@enumerated
late ShopInBitCategory category;
@enumerated
late ShopInBitOrderStatus status;
late String requestDescription;
late String deliveryCountry;
late String? offerProductName;
late String? offerPrice;
late String shippingName;
late String shippingStreet;
late String shippingCity;
late String shippingPostalCode;
late String shippingCountry;
late String? paymentMethod;
late List<ShopInBitTicketMessage> messages;
late DateTime createdAt;
late int apiTicketId;
}

@embedded
class ShopInBitTicketMessage {
late String text;
late DateTime timestamp;
late bool isFromUser;

ShopInBitTicketMessage();
}
Loading
Loading