implemented backend wallet service connection
Some checks failed
ci/woodpecker/push/chain_gateway Pipeline was successful
ci/woodpecker/push/billing_fees Pipeline was successful
ci/woodpecker/push/bff Pipeline was successful
ci/woodpecker/push/frontend Pipeline was successful
ci/woodpecker/push/db Pipeline was successful
ci/woodpecker/push/fx_ingestor Pipeline was successful
ci/woodpecker/push/fx_oracle Pipeline was successful
ci/woodpecker/push/nats Pipeline was successful
ci/woodpecker/push/ledger Pipeline was successful
ci/woodpecker/push/notification Pipeline was successful
ci/woodpecker/push/payments_orchestrator Pipeline was successful
ci/woodpecker/push/bump_version Pipeline failed

This commit is contained in:
Stephan D
2025-11-26 00:48:00 +01:00
parent 68f0a1048f
commit 48ccbb1c82
24 changed files with 420 additions and 37 deletions

View File

@@ -0,0 +1,16 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:pshared/data/dto/wallet/balance.dart';
part 'wallet_balance.g.dart';
@JsonSerializable(explicitToJson: true)
class WalletBalanceResponse {
final WalletBalanceDTO balance;
const WalletBalanceResponse({required this.balance});
factory WalletBalanceResponse.fromJson(Map<String, dynamic> json) => _$WalletBalanceResponseFromJson(json);
Map<String, dynamic> toJson() => _$WalletBalanceResponseToJson(this);
}

View File

@@ -0,0 +1,16 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:pshared/data/dto/wallet/wallet.dart';
part 'wallets.g.dart';
@JsonSerializable(explicitToJson: true)
class WalletsResponse {
final List<WalletDTO> wallets;
const WalletsResponse({required this.wallets});
factory WalletsResponse.fromJson(Map<String, dynamic> json) => _$WalletsResponseFromJson(json);
Map<String, dynamic> toJson() => _$WalletsResponseToJson(this);
}

View File

@@ -0,0 +1,20 @@
import 'package:json_annotation/json_annotation.dart';
part 'asset.g.dart';
@JsonSerializable()
class WalletAssetDTO {
final String chain;
final String tokenSymbol;
final String contractAddress;
const WalletAssetDTO({
required this.chain,
required this.tokenSymbol,
required this.contractAddress,
});
factory WalletAssetDTO.fromJson(Map<String, dynamic> json) => _$WalletAssetDTOFromJson(json);
Map<String, dynamic> toJson() => _$WalletAssetDTOToJson(this);
}

View File

@@ -0,0 +1,24 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:pshared/data/dto/wallet/money.dart';
part 'balance.g.dart';
@JsonSerializable()
class WalletBalanceDTO {
final MoneyDTO? available;
final MoneyDTO? pendingInbound;
final MoneyDTO? pendingOutbound;
final String? calculatedAt;
const WalletBalanceDTO({
required this.available,
required this.pendingInbound,
required this.pendingOutbound,
required this.calculatedAt,
});
factory WalletBalanceDTO.fromJson(Map<String, dynamic> json) => _$WalletBalanceDTOFromJson(json);
Map<String, dynamic> toJson() => _$WalletBalanceDTOToJson(this);
}

View File

@@ -0,0 +1,18 @@
import 'package:json_annotation/json_annotation.dart';
part 'money.g.dart';
@JsonSerializable()
class MoneyDTO {
final String amount;
final String currency;
const MoneyDTO({
required this.amount,
required this.currency,
});
factory MoneyDTO.fromJson(Map<String, dynamic> json) => _$MoneyDTOFromJson(json);
Map<String, dynamic> toJson() => _$MoneyDTOToJson(this);
}

View File

@@ -0,0 +1,34 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:pshared/data/dto/wallet/asset.dart';
part 'wallet.g.dart';
@JsonSerializable()
class WalletDTO {
final String walletRef;
final String organizationRef;
final String ownerRef;
final WalletAssetDTO asset;
final String depositAddress;
final String status;
final Map<String, String>? metadata;
final String? createdAt;
final String? updatedAt;
const WalletDTO({
required this.walletRef,
required this.organizationRef,
required this.ownerRef,
required this.asset,
required this.depositAddress,
required this.status,
this.metadata,
this.createdAt,
this.updatedAt,
});
factory WalletDTO.fromJson(Map<String, dynamic> json) => _$WalletDTOFromJson(json);
Map<String, dynamic> toJson() => _$WalletDTOToJson(this);
}

View File

@@ -0,0 +1,15 @@
import 'package:pshared/data/dto/wallet/balance.dart';
import 'package:pshared/data/mapper/wallet/money.dart';
import 'package:pshared/models/wallet/balance.dart';
extension WalletBalanceDTOMapper on WalletBalanceDTO {
WalletBalance toDomain() => WalletBalance(
available: available?.toDomain(),
pendingInbound: pendingInbound?.toDomain(),
pendingOutbound: pendingOutbound?.toDomain(),
calculatedAt: (calculatedAt == null || calculatedAt!.isEmpty)
? null
: DateTime.tryParse(calculatedAt!),
);
}

View File

