withdraw_coin_option.dart 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /// 提现支持币种 — POST uc/withdraw/support/coin/info
  2. class SupportCoinInfo {
  3. final String unit;
  4. final String? aliasName;
  5. final String? nameCn;
  6. final String? name;
  7. final String? balance;
  8. final String minWithdrawAmount;
  9. final String? minAmount;
  10. final String? minTransferAmount;
  11. final String? withdrawFeeValue;
  12. final String? fee;
  13. const SupportCoinInfo({
  14. required this.unit,
  15. this.aliasName,
  16. this.nameCn,
  17. this.name,
  18. this.balance,
  19. this.minWithdrawAmount = '0',
  20. this.minAmount,
  21. this.minTransferAmount,
  22. this.withdrawFeeValue,
  23. this.fee,
  24. });
  25. factory SupportCoinInfo.fromJson(Map<String, dynamic> json) {
  26. return SupportCoinInfo(
  27. unit: json['unit']?.toString() ?? '',
  28. aliasName: json['aliasName']?.toString(),
  29. nameCn: json['nameCn']?.toString(),
  30. name: json['name']?.toString(),
  31. balance: json['balance']?.toString(),
  32. minWithdrawAmount: json['minWithdrawAmount']?.toString() ?? '0',
  33. minAmount: json['minAmount']?.toString(),
  34. minTransferAmount: json['minTransferAmount']?.toString(),
  35. withdrawFeeValue: json['withdrawFeeValue']?.toString(),
  36. fee: json['fee']?.toString(),
  37. );
  38. }
  39. }
  40. /// 提币主网 — GET uc/coin-network/withdraw-networks
  41. class WithdrawNetworkItem {
  42. final int id;
  43. final String name;
  44. final String protocol;
  45. final int sort;
  46. const WithdrawNetworkItem({
  47. required this.id,
  48. required this.name,
  49. required this.protocol,
  50. this.sort = 0,
  51. });
  52. factory WithdrawNetworkItem.fromJson(Map<String, dynamic> json) {
  53. return WithdrawNetworkItem(
  54. id: int.tryParse(json['id']?.toString() ?? '') ?? 0,
  55. name: json['name']?.toString() ?? '',
  56. protocol: json['protocol']?.toString() ?? '',
  57. sort: int.tryParse(json['sort']?.toString() ?? '') ?? 0,
  58. );
  59. }
  60. }
  61. /// 可提/可转币种选项(链上子币或内部转账主币)
  62. class WithdrawCoinOption {
  63. final String unit;
  64. final String displayName;
  65. final String networkLabel;
  66. final int? networkId;
  67. final String balance;
  68. final String minWithdraw;
  69. final String minTransfer;
  70. final String withdrawFee;
  71. final bool isUsdtFamily;
  72. final bool isMainCoin;
  73. const WithdrawCoinOption({
  74. required this.unit,
  75. required this.displayName,
  76. this.networkLabel = '',
  77. this.networkId,
  78. this.balance = '0',
  79. this.minWithdraw = '0',
  80. this.minTransfer = '0',
  81. this.withdrawFee = '0',
  82. this.isUsdtFamily = false,
  83. this.isMainCoin = false,
  84. });
  85. }
  86. String firstNonEmptyStr(List<Object?> vals) {
  87. for (final v in vals) {
  88. if (v == null) {
  89. continue;
  90. }
  91. final s = v.toString().trim();
  92. if (s.isNotEmpty) {
  93. return s;
  94. }
  95. }
  96. return '';
  97. }
  98. bool isUsdtFamilyUnit(String unit) {
  99. final u = unit.toUpperCase();
  100. return u == 'USDT' ||
  101. u == 'EUSDT' ||
  102. u == 'TUSDT' ||
  103. u.contains('BEP20');
  104. }
  105. Map<String, SupportCoinInfo> supportInfoByUnit(List<SupportCoinInfo> list) {
  106. final map = <String, SupportCoinInfo>{};
  107. for (final c in list) {
  108. final u = c.unit.toLowerCase();
  109. if (u.isNotEmpty) {
  110. map[u] = c;
  111. }
  112. }
  113. return map;
  114. }
  115. WithdrawCoinOption mapTransferParent(
  116. Map<String, dynamic> row,
  117. Map<String, SupportCoinInfo> supportMap,
  118. ) {
  119. final unit = firstNonEmptyStr([row['unit']]).toLowerCase();
  120. final name = row['name']?.toString() ?? '';
  121. final support = supportMap[unit] ?? supportMap[name.toLowerCase()];
  122. final minFromCoin = firstNonEmptyStr([row['minWithdrawAmount']]);
  123. final minFromSupport = firstNonEmptyStr([
  124. support?.minAmount,
  125. support?.minWithdrawAmount,
  126. support?.minTransferAmount,
  127. ]);
  128. return WithdrawCoinOption(
  129. unit: unit,
  130. displayName: firstNonEmptyStr([
  131. row['nameCn'],
  132. support?.nameCn,
  133. support?.aliasName,
  134. name,
  135. ]).isNotEmpty
  136. ? firstNonEmptyStr([
  137. row['nameCn'],
  138. support?.nameCn,
  139. support?.aliasName,
  140. name,
  141. ])
  142. : unit.toUpperCase(),
  143. balance: firstNonEmptyStr([support?.balance, '0']),
  144. minWithdraw: minFromSupport.isNotEmpty ? minFromSupport : minFromCoin,
  145. minTransfer: firstNonEmptyStr([
  146. support?.minTransferAmount,
  147. support?.minAmount,
  148. minFromSupport,
  149. minFromCoin,
  150. ]),
  151. withdrawFee: firstNonEmptyStr([
  152. support?.withdrawFeeValue,
  153. support?.fee,
  154. row['withdrawFeeValue'],
  155. ]),
  156. isUsdtFamily: isUsdtFamilyUnit(unit),
  157. isMainCoin: true,
  158. );
  159. }
  160. WithdrawCoinOption mapWithdrawConfigFromDb(
  161. Map<String, dynamic> row,
  162. Map<String, SupportCoinInfo> supportMap,
  163. ) {
  164. final unit = firstNonEmptyStr([row['unit']]).toLowerCase();
  165. final coinName = row['coinName']?.toString() ?? '';
  166. final support = supportMap[unit] ?? supportMap[coinName.toLowerCase()];
  167. final networkName = row['networkName']?.toString() ?? '';
  168. final minFromDb = firstNonEmptyStr([row['minWithdrawAmount'], row['minAmount']]);
  169. final minFromSupport =
  170. firstNonEmptyStr([support?.minAmount, support?.minWithdrawAmount]);
  171. return WithdrawCoinOption(
  172. unit: unit,
  173. displayName: firstNonEmptyStr([
  174. row['coinNameCn'],
  175. support?.nameCn,
  176. support?.aliasName,
  177. coinName,
  178. ]).isNotEmpty
  179. ? firstNonEmptyStr([
  180. row['coinNameCn'],
  181. support?.nameCn,
  182. support?.aliasName,
  183. coinName,
  184. ])
  185. : unit.toUpperCase(),
  186. networkLabel: networkName,
  187. networkId: int.tryParse(row['networkId']?.toString() ?? '') ?? 0,
  188. balance: firstNonEmptyStr([support?.balance, '0']),
  189. minWithdraw: minFromSupport.isNotEmpty ? minFromSupport : minFromDb,
  190. minTransfer: firstNonEmptyStr([
  191. support?.minTransferAmount,
  192. support?.minAmount,
  193. minFromSupport,
  194. ]),
  195. withdrawFee: firstNonEmptyStr([
  196. support?.withdrawFeeValue,
  197. support?.fee,
  198. row['withdrawFeeValue'],
  199. ]),
  200. isUsdtFamily: isUsdtFamilyUnit(unit),
  201. isMainCoin: false,
  202. );
  203. }
  204. String symbolForWithdrawCoin(WithdrawCoinOption? coin) {
  205. if (coin == null) {
  206. return 'USDT';
  207. }
  208. if (coin.isMainCoin && coin.unit.toUpperCase() == 'USDT') {
  209. return 'USDT';
  210. }
  211. if (coin.isUsdtFamily &&
  212. coin.networkLabel.isNotEmpty &&
  213. coin.unit.toUpperCase() != 'USDT') {
  214. return '${coin.displayName} (${coin.unit.toUpperCase()})';
  215. }
  216. return coin.displayName.isNotEmpty ? coin.displayName : coin.unit.toUpperCase();
  217. }
  218. const networkWithdrawDefaults = <String, ({String fee, String min})>{
  219. 'TRC20': (fee: '1', min: '10'),
  220. 'ERC20': (fee: '5', min: '20'),
  221. 'BEP20': (fee: '2', min: '10'),
  222. };