YSShop.dart 75 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643
  1. import 'dart:math';
  2. import 'dart:typed_data';
  3. import 'package:flutter/cupertino.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:flutter_wallet/generated/l10n.dart';
  6. import 'package:flutter_wallet/shop/YSCrossRecord.dart';
  7. import 'package:flutter_wallet/shop/view/YSExchangeRecordListItemView.dart';
  8. import 'package:flutter_wallet/shop/view/YSShopListItemView.dart';
  9. import 'package:flutter_wallet/tools/YSRefrehLoad.dart';
  10. import 'package:skeletons/skeletons.dart';
  11. import 'package:web3dart/crypto.dart';
  12. import 'package:web3dart/web3dart.dart';
  13. import '../login/view/YSHelpView.dart';
  14. import '../tools/YSAes.dart';
  15. import '../tools/YSAlertView.dart';
  16. import '../tools/YSBip2.dart';
  17. import '../tools/YSColors.dart';
  18. import '../tools/YSNetWork.dart';
  19. import '../tools/YSTools.dart';
  20. import 'package:http/http.dart';
  21. import '../tools/YSTron.dart';
  22. class YSShop extends StatefulWidget {
  23. const YSShop({Key? key}) : super(key: key);
  24. @override
  25. YSShopState createState() => YSShopState();
  26. }
  27. class YSShopState extends State<YSShop> {//with AutomaticKeepAliveClientMixin
  28. final List _titleArray = [
  29. {'type':1,'title':S.current.DUIHUAN},
  30. {'type':2,'title':S.current.KUALIAN},
  31. {'type':3,'title':S.current.HANGQING}
  32. ];
  33. int _titleIndex = 1;
  34. @override
  35. Widget build(BuildContext context) {
  36. // super.build(context);
  37. int type = _titleArray[_titleIndex]['type'];
  38. return Scaffold(
  39. backgroundColor: YSColors.backgroundColor(context),
  40. body: SingleChildScrollView(
  41. child: SizedBox(
  42. width: ysWidth(context),
  43. height: ysHeight(context)-ystabBarHeight,
  44. child: Skeleton(
  45. isLoading: false,
  46. skeleton: Column(
  47. children: [
  48. SkeletonAvatar(
  49. style: SkeletonAvatarStyle(
  50. width: double.infinity,
  51. height: hsp(90)
  52. ),
  53. ),
  54. Padding(
  55. padding: EdgeInsets.all(hsp(20)),
  56. child: SkeletonAvatar(
  57. style: SkeletonAvatarStyle(
  58. width: double.infinity,
  59. height: hsp(200)
  60. ),
  61. ),
  62. ),
  63. Container(
  64. height: hsp(25),
  65. margin: EdgeInsets.only(left: hsp(20),right: hsp(20)),
  66. child: ListView.separated(
  67. itemBuilder: (context,index){
  68. return SkeletonAvatar( style: SkeletonAvatarStyle(width: (ysWidth(context)-hsp(130))/4, height: 25,borderRadius: const BorderRadius.all(Radius.circular(50))));
  69. },
  70. separatorBuilder: (context,index){
  71. return Container(width: hsp(30),);
  72. },
  73. itemCount: 4,
  74. scrollDirection: Axis.horizontal,
  75. ),
  76. ),
  77. Padding(
  78. padding: EdgeInsets.only(top: hsp(20)),
  79. child: SkeletonAvatar( style: SkeletonAvatarStyle(width: ysWidth(context)-hsp(40), height: hsp(50)))
  80. )
  81. ],
  82. ),
  83. child: Stack(
  84. children: [
  85. // const YSHeadView(),
  86. Container(
  87. height: hsp(90),
  88. decoration: BoxDecoration(
  89. color: YSColors.buttonColor(context),
  90. borderRadius: const BorderRadius.only(bottomRight: Radius.circular(10),bottomLeft: Radius.circular(10))
  91. ),
  92. ),
  93. Padding(
  94. padding: EdgeInsets.only(top: ysTOP(context)+hsp(10),left: hsp(type==3?0:20),right: hsp(type==3?0:20)),
  95. child: LayoutBuilder(
  96. builder: (context,conSize){
  97. return Column(
  98. children: [
  99. Container(
  100. height: hsp(50),
  101. margin: EdgeInsets.only(left: hsp(30),right: hsp(30)),
  102. child: ListView.builder(
  103. itemBuilder: (context,index){
  104. Map item = _titleArray[index];
  105. return GestureDetector(
  106. onTap: (){
  107. _titleIndex = index;
  108. setState(() {});
  109. },
  110. behavior: HitTestBehavior.opaque,
  111. child: Opacity(
  112. opacity: _titleIndex==index?1:0.6,
  113. child: Container(
  114. width: (conSize.maxWidth-hsp(60))/_titleArray.length,
  115. alignment: Alignment.center,
  116. child: Column(
  117. mainAxisSize: MainAxisSize.min,
  118. children: [
  119. Text(item['title'],style: YSColors.title2Style(context),),
  120. Container(
  121. margin: EdgeInsets.only(top: hsp(5)),
  122. width: hsp(20),
  123. height: hsp(2),
  124. color: _titleIndex==index?Colors.white60:Colors.transparent,
  125. )
  126. ],
  127. )
  128. ),
  129. ),
  130. );
  131. },
  132. padding: const EdgeInsets.all(0),
  133. scrollDirection: Axis.horizontal,
  134. itemCount: _titleArray.length,
  135. ),
  136. ),
  137. Container(
  138. height: conSize.maxHeight-hsp(50),
  139. padding: EdgeInsets.only(top: hsp(20)),
  140. child: type==1?const YSChangeView():
  141. type==2? const YSCrossView():const YSPriceView(),
  142. )
  143. ],
  144. );
  145. },
  146. ),
  147. ),
  148. if(type==1)Padding(
  149. padding: EdgeInsets.only(top: ysTOP(context)+hsp(165),left: ysWidth(context)/2-hsp(25)),
  150. child: Transform.rotate(angle: 1.55,child: Image.asset(YSColors.imageStyle(context, '交换 反向'),height: hsp(50),width: hsp(50),),)
  151. )
  152. ],
  153. ),
  154. ),
  155. ),
  156. ),
  157. );
  158. }
  159. // @override
  160. // // TODO: implement wantKeepAlive
  161. // bool get wantKeepAlive => false;
  162. }
  163. GlobalKey<YSChangeViewState> changeKey = GlobalKey();
  164. class YSChangeView extends StatefulWidget {
  165. const YSChangeView({Key? key}) : super(key: key);
  166. @override
  167. YSChangeViewState createState() => YSChangeViewState();
  168. }
  169. class YSChangeViewState extends State<YSChangeView> {
  170. final TextEditingController _amountField = TextEditingController();
  171. Map _wallet1 = {};
  172. Map _wallet2 = {};
  173. final TextEditingController _addressField = TextEditingController();
  174. int _changeIndex = 9999;
  175. List _array = [];
  176. @override
  177. void dispose() {
  178. _amountField.dispose();
  179. _addressField.dispose();
  180. super.dispose();
  181. }
  182. change() {
  183. }
  184. @override
  185. void initState() {
  186. networkDelay((){
  187. _getCrossListData();
  188. });
  189. super.initState();
  190. }
  191. @override
  192. Widget build(BuildContext context) {
  193. return LayoutBuilder(
  194. builder: (context,conSize) {
  195. return Column(
  196. children: [
  197. Container(
  198. width: conSize.maxWidth,
  199. decoration: BoxDecoration(
  200. color: YSColors.containColor(context),
  201. borderRadius: const BorderRadius.only(topLeft: Radius.circular(10),topRight: Radius.circular(10))
  202. ),
  203. height: hsp(110),
  204. alignment: Alignment.center,
  205. child: Row(
  206. mainAxisSize: MainAxisSize.min,
  207. children: [
  208. SizedBox(
  209. width: conSize.maxWidth-hsp(180),
  210. child: Column(
  211. mainAxisSize: MainAxisSize.min,
  212. crossAxisAlignment: CrossAxisAlignment.start,
  213. children: [
  214. Text(S.of(context).NINJIANGZHIFU,style: YSColors.contentStyle(context),),
  215. Padding(
  216. padding: EdgeInsets.only(top: hsp(10),bottom: hsp(10)),
  217. child: CupertinoTextField(
  218. placeholder: S.current.QINGSHURUZHIFUJINE,
  219. style: YSColors.contentStyle(context),
  220. decoration: const BoxDecoration(),
  221. padding: const EdgeInsets.all(0),
  222. controller: _amountField,
  223. inputFormatters: [YSNumberWithDecimalFormat(decimalRange: 18)],
  224. keyboardType: TextInputType.number,
  225. ),
  226. ),
  227. Row(
  228. children: [
  229. Text('${S.of(context).YUE}: ',style: YSColors.subStyle(context),),
  230. // if(_wallet1.isNotEmpty)Expanded(child: YSBalanceView(public: _wallet1['address'],style: YSColors.subStyle(context),key: Key(_wallet1['address']),))
  231. if(_wallet1.isNotEmpty)Expanded(child: YSBalanceView(
  232. public: _wallet1['address'],
  233. style: YSColors.subStyle(context),
  234. key: Key(_wallet1['address']),
  235. type: 1,
  236. walletAddress: YSData().wallet['public'],
  237. ))
  238. ],
  239. )
  240. ],
  241. ),
  242. ),
  243. GestureDetector(
  244. onTap: (){
  245. FocusScope.of(context).unfocus();
  246. // ysShowBottomAlertView(context, YSExchangeTypeChooseView1(valueSetter: (value){
  247. // _wallet1 = value;
  248. // _amountField.text = '';
  249. // _changeIndex = 9999;
  250. // setState(() {});
  251. // },),isBarr: true);
  252. ysShowBottomAlertView(context, YSExchangeTypeChooseView2(valueSetter: (value){
  253. _wallet1 = value;
  254. if(value['address']==_wallet2['address']){
  255. _wallet2.clear();
  256. }
  257. _amountField.text = '';
  258. _changeIndex = 9999;
  259. setState(() {});
  260. },),isBarr: true);
  261. },
  262. behavior: HitTestBehavior.opaque,
  263. child: Container(
  264. width: hsp(150),
  265. alignment: Alignment.center,
  266. child: _wallet1.isNotEmpty?Row(
  267. mainAxisSize: MainAxisSize.min,
  268. children: [
  269. ClipRRect(
  270. borderRadius: const BorderRadius.all(Radius.circular(50)),
  271. child: YSImage.network(_wallet1['icon_url'],height: hsp(40),width: hsp(40),),
  272. ),
  273. Text(' ${_wallet1['bl_symbol']}',style: YSColors.contentStyle(context),),
  274. Icon(Icons.arrow_drop_down,size: hsp(30),color: YSColors.sColor(context),)
  275. ],
  276. ):Row(
  277. mainAxisSize: MainAxisSize.min,
  278. children: [
  279. Text(S.current.QINGXUANZE,style: YSColors.contentStyle(context),),
  280. Icon(Icons.arrow_drop_down,size: hsp(30),color: YSColors.sColor(context),)
  281. ],
  282. ),
  283. ),
  284. )
  285. ],
  286. ),
  287. ),
  288. Container(
  289. margin: EdgeInsets.only(top: hsp(1)),
  290. width: conSize.maxWidth,
  291. decoration: BoxDecoration(
  292. color: YSColors.containColor(context),
  293. borderRadius: const BorderRadius.only(bottomRight: Radius.circular(10),bottomLeft: Radius.circular(10))
  294. ),
  295. padding: EdgeInsets.all(hsp(15)),
  296. alignment: Alignment.center,
  297. child: Column(
  298. children: [
  299. Row(
  300. children: [
  301. SizedBox(
  302. width: conSize.maxWidth-hsp(180),
  303. child: Column(
  304. crossAxisAlignment: CrossAxisAlignment.start,
  305. children: [
  306. Text(S.of(context).NINJIANGDEDAO,style: YSColors.contentStyle(context),),
  307. Padding(
  308. padding: EdgeInsets.only(top: hsp(10),bottom: hsp(10)),
  309. child: Text('0.00',style: YSColors.contentStyle(context),),
  310. ),
  311. Row(
  312. children: [
  313. Text('${S.of(context).YUE}: ',style: YSColors.subStyle(context),),
  314. if(_wallet2.isNotEmpty)Expanded(child: YSBalanceView(
  315. public: _wallet2['address'],
  316. style: YSColors.subStyle(context),
  317. key: Key(_wallet2['address']),
  318. type: 1,
  319. walletAddress: _addressField.text,
  320. ))
  321. ],
  322. )
  323. ],
  324. ),
  325. ),
  326. GestureDetector(
  327. onTap: (){
  328. FocusScope.of(context).unfocus();
  329. ysShowBottomAlertView(context, YSExchangeTypeChooseView2(valueSetter: (value){
  330. _wallet2 = value;
  331. if(value['address']==_wallet1['address']){
  332. _wallet1.clear();
  333. }
  334. _addressField.text = '';
  335. setState(() {});
  336. },),isBarr: true);
  337. },
  338. behavior: HitTestBehavior.opaque,
  339. child: Container(
  340. width: hsp(150),
  341. alignment: Alignment.center,
  342. child: _wallet2.isNotEmpty?Row(
  343. mainAxisSize: MainAxisSize.min,
  344. children: [
  345. ClipRRect(
  346. borderRadius: const BorderRadius.all(Radius.circular(50)),
  347. child: YSImage.network(_wallet2['icon_url'],height: hsp(40),width: hsp(40),),
  348. ),
  349. Text(' ${_wallet2['bl_symbol']}',style: YSColors.contentStyle(context),),
  350. Icon(Icons.arrow_drop_down,size: hsp(30),color: YSColors.sColor(context),)
  351. ],
  352. ):Row(
  353. mainAxisSize: MainAxisSize.min,
  354. children: [
  355. Text(S.current.QINGXUANZE,style: YSColors.contentStyle(context),),
  356. Icon(Icons.arrow_drop_down,size: hsp(30),color: YSColors.sColor(context),)
  357. ],
  358. ),
  359. ),
  360. )],
  361. ),
  362. if(_wallet1.isNotEmpty&&_wallet2.isNotEmpty&&_wallet1['parentName']!=_wallet2['parentName'])Container(
  363. margin: EdgeInsets.only(top: hsp(15)),
  364. height: hsp(20),
  365. decoration: BoxDecoration(
  366. color: YSColors.contain2Color(context),
  367. borderRadius: const BorderRadius.all(Radius.circular(4))
  368. ),
  369. child: Row(
  370. children: [
  371. Expanded(
  372. child: CupertinoTextField(
  373. placeholder: S.of(context).QINGSHURUHUOXUANZENINDEMUBIAOQIANBAODIZHI,
  374. style: YSColors.subStyle(context),
  375. padding: EdgeInsets.only(left: hsp(10),right: hsp(10)),
  376. decoration: const BoxDecoration(),
  377. controller: _addressField,
  378. )
  379. ),
  380. GestureDetector(
  381. onTap: (){
  382. // LogUtil.d(_wallet2);
  383. // LogUtil.d(_wallet1);
  384. // return;
  385. ysShowBottomAlertView(context, YSExchangeTypeChooseView1(valueSetter: (value){
  386. _addressField.text = value['address']??'';
  387. },item: _wallet2,),isBarr: true);
  388. },
  389. behavior: HitTestBehavior.opaque,
  390. child: Container(
  391. width: hsp(50),
  392. height: hsp(10),
  393. decoration: BoxDecoration(
  394. border: Border(left: BorderSide(color: YSColors.lineColor(context),width: hsp(1)))
  395. ),
  396. child: Image.asset(YSColors.imageStyle(context, '钱包 (2)'),height: hsp(10),width: hsp(10),),
  397. ),
  398. )
  399. ],
  400. ),
  401. )
  402. ],
  403. ),
  404. ),
  405. Container(
  406. height: hsp(25),
  407. margin: EdgeInsets.only(top: hsp(25),bottom: hsp(25)),
  408. child: ListView.separated(
  409. itemBuilder: (context,index){
  410. return GestureDetector(
  411. onTap: () async{
  412. String balanceStr = '0.0';
  413. if(_wallet1.isNotEmpty){
  414. if('${_wallet1['address']}'.substring(0,1)=='T'){
  415. String public = YSTron.changeAddress(_wallet1['address']).replaceFirst('41', '0x');
  416. String walletAddress = YSTron.changeAddress(YSData().wallet['public']).replaceFirst('41', '0x');
  417. balanceStr = (await Wbe3Api().getTokenBalance(walletAddress,public));
  418. }else{
  419. balanceStr = await Wbe3Api().getTokenBalance(YSData().wallet['public'],_wallet1['address']);
  420. }
  421. // String balanceStr = await Wbe3Api.getBalance(_wallet1['address']);
  422. double balance = double.parse(balanceStr);
  423. _amountField.text = '${(balance*((index+1)*25)/100)}';
  424. LogUtil.d(_amountField.text);
  425. }
  426. _changeIndex = index;
  427. setState(() {});
  428. },
  429. child: Container(
  430. height: hsp(25),
  431. width: (conSize.maxWidth-hsp(90))/4,
  432. decoration: BoxDecoration(
  433. color: _changeIndex==index?YSColors.selectedColor(context):const Color(0xFFE9EEFF),
  434. borderRadius: const BorderRadius.all(Radius.circular(50)),
  435. boxShadow: [
  436. BoxShadow(color: YSColors.shadowColor(context),blurRadius: 3)
  437. ]
  438. ),
  439. alignment: Alignment.center,
  440. child: Text('${(index+1)*25}%',style: TextStyle(
  441. fontSize: zsp(14),
  442. color: _changeIndex==index?YSColors.content2Style(context).color:YSColors.selectedColor(context)),
  443. ),
  444. ),
  445. );
  446. },
  447. separatorBuilder: (context,index){
  448. return Container(width: hsp(30),);
  449. },
  450. itemCount: 4,
  451. scrollDirection: Axis.horizontal,
  452. ),
  453. ),
  454. GestureDetector(
  455. onTap: () async{
  456. // LogUtil.d(_wallet2);
  457. // LogUtil.d(_wallet1);
  458. // return;
  459. if(_wallet1.isEmpty){
  460. ysFlutterToast(S.current.QINGXUANZEZHUANZHANGDIZHI);
  461. return;
  462. }
  463. if(_wallet1['parentName']==_wallet2['parentName']){
  464. _addressField.text = YSData().wallet['public'];
  465. }
  466. if(_addressField.text.isEmpty){
  467. ysFlutterToast(S.current.QINGWANSHANJIESHOUDIZHI);
  468. return;
  469. }
  470. if(_amountField.text.isEmpty){
  471. ysFlutterToast(S.current.QINGTIANXIEZHUANZHANGSHULIANG);
  472. return;
  473. }
  474. // List walletArray = await YSSqflite().init().rawQuery();
  475. // Map wallet = walletArray.firstWhere((element) => element['public']==_wallet1['address']);
  476. if(!mounted)return;
  477. if(YSData().typeId=='TRON-HD'){
  478. ysShowCenterAlertView(context, YSLoadView(funAction: _exchangeData,wallet: YSData().wallet,successStr: S.current.SHOUQUANTIJIAOCHENGGONG,failStr: S.current.SHOUQUANTIJIAOSHIBAI,),isTrans: false);
  479. }else{
  480. ysShowCenterAlertView(context, YSLoadView(funAction: _exchangeData,wallet: YSData().wallet,successStr: S.current.DUIHUANTIJIAOCHENGGONG,failStr: S.current.DUIHUANTIJIAOSHIBAI,),isTrans: false);
  481. }
  482. // if(!mounted)return;
  483. // Wbe3Api? web = await Wbe3Api().getInstances();//_wallet2['decimal']
  484. // bool? isCheck = await web?.setContaract(_wallet2['address']);//,decimal: _wallet2['decimal']
  485. // // LogUtil.d(isCheck);
  486. // // return;
  487. // if(isCheck==true&&mounted){
  488. //
  489. // }
  490. },
  491. behavior: HitTestBehavior.opaque,
  492. child: Container(
  493. height: hsp(50),
  494. decoration: BoxDecoration(
  495. color: YSColors.buttonColor(context),
  496. borderRadius: const BorderRadius.all(Radius.circular(10))
  497. ),
  498. alignment: Alignment.center,
  499. child: Text(S.of(context).DUIHUANYULAN,style: YSColors.buttonStyle(context),),
  500. ),
  501. ),
  502. // Expanded(child: Padding(
  503. // padding: EdgeInsets.only(top: hsp(25)),
  504. // child: SingleChildScrollView(
  505. // padding: EdgeInsets.only(bottom: hsp(10)),
  506. // child: Column(
  507. // children: [
  508. // Container(
  509. // width: conSize.maxWidth,
  510. // decoration: BoxDecoration(
  511. // color: YSColors.containColor(context),
  512. // borderRadius: const BorderRadius.all(Radius.circular(10))
  513. // ),
  514. // padding: EdgeInsets.only(left: hsp(15),right: hsp(15)),
  515. // child: Column(
  516. // children: [
  517. // SizedBox(
  518. // height: hsp(45),
  519. // child: Row(
  520. // children: [
  521. // Expanded(child: Text(S.of(context).DUIHUANBAOJIA,style: YSColors.contentStyle(context),)),
  522. // Expanded(
  523. // child: Container(
  524. // alignment: Alignment.centerRight,
  525. // child: Text('1BTC≈15.966015ETH',style: YSColors.subStyle(context),),
  526. // )
  527. // )
  528. // ],
  529. // ),
  530. // ),
  531. // Divider(color: YSColors.lineColor(context),height: hsp(1),),
  532. // Container(
  533. // alignment: Alignment.centerLeft,
  534. // height: hsp(30),
  535. // child: Row(
  536. // children: [
  537. // Expanded(child: Text(S.of(context).ZUIDAHUADONGCHAJIA,style: YSColors.contentStyle(context),)),
  538. // Expanded(
  539. // child: Container(
  540. // alignment: Alignment.centerRight,
  541. // child: Text('2.00%',style: YSColors.subStyle(context),),
  542. // )
  543. // )
  544. // ],
  545. // ),
  546. // ),
  547. // Container(
  548. // alignment: Alignment.centerLeft,
  549. // height: hsp(30),
  550. // child: Row(
  551. // children: [
  552. // Expanded(child: Text(S.of(context).SHOUXUFEI,style: YSColors.contentStyle(context),)),
  553. // Expanded(
  554. // child: Container(
  555. // alignment: Alignment.centerRight,
  556. // child: Text('2.00%',style: YSColors.subStyle(context),),
  557. // )
  558. // )
  559. // ],
  560. // ),
  561. // ),
  562. // Container(
  563. // alignment: Alignment.centerLeft,
  564. // height: hsp(30),
  565. // child: Row(
  566. // children: [
  567. // Expanded(child: Text(S.of(context).JIAGEYINGXIANG,style: YSColors.contentStyle(context),)),
  568. // Expanded(
  569. // child: Container(
  570. // alignment: Alignment.centerRight,
  571. // child: Text('2.00%',style: YSColors.subStyle(context),),
  572. // )
  573. // )
  574. // ],
  575. // ),
  576. // )
  577. // ],
  578. // ),
  579. // ),
  580. // Container(
  581. // margin: EdgeInsets.only(top: hsp(10)),
  582. // width: conSize.maxWidth,
  583. // decoration: BoxDecoration(
  584. // color: YSColors.containColor(context),
  585. // borderRadius: const BorderRadius.all(Radius.circular(10))
  586. // ),
  587. // padding: EdgeInsets.only(left: hsp(15),right: hsp(15)),
  588. // child: Column(
  589. // children: [
  590. // SizedBox(
  591. // height: hsp(45),
  592. // child: Row(
  593. // children: [
  594. // Expanded(child: Text(S.of(context).ZUIJINDUIHUANJILU,style: YSColors.contentStyle(context),)),
  595. // Expanded(
  596. // child: Container(
  597. // alignment: Alignment.centerRight,
  598. // child: Text(S.of(context).GENGDUOJILU,style: YSColors.subStyle(context),),
  599. // )
  600. // )
  601. // ],
  602. // ),
  603. // ),
  604. // Divider(color: YSColors.lineColor(context),height: hsp(1),),
  605. // const YSExchangeRecordListItemView(),
  606. // ],
  607. // ),
  608. // )
  609. // ],
  610. // ),
  611. // ),
  612. // ))
  613. if(_array.isNotEmpty)Container(
  614. margin: EdgeInsets.only(top: hsp(20)),
  615. width: conSize.maxWidth,
  616. decoration: BoxDecoration(
  617. color: YSColors.containColor(context),
  618. borderRadius: const BorderRadius.all(Radius.circular(10))
  619. ),
  620. padding: EdgeInsets.only(left: hsp(15),right: hsp(15)),
  621. child: Column(
  622. children: [
  623. SizedBox(
  624. height: hsp(45),
  625. child: Row(
  626. children: [
  627. Expanded(child: Text(S.of(context).ZUIJINDUIHUANJILU,style: YSColors.contentStyle(context),)),
  628. Expanded(
  629. child: GestureDetector(
  630. onTap: (){
  631. Navigator.of(context).push(
  632. CupertinoPageRoute(builder: (context){
  633. return YSData().typeId=='TRON-HD'?const YSCrossRecord2():YSCrossRecord(item: _wallet1,);
  634. })
  635. );
  636. },
  637. behavior: HitTestBehavior.opaque,
  638. child: Container(
  639. alignment: Alignment.centerRight,
  640. child: Text(S.of(context).GENGDUOJILU,style: YSColors.subStyle(context),),
  641. ),
  642. )
  643. )
  644. ],
  645. ),
  646. ),
  647. Divider(color: YSColors.lineColor(context),height: hsp(1),),
  648. ListView.builder(
  649. itemBuilder: (context,index){
  650. Map item = _array[index];
  651. return YSExchangeRecordListItemView2(item: item);
  652. },
  653. itemCount: _array.length>1?1:_array.length,
  654. padding: const EdgeInsets.all(0),
  655. physics: const NeverScrollableScrollPhysics(),
  656. shrinkWrap: true,
  657. ),
  658. ],
  659. ),
  660. )
  661. ],
  662. );
  663. }
  664. );
  665. }
  666. // _getCrossListData() async{
  667. // YSNetWork.ysRequestHttp(context, type: RequestType.get, api: 'cross-txs', parameter: {'from_addr':_wallet1['address'],'page':1,'size':1}, successSetter: (dict){
  668. // _array = dict['data']['list']??[];
  669. // setState(() {});
  670. // });
  671. // }
  672. _getCrossListData() async{
  673. YSNetWork.ysRequestHttp(context, type: RequestType.get, api: 'transactions',
  674. parameter: {'chain_id':YSData().typeId,'address':YSData().wallet['public'],'type':0,'page':1,'size':1},
  675. successSetter: (dict){
  676. _array = dict['data']['list']??[];
  677. setState(() {});
  678. });
  679. }
  680. _exchangeData() async{
  681. try{
  682. Wbe3Api? web = await Wbe3Api().getInstances();//_wallet2['decimal']
  683. // Map dataMap = _dict2['data'];
  684. Web3Client? client = Web3Client(_wallet1['parentRpc'], Client());
  685. String walletPublic = YSData().wallet['public'];
  686. String wall1Address = _wallet1['address'];
  687. String wall2Address = _wallet2['address'];
  688. String addressFileText = _addressField.text;
  689. if(!mounted)return;
  690. YSData().pancakeAddress = YSData().typeId=='ETH-HD'?'0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D':
  691. YSData().typeId=='TRON-HD'?'TKzxdSv2FZKQrEqkKVgp5DcwEXBEKMg2Ax':'0x10ED43C718714eb63d5aA57B78B54704E256024E';
  692. bool isTron = wall1Address.substring(0,1)=='T';
  693. if(isTron){
  694. double amountD = double.parse(_amountField.text);
  695. double number = amountD * pow(10, _wallet1['decimal']);
  696. String result = await YSTron.approveContractData(context, from: walletPublic, to: addressFileText, private: YSData().wallet['private'], amount: '$number', fromTokenAddress: wall1Address, toTokenAddress: wall2Address);
  697. if(result.isNotEmpty){
  698. _amountField.text = '';
  699. _changeIndex = 9999;
  700. _getCrossListData();
  701. return true;
  702. // setState(() {});
  703. }
  704. return false;
  705. }else{
  706. if(isTron){
  707. walletPublic = YSTron.changeAddress(walletPublic).replaceFirst('41', '0x');
  708. wall1Address = YSTron.changeAddress(wall1Address).replaceFirst('41', '0x');
  709. wall2Address = YSTron.changeAddress(wall2Address).replaceFirst('41', '0x');
  710. addressFileText = YSTron.changeAddress(addressFileText).replaceFirst('41', '0x');
  711. YSData().pancakeAddress = YSTron.changeAddress(YSData().pancakeAddress).replaceFirst('41', '0x');
  712. }
  713. DeployedContract? contract = await web!.fromAssets('asset/abi.json', wall1Address);
  714. LogUtil.d('allowance=============$walletPublic========$wall1Address========$wall2Address========$addressFileText');
  715. var allowance = await client.call(
  716. contract: contract,
  717. function: contract.function('allowance'),
  718. params: [
  719. EthereumAddress.fromHex(walletPublic),
  720. EthereumAddress.fromHex(YSData().pancakeAddress),
  721. ],
  722. );
  723. double amountD = double.parse(_amountField.text);
  724. // double number = amountD*pow(10, int.parse('18'));
  725. double number = amountD * pow(10, _wallet1['decimal']);
  726. // final gasprice = await client.getGasPrice();
  727. // number = number+gasprice.getValueInUnit(EtherUnit.wei);
  728. // return false;
  729. LogUtil.d('allowance=============${allowance.first}========$number');
  730. // return;
  731. if(double.parse('${allowance.first}')<number){
  732. BigInt amountValue = BigInt.from(number);
  733. LogUtil.d('approve=============$number ${_wallet1['decimal']} $amountValue');
  734. // BigInt amountValue = BigInt.from(number);
  735. var approve = Transaction.callContract(
  736. contract: contract,
  737. function: contract.function('approve'),
  738. parameters: [
  739. EthereumAddress.fromHex(YSData().pancakeAddress),
  740. amountValue,
  741. ],
  742. );
  743. final networkId = await client.getNetworkId();
  744. LogUtil.d('allowance=============${approve.nonce}========$number');
  745. var txHash = '';
  746. if(isTron){
  747. Map request = {};
  748. request['tx'] = approve.data;
  749. String privateS = YSAes.aesEncode3('${YSData().wallet['private']}_${DateTime.now().microsecond}');
  750. request['prikey'] = privateS;
  751. // ignore: use_build_context_synchronously
  752. Map signDict = await YSNetWork.ysRequestHttpNOSet(context, type: RequestType.post, api: 'tronsign', parameter: request);
  753. if(signDict.isNotEmpty){
  754. }
  755. }else{
  756. final credentials = EthPrivateKey.fromHex(YSData().wallet['private']);
  757. txHash = await client.sendTransaction(
  758. credentials,
  759. approve,
  760. chainId: networkId,
  761. );
  762. }
  763. // return;
  764. TransactionReceipt? receipt = await client.getTransactionReceipt(txHash);
  765. LogUtil.d('approve=============$txHash');
  766. // return;
  767. double feeValue = double.parse(_amountField.text)*0.0001;
  768. var result = await web.tokenExchange(walletPublic, YSData().wallet['private'], feeValue.toStringAsFixed(8),_amountField.text,'${_wallet2['gas']}',
  769. wall2Address,_wallet1['parentRpc'],addressFileText,wall1Address);
  770. String resultStr = '$result';
  771. if(!mounted)return;
  772. if(resultStr.isNotEmpty){
  773. _amountField.text = '';
  774. _changeIndex = 9999;
  775. setState(() {});
  776. Map map = {};
  777. map['public'] = _wallet1['address'];
  778. map['balance'] = await Wbe3Api().getTokenBalance(walletPublic,wall1Address);
  779. if(!mounted)return;
  780. YSBalanceManager.notifier(context,map);
  781. return true;
  782. }
  783. }else{
  784. double feeValue = double.parse(_amountField.text)*0.0001;
  785. var result = await web.tokenExchange(walletPublic, YSData().wallet['private'], feeValue.toStringAsFixed(8),_amountField.text,'${_wallet2['gas']}',
  786. wall2Address,_wallet1['parentRpc'],addressFileText,wall1Address);
  787. String resultStr = '$result';
  788. if(!mounted)return;
  789. if(resultStr.isNotEmpty){
  790. _amountField.text = '';
  791. _changeIndex = 9999;
  792. setState(() {});
  793. Map map = {};
  794. map['public'] = _wallet1['address'];
  795. map['balance'] = await Wbe3Api().getTokenBalance(walletPublic,wall1Address);
  796. if(!mounted)return;
  797. YSBalanceManager.notifier(context,map);
  798. return true;
  799. }
  800. }
  801. return false;
  802. }
  803. }catch(e){
  804. LogUtil.d(e);
  805. ysFlutterToast('$e');
  806. return false;
  807. }
  808. // YSBip3().exchange(_wallet2['address']);
  809. // return false;
  810. // LogUtil.d(_wallet1);
  811. // return;
  812. // YSData().rpc = 'https://data-seed-prebsc-1-s1.binance.org:8545/';
  813. // Wbe3Api? web = await Wbe3Api().getInstances();//_wallet2['decimal']
  814. // double feeValue = double.parse(_amountField.text)*0.0001;
  815. // var result = await web.tokenExchange(_wallet1['address'], _wallet1['private'], feeValue.toStringAsFixed(8),_amountField.text,'${_wallet2['gas']}',
  816. // _wallet2['address'],_wallet1['parentRpc'],_addressField.text,_wallet1['address']);
  817. // String resultStr = '$result';
  818. // if(!mounted)return;
  819. // if(resultStr.isNotEmpty){
  820. // _amountField.text = '';
  821. // _changeIndex = 9999;
  822. // setState(() {});
  823. // Map map = {};
  824. // map['public'] = _wallet1['address'];
  825. // map['balance'] = await Wbe3Api.getBalance(_wallet1['address']);
  826. // if(!mounted)return;
  827. // YSBalanceManager.notifier(context,map);
  828. // return true;
  829. // }
  830. // return false;
  831. }
  832. }
  833. class YSCrossView extends StatefulWidget {
  834. const YSCrossView({Key? key}) : super(key: key);
  835. @override
  836. YSCrossViewState createState() => YSCrossViewState();
  837. }
  838. class YSCrossViewState extends State<YSCrossView> {
  839. final TextEditingController _amountField = TextEditingController();
  840. Map _coin = {};
  841. Map _wallet1 = {};
  842. Map _wallet2 = {};
  843. List _array = [];
  844. final TextEditingController _addressField = TextEditingController();
  845. int _changeIndex = 9999;
  846. @override
  847. void initState() {
  848. _getWallet();
  849. super.initState();
  850. }
  851. _getWallet() async{
  852. Map item = YSData().typeArray.firstWhere((element) => element['id']==YSData().typeId);
  853. _wallet1 = {
  854. 'icon_url':item['icon'],
  855. 'bl_symbol':item['name'],
  856. 'address':YSData().wallet['public'],
  857. 'private':YSData().wallet['private'],
  858. };
  859. _getCoinData();
  860. }
  861. _getCoinData() async{
  862. YSNetWork.ysRequestHttp(context, type: RequestType.get, api: 'coins', parameter: {'page':'1','size':100,'symbol':_wallet1['bl_symbol']}, successSetter: (dict){
  863. YSData().coinArray = dict['data']['list']??[];
  864. _getCrossListData();
  865. });
  866. }
  867. @override
  868. void dispose() {
  869. _amountField.dispose();
  870. _addressField.dispose();
  871. super.dispose();
  872. }
  873. change() {
  874. Map temp = _wallet1;
  875. _wallet1 = _wallet2;
  876. _wallet2 = temp;
  877. setState(() {});
  878. }
  879. @override
  880. Widget build(BuildContext context) {
  881. return LayoutBuilder(
  882. builder: (context,conSize) {
  883. return Column(
  884. children: [
  885. Container(
  886. width: conSize.maxWidth,
  887. decoration: BoxDecoration(
  888. color: YSColors.containColor(context),
  889. borderRadius: const BorderRadius.all(Radius.circular(10))
  890. ),
  891. padding: EdgeInsets.only(left: hsp(20),right: hsp(20),top: hsp(20),bottom: hsp(20)),
  892. alignment: Alignment.center,
  893. child: Column(
  894. mainAxisSize: MainAxisSize.min,
  895. children: [
  896. Container(
  897. height: hsp(30),
  898. alignment: Alignment.centerLeft,
  899. child: Row(
  900. children: [
  901. Container(
  902. constraints: BoxConstraints(
  903. maxWidth: conSize.maxWidth-hsp(190)
  904. ),
  905. child: Text('${S.current.XUANZEXUYAOKUALIANDEZICHAN} ',style: YSColors.subStyle(context),),
  906. ),
  907. GestureDetector(
  908. onTap: (){
  909. FocusScope.of(context).unfocus();
  910. ysShowBottomAlertView(context, YSCrossCoinChooseView(valueSetter: (value) async{
  911. _coin = value;
  912. // _coinbalance = double.parse(await Wbe3Api.getBalance(_coin['address']));
  913. setState(() {});
  914. },),isBarr: true);
  915. },
  916. behavior: HitTestBehavior.opaque,
  917. child: Container(
  918. width: hsp(150),
  919. alignment: Alignment.centerLeft,
  920. child: _coin.isNotEmpty?Row(
  921. mainAxisSize: MainAxisSize.min,
  922. children: [
  923. ClipRRect(
  924. borderRadius: const BorderRadius.all(Radius.circular(50)),
  925. child: YSImage.network(_coin['icon_url'],height: hsp(30),width: hsp(30),),
  926. ),
  927. Text(' ${_coin['bl_symbol']}',style: YSColors.contentStyle(context),),
  928. Icon(Icons.arrow_drop_down,size: hsp(30),color: YSColors.sColor(context),)
  929. ],
  930. ):Row(
  931. mainAxisSize: MainAxisSize.min,
  932. children: [
  933. Text(S.current.QINGXUANZE,style: YSColors.contentStyle(context),),
  934. Icon(Icons.arrow_drop_down,size: hsp(30),color: YSColors.sColor(context),)
  935. ],
  936. ),
  937. ),
  938. )
  939. ],
  940. ),
  941. ),
  942. Container(
  943. margin: EdgeInsets.only(bottom: hsp(20)),
  944. decoration: BoxDecoration(
  945. border: Border(bottom: BorderSide(color: YSColors.lineColor(context),width: hsp(1)))
  946. ),
  947. child: Container(
  948. margin: EdgeInsets.only(top: hsp(10),bottom: hsp(20)),
  949. height: hsp(25),
  950. child: Row(
  951. children: [
  952. Row(
  953. children: [
  954. SizedBox(
  955. width: hsp(40),
  956. child: Text('${S.current.YUE}:',style: YSColors.contentStyle(context),),
  957. ),
  958. SizedBox(
  959. width: hsp(100),
  960. // constraints: BoxConstraints(
  961. // maxWidth: hsp(180)
  962. // ),
  963. child:_coin.isEmpty?const SizedBox():YSBalanceView(public: _coin['address'],style: YSColors.subStyle(context),key: Key(_coin['address']),type: 1,walletAddress: _wallet1['address'],dymic: 4,),
  964. )
  965. ],
  966. ),
  967. Container(
  968. width: conSize.maxWidth-hsp(210),
  969. alignment: Alignment.centerLeft,
  970. decoration: BoxDecoration(
  971. color: YSColors.contain2Color(context),
  972. borderRadius: const BorderRadius.all(Radius.circular(5)),
  973. ),
  974. padding: EdgeInsets.only(left: hsp(10),right: hsp(10)),
  975. child: CupertinoTextField(
  976. placeholder: S.current.QINGSHURUKUALIANZICHANSHULIANG,
  977. style: YSColors.subStyle(context),
  978. padding: const EdgeInsets.all(0),
  979. decoration: const BoxDecoration(),
  980. inputFormatters: [YSNumberWithDecimalFormat()],
  981. keyboardType: TextInputType.number,
  982. controller: _amountField,
  983. ),
  984. )
  985. ],
  986. ),
  987. ),
  988. ),
  989. Padding(
  990. padding: EdgeInsets.only(top: hsp(10),bottom: hsp(10)),
  991. child: Row(
  992. mainAxisSize: MainAxisSize.min,
  993. children: [
  994. GestureDetector(
  995. onTap: (){
  996. FocusScope.of(context).unfocus();
  997. ysShowBottomAlertView(context, YSExchangeTypeChooseView1(valueSetter: (value){
  998. _wallet1 = value;
  999. _coin.clear();
  1000. setState(() {});
  1001. _getCrossListData();
  1002. },),isBarr: true);
  1003. },
  1004. behavior: HitTestBehavior.opaque,
  1005. child: Container(
  1006. alignment: Alignment.centerRight,
  1007. child: _wallet1.isNotEmpty?Row(
  1008. mainAxisSize: MainAxisSize.min,
  1009. children: [
  1010. ClipRRect(
  1011. borderRadius: const BorderRadius.all(Radius.circular(50)),
  1012. child: YSImage.network(_wallet1['icon_url'],height: hsp(30),width: hsp(30),),
  1013. ),
  1014. Container(
  1015. constraints: BoxConstraints(
  1016. maxWidth: ((ysWidth(context)-hsp(200))/2)
  1017. ),
  1018. child: SingleChildScrollView(
  1019. scrollDirection: Axis.horizontal,
  1020. child: Text(' ${_wallet1['bl_symbol']}',style: YSColors.contentStyle(context),),
  1021. )
  1022. ),
  1023. Icon(Icons.arrow_drop_down,size: hsp(30),color: YSColors.sColor(context),)
  1024. ],
  1025. ):Row(
  1026. mainAxisSize: MainAxisSize.min,
  1027. children: [
  1028. Container(
  1029. constraints: BoxConstraints(
  1030. maxWidth: ((ysWidth(context)-hsp(150))/2)
  1031. ),
  1032. child: SingleChildScrollView(
  1033. scrollDirection: Axis.horizontal,
  1034. child: Text(S.current.QINGXUANZE,style: YSColors.contentStyle(context),),
  1035. )
  1036. ),
  1037. Icon(Icons.arrow_drop_down,size: hsp(30),color: YSColors.sColor(context),)
  1038. ],
  1039. ),
  1040. ),
  1041. ),
  1042. Padding(
  1043. padding: EdgeInsets.only(left: hsp(8),right: hsp(8)),
  1044. child: GestureDetector(
  1045. onTap: (){
  1046. // change();
  1047. },
  1048. child: Image.asset(YSColors.imageStyle(context, '交换 反向'),height: hsp(30),width: hsp(30),),
  1049. ),
  1050. ),
  1051. GestureDetector(
  1052. onTap: (){
  1053. FocusScope.of(context).unfocus();
  1054. ysShowBottomAlertView(context, YSExchangeTypeChooseView1(valueSetter: (value){
  1055. _wallet2 = value;
  1056. _addressField.text = _wallet2['address']??'';
  1057. setState(() {});
  1058. },),isBarr: true);
  1059. },
  1060. behavior: HitTestBehavior.opaque,
  1061. child: Container(
  1062. alignment: Alignment.centerRight,
  1063. child: _wallet2.isNotEmpty?Row(
  1064. mainAxisSize: MainAxisSize.min,
  1065. children: [
  1066. ClipRRect(
  1067. borderRadius: const BorderRadius.all(Radius.circular(50)),
  1068. child: YSImage.network(_wallet2['icon_url'],height: hsp(30),width: hsp(30),),
  1069. ),
  1070. Container(
  1071. constraints: BoxConstraints(
  1072. maxWidth: ((ysWidth(context)-hsp(200))/2)
  1073. ),
  1074. child: SingleChildScrollView(
  1075. scrollDirection: Axis.horizontal,
  1076. child: Text(' ${_wallet2['bl_symbol']}',style: YSColors.contentStyle(context),),
  1077. )
  1078. ),
  1079. Icon(Icons.arrow_drop_down,size: hsp(30),color: YSColors.sColor(context),)
  1080. ],
  1081. ):Row(
  1082. mainAxisSize: MainAxisSize.min,
  1083. children: [
  1084. Container(
  1085. constraints: BoxConstraints(
  1086. maxWidth: ((ysWidth(context)-hsp(150))/2)
  1087. ),
  1088. child: SingleChildScrollView(
  1089. scrollDirection: Axis.horizontal,
  1090. child: Text(S.current.QINGXUANZE,style: YSColors.contentStyle(context),),
  1091. )
  1092. ),
  1093. Icon(Icons.arrow_drop_down,size: hsp(30),color: YSColors.sColor(context),)
  1094. ],
  1095. ),
  1096. ),
  1097. )
  1098. ],
  1099. ),
  1100. ),
  1101. Container(
  1102. margin: EdgeInsets.only(top: hsp(15)),
  1103. height: hsp(20),
  1104. decoration: BoxDecoration(
  1105. color: YSColors.contain2Color(context),
  1106. borderRadius: const BorderRadius.all(Radius.circular(4))
  1107. ),
  1108. child: Row(
  1109. children: [
  1110. Expanded(
  1111. child: CupertinoTextField(
  1112. placeholder: S.of(context).QINGSHURUHUOXUANZENINDEMUBIAOQIANBAODIZHI,
  1113. style: YSColors.subStyle(context),
  1114. padding: EdgeInsets.only(left: hsp(10),right: hsp(10)),
  1115. decoration: const BoxDecoration(),
  1116. controller: _addressField,
  1117. )
  1118. ),
  1119. GestureDetector(
  1120. onTap: (){
  1121. ysShowBottomAlertView(context, YSExchangeTypeChooseView1(valueSetter: (value){
  1122. _addressField.text = value['address']??'';
  1123. },item: _wallet2,),isBarr: true);
  1124. },
  1125. behavior: HitTestBehavior.opaque,
  1126. child: Container(
  1127. width: hsp(50),
  1128. height: hsp(10),
  1129. decoration: BoxDecoration(
  1130. border: Border(left: BorderSide(color: YSColors.lineColor(context),width: hsp(1)))
  1131. ),
  1132. child: Image.asset(YSColors.imageStyle(context, '钱包 (2)'),height: hsp(10),width: hsp(10),),
  1133. ),
  1134. )
  1135. ],
  1136. ),
  1137. )
  1138. ],
  1139. ),
  1140. ),
  1141. Container(
  1142. height: hsp(25),
  1143. margin: EdgeInsets.only(top: hsp(25),bottom: hsp(25)),
  1144. child: ListView.separated(
  1145. itemBuilder: (context,index){
  1146. return GestureDetector(
  1147. onTap: () async{
  1148. if(_coin.isNotEmpty){
  1149. Wbe3Api? web = await Wbe3Api().getInstances();
  1150. String balanceStr = '0.0';
  1151. if('${_wallet1['address']}'.substring(0,1)=='T'){
  1152. String public = YSTron.changeAddress(_wallet1['address']).replaceFirst('41', '0x');
  1153. String walletAddress = YSTron.changeAddress(YSData().wallet['public']).replaceFirst('41', '0x');
  1154. balanceStr = (await Wbe3Api().getTokenBalance(walletAddress,public));
  1155. }else{
  1156. balanceStr = await Wbe3Api().getTokenBalance(YSData().wallet['public'],_wallet1['address']);
  1157. }
  1158. // String? balanceStr = await web?.getTokenBalance(_wallet1['address'],_coin['address']);
  1159. double balance = double.parse(balanceStr);
  1160. _amountField.text = (balance/100*((index+1)*25)).toStringAsFixed(4);
  1161. _changeIndex = index;
  1162. setState(() {});
  1163. }
  1164. },
  1165. child: Container(
  1166. height: hsp(25),
  1167. width: (conSize.maxWidth-hsp(90))/4,
  1168. decoration: BoxDecoration(
  1169. color: _changeIndex==index?YSColors.selectedColor(context):const Color(0xFFE9EEFF),
  1170. borderRadius: const BorderRadius.all(Radius.circular(50)),
  1171. boxShadow: [
  1172. BoxShadow(color: YSColors.shadowColor(context),blurRadius: 3)
  1173. ]
  1174. ),
  1175. alignment: Alignment.center,
  1176. child: Text('${(index+1)*25}%',style: TextStyle(fontSize: zsp(14),color: _changeIndex==index?YSColors.containColor(context):YSColors.selectedColor(context)),),
  1177. ),
  1178. );
  1179. },
  1180. separatorBuilder: (context,index){
  1181. return Container(width: hsp(30),);
  1182. },
  1183. itemCount: 4,
  1184. scrollDirection: Axis.horizontal,
  1185. ),
  1186. ),
  1187. GestureDetector(
  1188. onTap: () async{
  1189. _crossData();
  1190. },
  1191. behavior: HitTestBehavior.opaque,
  1192. child: Container(
  1193. height: hsp(50),
  1194. decoration: BoxDecoration(
  1195. color: YSColors.buttonColor(context),
  1196. borderRadius: const BorderRadius.all(Radius.circular(10))
  1197. ),
  1198. alignment: Alignment.center,
  1199. child: Text('${S.current.SHOUQUAN}${_coin['bl_symbol']??''}',style: YSColors.buttonStyle(context),),
  1200. ),
  1201. ),
  1202. Expanded(child: Padding(
  1203. padding: EdgeInsets.only(top: hsp(25)),
  1204. child: SingleChildScrollView(
  1205. padding: EdgeInsets.only(bottom: hsp(10)),
  1206. child: Column(
  1207. children: [
  1208. // Container(
  1209. // width: conSize.maxWidth,
  1210. // decoration: BoxDecoration(
  1211. // color: YSColors.containColor(context),
  1212. // borderRadius: const BorderRadius.all(Radius.circular(10))
  1213. // ),
  1214. // padding: EdgeInsets.only(left: hsp(15),right: hsp(15)),
  1215. // child: Column(
  1216. // children: [
  1217. // SizedBox(
  1218. // height: hsp(45),
  1219. // child: Row(
  1220. // children: [
  1221. // Expanded(child: Text(S.of(context).DUIHUANBAOJIA,style: YSColors.contentStyle(context),)),
  1222. // Expanded(
  1223. // child: Container(
  1224. // alignment: Alignment.centerRight,
  1225. // child: Text('1BTC≈15.966015ETH',style: YSColors.subStyle(context),),
  1226. // )
  1227. // )
  1228. // ],
  1229. // ),
  1230. // ),
  1231. // Divider(color: YSColors.lineColor(context),height: hsp(1),),
  1232. // Container(
  1233. // alignment: Alignment.centerLeft,
  1234. // height: hsp(30),
  1235. // child: Row(
  1236. // children: [
  1237. // Expanded(child: Text(S.of(context).ZUIDAHUADONGCHAJIA,style: YSColors.contentStyle(context),)),
  1238. // Expanded(
  1239. // child: Container(
  1240. // alignment: Alignment.centerRight,
  1241. // child: Text('2.00%',style: YSColors.subStyle(context),),
  1242. // )
  1243. // )
  1244. // ],
  1245. // ),
  1246. // ),
  1247. // Container(
  1248. // alignment: Alignment.centerLeft,
  1249. // height: hsp(30),
  1250. // child: Row(
  1251. // children: [
  1252. // Expanded(child: Text(S.of(context).SHOUXUFEI,style: YSColors.contentStyle(context),)),
  1253. // Expanded(
  1254. // child: Container(
  1255. // alignment: Alignment.centerRight,
  1256. // child: Text('2.00%',style: YSColors.subStyle(context),),
  1257. // )
  1258. // )
  1259. // ],
  1260. // ),
  1261. // ),
  1262. // Container(
  1263. // alignment: Alignment.centerLeft,
  1264. // height: hsp(30),
  1265. // child: Row(
  1266. // children: [
  1267. // Expanded(child: Text(S.of(context).JIAGEYINGXIANG,style: YSColors.contentStyle(context),)),
  1268. // Expanded(
  1269. // child: Container(
  1270. // alignment: Alignment.centerRight,
  1271. // child: Text('2.00%',style: YSColors.subStyle(context),),
  1272. // )
  1273. // )
  1274. // ],
  1275. // ),
  1276. // )
  1277. // ],
  1278. // ),
  1279. // ),
  1280. if(_array.isNotEmpty)Container(
  1281. // margin: EdgeInsets.only(top: hsp(10)),
  1282. width: conSize.maxWidth,
  1283. decoration: BoxDecoration(
  1284. color: YSColors.containColor(context),
  1285. borderRadius: const BorderRadius.all(Radius.circular(10))
  1286. ),
  1287. padding: EdgeInsets.only(left: hsp(15),right: hsp(15)),
  1288. child: Column(
  1289. children: [
  1290. SizedBox(
  1291. height: hsp(45),
  1292. child: Row(
  1293. children: [
  1294. Expanded(child: Text(S.of(context).ZUIJINDUIHUANJILU,style: YSColors.contentStyle(context),)),
  1295. Expanded(
  1296. child: GestureDetector(
  1297. onTap: (){
  1298. Navigator.of(context).push(
  1299. CupertinoPageRoute(builder: (context){
  1300. return YSCrossRecord(item: _wallet1,);
  1301. })
  1302. );
  1303. },
  1304. behavior: HitTestBehavior.opaque,
  1305. child: Container(
  1306. alignment: Alignment.centerRight,
  1307. child: Text(S.of(context).GENGDUOJILU,style: YSColors.subStyle(context),),
  1308. ),
  1309. )
  1310. )
  1311. ],
  1312. ),
  1313. ),
  1314. Divider(color: YSColors.lineColor(context),height: hsp(1),),
  1315. ListView.builder(
  1316. itemBuilder: (context,index){
  1317. Map item = _array[index];
  1318. return YSExchangeRecordListItemView(item: item);
  1319. },
  1320. itemCount: _array.length>1?1:_array.length,
  1321. padding: const EdgeInsets.all(0),
  1322. physics: const NeverScrollableScrollPhysics(),
  1323. shrinkWrap: true,
  1324. ),
  1325. ],
  1326. ),
  1327. )
  1328. ],
  1329. ),
  1330. ),
  1331. ))
  1332. ],
  1333. );
  1334. }
  1335. );
  1336. }
  1337. _getCrossListData() async{
  1338. YSNetWork.ysRequestHttp(context, type: RequestType.get, api: 'cross-txs', parameter: {'from_addr':_wallet1['address'],'page':1,'size':1}, successSetter: (dict){
  1339. _array = dict['data']['list']??[];
  1340. setState(() {});
  1341. });
  1342. }
  1343. Map _dict2 = {};
  1344. _crossData() async{
  1345. FocusScope.of(context).unfocus();
  1346. if(_coin.isEmpty){
  1347. ysFlutterToast('请选择需要转出的资产');
  1348. return;
  1349. }
  1350. if(_amountField.text.isEmpty){
  1351. ysFlutterToast('请输入转出的资产金额');
  1352. return;
  1353. }
  1354. if(_wallet1.isEmpty){
  1355. ysFlutterToast('请选择转出链');
  1356. return;
  1357. }
  1358. if(_wallet2.isEmpty){
  1359. ysFlutterToast('请选择转入链');
  1360. return;
  1361. }
  1362. if(_addressField.text.isEmpty){
  1363. ysFlutterToast('请选择目标钱包的地址');
  1364. return;
  1365. }
  1366. if(!mounted)return;
  1367. // String? tokenBStr = await wbe3api?.getTokenBalance(_wallet1['address'], _coin['address']);
  1368. Map code = {'Bnbchain':'bsc','Ethereum':'eth','Tron':'tron','Nova':'nova'};
  1369. if(_wallet1['bl_symbol']==_wallet2['bl_symbol'])return;
  1370. YSNetWork.ysRequestHttp(context, type: RequestType.get, api: 'cross-configs', parameter: {},isLoading: true, successSetter: (dict){
  1371. List list = dict['data']['list']??[];
  1372. for (var element in list) {
  1373. String key1 = code['${_wallet1['bl_symbol']}'];
  1374. String key2 = code['${_wallet2['bl_symbol']}'];
  1375. if(element['from_chain']==key1&&element['to_chain']==key2){
  1376. if(element['fee_type']==1){
  1377. double navaAmount = double.parse(_amountField.text);
  1378. double fee = double.parse('${element['fee_amount']}');
  1379. if(navaAmount<=fee){
  1380. ysFlutterToast('钱包余额不足');
  1381. return;
  1382. }
  1383. }
  1384. Map request = {};
  1385. request['symbol'] = '${_coin['bl_symbol']}'.toLowerCase();
  1386. request['amount'] = _amountField.text;
  1387. request['from_chain'] = key1;
  1388. request['from_addr'] = _wallet1['address'];
  1389. request['to_chain'] = key2;
  1390. request['to_addr'] = _wallet2['address'];
  1391. YSNetWork.ysRequestHttp(context, type: RequestType.post, api: 'cross-txs', parameter: request,isLoading: true, successSetter: (dict2) async{
  1392. // _postCrossData(dict2);
  1393. _dict2 = dict2;
  1394. ysShowCenterAlertView(context, YSLoadView(funAction: _postCrossData,wallet: YSData().wallet,),isTrans: false);
  1395. });
  1396. }
  1397. }}
  1398. );
  1399. }
  1400. Future<bool> _postCrossData() async{
  1401. Wbe3Api? wbe3api = await Wbe3Api().getInstances();
  1402. Map dataMap = _dict2['data'];
  1403. Web3Client? client = Web3Client(YSData().rpc, Client());
  1404. DeployedContract? contract = await wbe3api?.fromAssets('asset/abi.json', _coin['address']);
  1405. var allowance = await client.call(
  1406. contract: contract!,
  1407. function: contract.function('allowance'),
  1408. params: [
  1409. EthereumAddress.fromHex(_wallet1['address']),
  1410. EthereumAddress.fromHex(dataMap['contract']),
  1411. ],
  1412. );
  1413. double amountD = double.parse('${dataMap['tx']['amount']}');
  1414. double number = amountD*10*int.parse('${_coin['decimal']}');
  1415. if(double.parse('${allowance.first}')<number){
  1416. bool isCheck = await YSAuthCheck().check();
  1417. if(isCheck){
  1418. BigInt amountValue = BigInt.from(double.parse('${dataMap['tx']['amount']}') * pow(10, _coin['decimal']));
  1419. var approve = Transaction.callContract(
  1420. contract: contract,
  1421. function: contract.function('approve'),
  1422. parameters: [
  1423. EthereumAddress.fromHex(dataMap['contract']),
  1424. amountValue,
  1425. ],
  1426. );
  1427. final networkId = await client.getNetworkId();
  1428. final credentials = EthPrivateKey.fromHex(_wallet1['private']);
  1429. var txHash = await client.sendTransaction(
  1430. credentials,
  1431. approve,
  1432. chainId: networkId,
  1433. );
  1434. TransactionReceipt? receipt = await client.getTransactionReceipt(txHash);
  1435. Uint8List bytes = hexToBytes(dataMap['data']!);
  1436. String from = dataMap['tx']['from_addr'];
  1437. String to = dataMap['contract'];
  1438. // String fee = dataMap['tx']['fee_amount'];
  1439. String amount = '0';//dataMap['tx']['amount'];
  1440. Wbe3Api? web = await Wbe3Api().getInstances();
  1441. web?.adppContaractDecimals(to);
  1442. var result = await web?.signETHTransaction(from,to, YSData().wallet['private'], amount,'100000',data: bytes);
  1443. if('$result'.isNotEmpty){
  1444. return true;
  1445. }
  1446. }else{
  1447. return false;
  1448. }
  1449. }else{
  1450. Uint8List bytes = hexToBytes(dataMap['data']!);
  1451. String from = dataMap['tx']['from_addr'];
  1452. String to = dataMap['contract'];
  1453. // String fee = dataMap['tx']['fee_amount'];
  1454. String amount = '0';//dataMap['tx']['amount'];
  1455. Wbe3Api? web = await Wbe3Api().getInstances();
  1456. web?.adppContaractDecimals(to);
  1457. var result = await web?.signETHTransaction(from,to, YSData().wallet['private'], amount, '100000',data: bytes);
  1458. if('$result'.isNotEmpty){
  1459. return true;
  1460. }
  1461. }
  1462. return false;
  1463. }
  1464. }
  1465. class YSPriceView extends StatefulWidget {
  1466. const YSPriceView({Key? key}) : super(key: key);
  1467. @override
  1468. YSPriceViewState createState() => YSPriceViewState();
  1469. }
  1470. class YSPriceViewState extends State<YSPriceView> with SingleTickerProviderStateMixin{
  1471. List _titleArray = [];
  1472. // final List _siftArray = [
  1473. // {'title':S.current.MINGCHENG,'tag':1,'status':0},
  1474. // {'title':S.current.HCHENGJIAOE,'tag':2,'status':0},
  1475. // {'title':S.current.ZUIXINJIA,'tag':3,'status':0},
  1476. // {'title':S.current.HZHANGDIE,'tag':4,'status':0}
  1477. // ];
  1478. TabController? _tabController;
  1479. bool _isTips = false;
  1480. @override
  1481. void initState() {
  1482. networkDelay((){
  1483. _getTitleArray();
  1484. });
  1485. super.initState();
  1486. }
  1487. _getTitleArray() async{
  1488. YSNetWork.ysRequestHttp(context, type: RequestType.get, api: 'marketclass', parameter: {}, successSetter: (dict){
  1489. Map data = dict['data'];
  1490. _titleArray = data['list']??[];
  1491. _tabController = TabController(
  1492. vsync: this,
  1493. length: _titleArray.length,
  1494. );
  1495. setState(() {});
  1496. });
  1497. }
  1498. @override
  1499. Widget build(BuildContext context) {
  1500. return ClipRRect(
  1501. borderRadius: const BorderRadius.only(topLeft: Radius.circular(10),topRight: Radius.circular(10)),
  1502. child: Container(
  1503. color: YSColors.backgroundColor(context),
  1504. padding: EdgeInsets.only(left: hsp(20),right: hsp(20)),
  1505. child: LayoutBuilder(
  1506. builder: (context,conSize) {
  1507. return _tabController==null?Container():DefaultTabController(
  1508. length: _titleArray.length,
  1509. child: Column(
  1510. children: [
  1511. SizedBox(
  1512. height: hsp(45),
  1513. child: TabBar(
  1514. controller: _tabController,
  1515. indicatorColor: Colors.transparent,
  1516. isScrollable: true,
  1517. indicatorWeight: hsp(1),
  1518. labelColor: YSColors.contentStyle(context).color,
  1519. tabs: _titleArray.map((f) {
  1520. return Tab(
  1521. child: Text(f['title']),
  1522. );
  1523. }).toList(),
  1524. ),
  1525. ),
  1526. // SizedBox(
  1527. // height: hsp(45),
  1528. // child: Row(
  1529. // children: [
  1530. // Expanded(
  1531. // child: ListView.builder(
  1532. // itemBuilder: (context,index){
  1533. // Map item = _siftArray[index];
  1534. // return Container(
  1535. // width: conSize.maxWidth/4,
  1536. // alignment: Alignment.center,
  1537. // child: YSSiftView(siftMap: item,valueSetter: (value){
  1538. // for (Map element in _siftArray) {
  1539. // element.remove('status');
  1540. // }
  1541. // item['status'] = value;
  1542. // if(item['tag']==1){
  1543. //
  1544. // }else if(item['tag']==2){
  1545. //
  1546. // }else if(item['tag']==3){
  1547. //
  1548. // }else if(item['tag']==4){
  1549. //
  1550. // }
  1551. // setState(() {});
  1552. // },key: Key('${item['tag']}${item['status']}'),),
  1553. // );
  1554. // },
  1555. // itemCount: _siftArray.length,
  1556. // scrollDirection: Axis.horizontal,
  1557. // padding: const EdgeInsets.all(0),
  1558. // )
  1559. // )
  1560. // ],
  1561. // ),
  1562. // ),
  1563. if(_isTips==true)YSShowTipsView(tipStr: S.current.GAIDIZHIJINZHICHIBSC,callback: (){
  1564. _isTips = false;
  1565. setState(() {});
  1566. },),
  1567. SizedBox(
  1568. height: conSize.maxHeight-hsp(_isTips==false?90:130)+hsp(45),//45
  1569. child: TabBarView(
  1570. controller: _tabController,
  1571. children: _titleArray.map((f) {
  1572. return YSShopPriceDataView(item: f,);
  1573. }).toList(),
  1574. ),
  1575. )
  1576. ],
  1577. ),
  1578. );
  1579. }
  1580. ),
  1581. ),
  1582. );
  1583. }
  1584. }
  1585. class YSShopPriceDataView extends StatefulWidget {
  1586. final Map item;
  1587. const YSShopPriceDataView({Key? key, required this.item}) : super(key: key);
  1588. @override
  1589. YSShopPriceDataViewState createState() => YSShopPriceDataViewState();
  1590. }
  1591. class YSShopPriceDataViewState extends State<YSShopPriceDataView> {
  1592. List _dataArray = [];
  1593. @override
  1594. Widget build(BuildContext context) {
  1595. return YSRefreshLoad(
  1596. url: 'marketlist',
  1597. request: {'class':widget.item['class']},
  1598. postData: (value) {
  1599. _dataArray = value;
  1600. setState(() {});
  1601. },
  1602. child: SingleChildScrollView(
  1603. child: ListView.builder(
  1604. itemBuilder: (context, index) {
  1605. Map item = _dataArray[index];
  1606. return YSShopListItemView(item: item,);
  1607. },
  1608. itemCount: _dataArray.length,
  1609. padding: const EdgeInsets.all(0),
  1610. shrinkWrap: true,
  1611. physics: const NeverScrollableScrollPhysics(),
  1612. ),
  1613. ),
  1614. );
  1615. }
  1616. }