@@ -0,0 +1,10 @@
import 'package:pshared/data/dto/wallet/money.dart';
import 'package:pshared/models/wallet/money.dart';
extension MoneyDTOMapper on MoneyDTO {
WalletMoney toDomain() => WalletMoney(
amount: amount,
currency: currency,
);
}

View File

@@ -0,0 +1,14 @@
import 'package:pshared/api/responses/wallet_balance.dart';
import 'package:pshared/api/responses/wallets.dart';
import 'package:pshared/data/mapper/wallet/balance.dart';
import 'package:pshared/data/mapper/wallet/wallet.dart';
import 'package:pshared/models/wallet/balance.dart';
import 'package:pshared/models/wallet/wallet.dart';
extension WalletsResponseMapper on WalletsResponse {
List<WalletModel> toDomain() => wallets.map((w) => w.toDomain()).toList();
}
extension WalletBalanceResponseMapper on WalletBalanceResponse {
WalletBalance toDomain() => balance.toDomain();
}

View File

@@ -0,0 +1,26 @@
import 'package:pshared/data/dto/wallet/balance.dart';
import 'package:pshared/data/dto/wallet/wallet.dart';
import 'package:pshared/data/mapper/wallet/balance.dart';
import 'package:pshared/data/mapper/wallet/money.dart';
import 'package:pshared/models/wallet/wallet.dart';
extension WalletDTOMapper on WalletDTO {
WalletModel toDomain({WalletBalanceDTO? balance}) => WalletModel(
walletRef: walletRef,
organizationRef: organizationRef,
ownerRef: ownerRef,
asset: WalletAsset(
chain: asset.chain,
tokenSymbol: asset.tokenSymbol,
contractAddress: asset.contractAddress,
),
depositAddress: depositAddress,
status: status,
metadata: metadata,
createdAt: (createdAt == null || createdAt!.isEmpty) ? null : DateTime.tryParse(createdAt!),
updatedAt: (updatedAt == null || updatedAt!.isEmpty) ? null : DateTime.tryParse(updatedAt!),
balance: balance?.toDomain(),
availableMoney: balance?.available?.toDomain(),
);
}

View File

@@ -0,0 +1,16 @@
import 'package:pshared/models/wallet/money.dart';
class WalletBalance {
final WalletMoney? available;
final WalletMoney? pendingInbound;
final WalletMoney? pendingOutbound;
final DateTime? calculatedAt;
const WalletBalance({
required this.available,
required this.pendingInbound,
required this.pendingOutbound,
required this.calculatedAt,
});
}

View File

@@ -0,0 +1,9 @@
class WalletMoney {
final String amount;
final String currency;
const WalletMoney({
required this.amount,
required this.currency,
});
}

View File

@@ -0,0 +1,62 @@
import 'package:pshared/models/wallet/balance.dart';
import 'package:pshared/models/wallet/money.dart';
class WalletAsset {
final String chain;
final String tokenSymbol;
final String contractAddress;
const WalletAsset({
required this.chain,
required this.tokenSymbol,
required this.contractAddress,
});
}
class WalletModel {
final String walletRef;
final String organizationRef;
final String ownerRef;
final WalletAsset asset;
final String depositAddress;
final String status;
final Map<String, String>? metadata;
final DateTime? createdAt;
final DateTime? updatedAt;
final WalletBalance? balance;
final WalletMoney? availableMoney;
const WalletModel({
required this.walletRef,
required this.organizationRef,
required this.ownerRef,
required this.asset,
required this.depositAddress,
required this.status,
this.metadata,
this.createdAt,
this.updatedAt,
this.balance,
this.availableMoney,
});
WalletModel copyWith({
WalletBalance? balance,
WalletMoney? availableMoney,
}) {
return WalletModel(
walletRef: walletRef,
organizationRef: organizationRef,
ownerRef: ownerRef,
asset: asset,
depositAddress: depositAddress,
status: status,
metadata: metadata,
createdAt: createdAt,
updatedAt: updatedAt,
balance: balance ?? this.balance,
availableMoney: availableMoney ?? this.availableMoney,
);
}
}

View File

@@ -7,6 +7,7 @@ class Services {
static const String organization = 'organizations';
static const String permission = 'permissions';
static const String storage = 'storage';
static const String chainWallets = 'chain_wallets';
static const String amplitude = 'amplitude';
static const String clients = 'clients';

View File

@@ -0,0 +1,31 @@
import 'package:pshared/api/responses/wallet_balance.dart';
import 'package:pshared/api/responses/wallets.dart';
import 'package:pshared/data/mapper/wallet/response.dart';
import 'package:pshared/models/wallet/balance.dart';
import 'package:pshared/models/wallet/wallet.dart';
import 'package:pshared/service/authorization/service.dart';
import 'package:pshared/service/services.dart';
class WalletService {
static const String _objectType = Services.chainWallets;
static Future<List<WalletModel>> list(String organizationRef) async {
final json = await AuthorizationService.getGETResponse(
_objectType,
'/$organizationRef',
);
return WalletsResponse.fromJson(json).toDomain();
}
static Future<WalletBalance> getBalance({
required String organizationRef,
required String walletRef,
}) async {
final json = await AuthorizationService.getGETResponse(
_objectType,
'/$organizationRef/$walletRef/balance',
);
return WalletBalanceResponse.fromJson(json).toDomain();
}
}