Skip to content
Closed
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
5 changes: 4 additions & 1 deletion lib/models/exchange/aggregate_currency.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
*
*/

import 'package:tuple/tuple.dart';

import '../isar/exchange_cache/currency.dart';
import '../isar/exchange_cache/pair.dart';
import 'package:tuple/tuple.dart';

class AggregateCurrency {
final Map<String, Currency?> _map = {};
Expand All @@ -29,6 +30,8 @@ class AggregateCurrency {
return _map[exchangeName];
}

String? networkFor(String exchangeName) => forExchange(exchangeName)?.network;

String get ticker => _map.values.first!.ticker;

String get name => _map.values.first!.name;
Expand Down
174 changes: 174 additions & 0 deletions lib/models/exchange/change_now/cn_exchange_transaction.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2025 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2025-04-26
*
*/

import 'package:decimal/decimal.dart';
import 'package:uuid/uuid.dart';

import 'cn_exchange_transaction_status.dart';

class CNExchangeTransaction {
/// The amount being sent from the user.
final Decimal fromAmount;

/// The amount the user will receive.
final Decimal toAmount;

/// The type of exchange flow. Either "standard" or "fixed-rate".
final String flow;

/// Direction of the exchange: "direct" or "reverse".
final String type;

/// The address to which the user sends the input currency.
final String payinAddress;

/// The address where the exchanged currency will be sent.
final String payoutAddress;

/// Extra ID for payout address (e.g., memo, tag). Empty string if not used.
final String payoutExtraId;

/// Currency ticker being exchanged from (e.g., "btc").
final String fromCurrency;

/// Currency ticker being exchanged to (e.g., "xmr").
final String toCurrency;

/// Refund address in case of failure or timeout.
final String refundAddress;

/// Extra ID for the refund address (if needed). Empty string if not used.
final String refundExtraId;

/// Deadline until which the estimated rate or transaction is valid.
final DateTime validUntil;

/// Date when transaction was created.
final DateTime date;

/// Unique transaction identifier.
final String id;

/// The user-defined or system-determined amount in a "directed" flow.
final Decimal? directedAmount;

/// Network of the currency being sent.
final String fromNetwork;

/// Network of the currency being received.
final String toNetwork;

final String uuid;

final CNExchangeTransactionStatus? statusObject;

const CNExchangeTransaction({
required this.fromAmount,
required this.toAmount,
required this.flow,
required this.type,
required this.payinAddress,
required this.payoutAddress,
required this.payoutExtraId,
required this.fromCurrency,
required this.toCurrency,
required this.refundAddress,
required this.refundExtraId,
required this.validUntil,
required this.date,
required this.id,
required this.directedAmount,
required this.fromNetwork,
required this.toNetwork,
required this.uuid,
this.statusObject,
});

factory CNExchangeTransaction.fromJson(Map<String, dynamic> json) {
return CNExchangeTransaction(
fromAmount: Decimal.parse(json["fromAmount"].toString()),
toAmount: Decimal.parse(json["toAmount"].toString()),
flow: json["flow"] as String,
type: json["type"] as String,
payinAddress: json["payinAddress"] as String,
payoutAddress: json["payoutAddress"] as String,
payoutExtraId: json["payoutExtraId"] as String? ?? "",
fromCurrency: json["fromCurrency"] as String,
toCurrency: json["toCurrency"] as String,
refundAddress: json["refundAddress"] as String,
refundExtraId: json["refundExtraId"] as String,
validUntil: DateTime.parse(json["validUntil"] as String),
date: DateTime.parse(json["date"] as String),
id: json["id"] as String,
directedAmount: Decimal.tryParse(json["directedAmount"].toString()),
fromNetwork: json["fromNetwork"] as String? ?? "",
toNetwork: json["toNetwork"] as String? ?? "",
uuid: json["uuid"] as String? ?? const Uuid().v1(),
statusObject:
json["statusObject"] is Map<String, dynamic>
? CNExchangeTransactionStatus.fromMap(
json["statusObject"] as Map<String, dynamic>,
)
: null,
);
}

Map<String, dynamic> toMap() {
return {
"fromAmount": fromAmount,
"toAmount": toAmount,
"flow": flow,
"type": type,
"payinAddress": payinAddress,
"payoutAddress": payoutAddress,
"payoutExtraId": payoutExtraId,
"fromCurrency": fromCurrency,
"toCurrency": toCurrency,
"refundAddress": refundAddress,
"refundExtraId": refundExtraId,
"validUntil": validUntil.toIso8601String(),
"date": date.toIso8601String(),
"id": id,
"directedAmount": directedAmount,
"fromNetwork": fromNetwork,
"uuid": uuid,
"statusObject": statusObject?.toMap(),
};
}

CNExchangeTransaction copyWithStatus(CNExchangeTransactionStatus? status) {
return CNExchangeTransaction(
fromAmount: fromAmount,
toAmount: toAmount,
flow: flow,
type: type,
payinAddress: payinAddress,
payoutAddress: payoutAddress,
payoutExtraId: payoutExtraId,
fromCurrency: fromCurrency,
toCurrency: toCurrency,
refundAddress: refundAddress,
refundExtraId: refundExtraId,
validUntil: validUntil,
date: date,
id: id,
directedAmount: directedAmount,
fromNetwork: fromNetwork,
toNetwork: toNetwork,
uuid: uuid,
statusObject: status,
);
}

@override
String toString() {
return "CNExchangeTransaction: ${toMap()}";
}
}
172 changes: 172 additions & 0 deletions lib/models/exchange/change_now/cn_exchange_transaction_status.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
import 'package:decimal/decimal.dart';

enum ChangeNowTransactionStatus {
New,
Waiting,
Confirming,
Exchanging,
Sending,
Finished,
Failed,
Refunded,
Verifying,
}

extension ChangeNowTransactionStatusExt on ChangeNowTransactionStatus {
String get lowerCaseName => name.toLowerCase();
}

ChangeNowTransactionStatus changeNowTransactionStatusFromStringIgnoreCase(
String string,
) {
for (final value in ChangeNowTransactionStatus.values) {
if (value.lowerCaseName == string.toLowerCase()) {
return value;
}
}
throw ArgumentError(
"String value does not match any known ChangeNowTransactionStatus",
);
}

class CNExchangeTransactionStatus {
final String id;
final ChangeNowTransactionStatus status;
final bool actionsAvailable;
final String fromCurrency;
final String fromNetwork;
final String toCurrency;
final String toNetwork;
final String? expectedAmountFrom;
final String? expectedAmountTo;
final String? amountFrom;
final String? amountTo;
final String payinAddress;
final String payoutAddress;
final String? payinExtraId;
final String? payoutExtraId;
final String? refundAddress;
final String? refundExtraId;
final String createdAt;
final String updatedAt;
final String? depositReceivedAt;
final String? payinHash;
final String? payoutHash;
final String fromLegacyTicker;
final String toLegacyTicker;
final String? refundHash;
final String? refundAmount;
final int? userId;
final String? validUntil;

const CNExchangeTransactionStatus({
required this.id,
required this.status,
required this.actionsAvailable,
required this.fromCurrency,
required this.fromNetwork,
required this.toCurrency,
required this.toNetwork,
this.expectedAmountFrom,
this.expectedAmountTo,
this.amountFrom,
this.amountTo,
required this.payinAddress,
required this.payoutAddress,
this.payinExtraId,
this.payoutExtraId,
this.refundAddress,
this.refundExtraId,
required this.createdAt,
required this.updatedAt,
this.depositReceivedAt,
this.payinHash,
this.payoutHash,
required this.fromLegacyTicker,
required this.toLegacyTicker,
this.refundHash,
this.refundAmount,
this.userId,
this.validUntil,
});

factory CNExchangeTransactionStatus.fromMap(Map<String, dynamic> map) {
return CNExchangeTransactionStatus(
id: map["id"] as String,
status: changeNowTransactionStatusFromStringIgnoreCase(
map["status"] as String,
),
actionsAvailable: map["actionsAvailable"] as bool,
fromCurrency: map["fromCurrency"] as String? ?? "",
fromNetwork: map["fromNetwork"] as String? ?? "",
toCurrency: map["toCurrency"] as String? ?? "",
toNetwork: map["toNetwork"] as String? ?? "",
expectedAmountFrom: _get(map["expectedAmountFrom"]),
expectedAmountTo: _get(map["expectedAmountTo"]),
amountFrom: _get(map["amountFrom"]),
amountTo: _get(map["amountTo"]),
payinAddress: map["payinAddress"] as String? ?? "",
payoutAddress: map["payoutAddress"] as String? ?? "",
payinExtraId: map["payinExtraId"] as String?,
payoutExtraId: map["payoutExtraId"] as String?,
refundAddress: map["refundAddress"] as String?,
refundExtraId: map["refundExtraId"] as String?,
createdAt: map["createdAt"] as String? ?? "",
updatedAt: map["updatedAt"] as String? ?? "",
depositReceivedAt: map["depositReceivedAt"] as String?,
payinHash: map["payinHash"] as String?,
payoutHash: map["payoutHash"] as String?,
fromLegacyTicker: map["fromLegacyTicker"] as String? ?? "",
toLegacyTicker: map["toLegacyTicker"] as String? ?? "",
refundHash: map["refundHash"] as String?,
refundAmount: _get(map["refundAmount"]),
userId:
map["userId"] is int
? map["userId"] as int
: int.tryParse(map["userId"].toString()),
validUntil: map["validUntil"] as String?,
);
}

Map<String, dynamic> toMap() {
return {
"id": id,
"status": status,
"actionsAvailable": actionsAvailable,
"fromCurrency": fromCurrency,
"fromNetwork": fromNetwork,
"toCurrency": toCurrency,
"toNetwork": toNetwork,
"expectedAmountFrom": expectedAmountFrom,
"expectedAmountTo": expectedAmountTo,
"amountFrom": amountFrom,
"amountTo": amountTo,
"payinAddress": payinAddress,
"payoutAddress": payoutAddress,
"payinExtraId": payinExtraId,
"payoutExtraId": payoutExtraId,
"refundAddress": refundAddress,
"refundExtraId": refundExtraId,
"createdAt": createdAt,
"updatedAt": updatedAt,
"depositReceivedAt": depositReceivedAt,
"payinHash": payinHash,
"payoutHash": payoutHash,
"fromLegacyTicker": fromLegacyTicker,
"toLegacyTicker": toLegacyTicker,
"refundHash": refundHash,
"refundAmount": refundAmount,
"userId": userId,
"validUntil": validUntil,
};
}

static String? _get(dynamic value) {
if (value is String) return value;
if (value is num) return Decimal.tryParse(value.toString())?.toString();
return null;
}

@override
String toString() => "CNExchangeTransactionStatus: ${toMap()}";
}
Loading
Loading