index.vue 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. <template>
  2. <view class="content">
  3. <view class="content-text">1.连接钱包</view>
  4. <button class="content-button" @click="modal.open()">Open Connect Modal</button>
  5. <button class="content-button" @click="modal.open({ view: 'Networks' })">Open Network Modal</button>
  6. <button class="content-button" @click="disconnect()">断开连接</button>
  7. <view class="content-text">2.获取钱包信息</view>
  8. <view class="content-text2">address:{{ address }}</view>
  9. <view class="content-text2">chainId:{{ chainId }}</view>
  10. <view class="content-text">3.签名</view>
  11. <button class="content-button" @click="sign()">sign message</button>
  12. <view class="content-text">4.查询 Match 余额</view>
  13. <view class="content-text2">MAT: {{balance && formatUnits(balance.value,18)}}</view>
  14. <view class="content-text2">TOX: {{usdtBalance && formatUnits(usdtBalance,18)}}</view>
  15. <view class="content-text">5.转账</view>
  16. <input v-model="state.inputValue" @input="fun" type="text" />
  17. <button class="content-button" @click="transfer()">transfer</button>
  18. <view class="content-text">6.查询 授权合约额度</view>
  19. <view class="content-text2"> allowance: {{allowance && formatUnits(allowance,18)}}</view>
  20. <button class="content-button" @click="signLogin()">Login</button>
  21. </view>
  22. </template>
  23. <script setup>
  24. import {
  25. toRefs,
  26. toRaw,
  27. ref,
  28. defineModel,
  29. reactive
  30. } from 'vue';
  31. import {
  32. arbitrum,
  33. mainnet
  34. } from '@wagmi/core/chains'
  35. import {
  36. createWeb3Modal,
  37. useWeb3Modal,
  38. useWeb3ModalEvents,
  39. useWeb3ModalState,
  40. useWeb3ModalTheme
  41. } from '@web3modal/wagmi/vue'
  42. import {
  43. chains,
  44. projectId,
  45. wagmiConfig
  46. } from "../../unit/config.js";
  47. // 3. Create modal
  48. createWeb3Modal({
  49. wagmiConfig,
  50. projectId,
  51. chains,
  52. themeMode: 'light'
  53. })
  54. import {
  55. useAccount,
  56. useBalance,
  57. useDisconnect,
  58. useReadContract,
  59. useSignMessage,
  60. useWriteContract
  61. } from "@wagmi/vue";
  62. import ERC20 from '../../contract/abi/ERC20.json'
  63. import {
  64. ChainId,
  65. USDT_ADDRESS
  66. } from "@/contract/address";
  67. import {
  68. formatUnits,
  69. parseUnits
  70. } from "viem";
  71. const {
  72. signMessageAsync
  73. } = useSignMessage()
  74. const {
  75. disconnect
  76. } = useDisconnect()
  77. // 4. Use modal composable 。
  78. // 注意在使用“useWeb3Mode”compositable之前,请调用“createWeb3Model”
  79. const modal = useWeb3Modal()
  80. const {
  81. address,
  82. chainId,
  83. isConnected
  84. } = useAccount()
  85. // 获取原生代币余额
  86. // const {
  87. // data
  88. // } = useBalance({
  89. // address: address?.value// '0x9e4caaf0525eeb2F92Ab985AacC14B9C8BcfDB82'
  90. // })
  91. // const balance = toRaw(data._object).datat && toRaw(data._object).data.formatted
  92. // console.log("balance:",balance);
  93. //const blance2 = balance["_object"]
  94. //console.log("blance2 --- ",JSON.parse(JSON.stringify(balance)));
  95. const {
  96. data: balance
  97. } = useBalance({
  98. address: address?.value
  99. })
  100. const balanceData = balance.value;
  101. if (balanceData) {
  102. console.log("Balance value:", formatUnits(balanceData.value, 18));
  103. console.log("Balance object:", balanceData);
  104. const balanceFormatted = balanceData?.formatted || 'undefined';
  105. const balanceSymbol = balanceData?.symbol || 'undefined';
  106. const balanceValue = formatUnits(balanceData.value, 18);
  107. console.log("Balance formatted:", balanceFormatted);
  108. console.log("Balance symbol:", balanceSymbol);
  109. console.log("Balance value:", balanceValue);
  110. } else {
  111. console.log("Balance data is not available.");
  112. }
  113. //签名
  114. async function sign() {
  115. const signature = await signMessageAsync({
  116. message: 'gm wagmi frens'
  117. })
  118. console.log(signature)
  119. }
  120. //测试签名登录
  121. async function signLogin() {
  122. if (!address) {
  123. await modal.open();
  124. }
  125. console.log("Connected address:", address);
  126. const userAddress = address.value;
  127. console.log("userAddress:", userAddress)
  128. const message = `Login request from ${userAddress}`;
  129. const signature = await signMessageAsync({
  130. message
  131. });
  132. // Send signature and account to backend
  133. // const response = await axios.post('http://192.168.0.113:30001/ms_dev/program/getLoginToken', {
  134. // address: address,
  135. // signature: signature,
  136. // message: message
  137. // });
  138. const params = {
  139. address: userAddress,
  140. signature: signature,
  141. message: message
  142. }
  143. uni.request({
  144. url: "http://127.0.0.1:30001/ms_dev/program/getLoginToken",
  145. data: params,
  146. method: "POST",
  147. header: {
  148. "Content-Type": "application/json",
  149. },
  150. success: function(res) {
  151. if (res.statusCode == 200) {
  152. let data = res.data;
  153. console.log("res:", data);
  154. const token = data.token;
  155. console.log(token)
  156. } else {
  157. console.error("Error:", res)
  158. }
  159. },
  160. fail: function(e) {
  161. console.error("Failed:", e)
  162. }
  163. })
  164. }
  165. // function getBalance(){
  166. // console.log(isConnected.value,chainId.value,address.value)
  167. // // 读取合约数据
  168. // const usdtBalance = useReadContract({
  169. // abi:ERC20,
  170. // address: USDT_ADDRESS[chainId.value],
  171. // functionName: 'balanceOf',
  172. // args: [address.value],
  173. // })
  174. // console.log(usdtBalance)
  175. // }
  176. // 获取 USDT 余额
  177. const {
  178. data: usdtBalance
  179. } = useReadContract({
  180. abi: ERC20,
  181. address: USDT_ADDRESS[ChainId.MATCH],
  182. functionName: 'balanceOf',
  183. args: [address],
  184. })
  185. // 获取 USDT授权某个合约额度 直接转账transfer不需要授权 调用合约扣除自己代币的需要先授权
  186. // 授权方法 approve 参数 合约地址 数量(一般MaxUint256)具体看 abi erc20
  187. // export const MaxUint256: bigint = BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
  188. const {
  189. data: allowance
  190. } = useReadContract({
  191. abi: ERC20,
  192. address: USDT_ADDRESS[ChainId.MATCH],
  193. functionName: 'allowance',
  194. //自己地址 合约地址
  195. args: [address, address],
  196. })
  197. const {
  198. writeContractAsync
  199. } = useWriteContract()
  200. const state = reactive({
  201. inputValue: '',
  202. })
  203. // 输入处理函数
  204. let fun = (event)=>{
  205. console.log(event);
  206. state.inputValue = event.target.value;
  207. }
  208. async function transfer() {
  209. console.log(state.inputValue);
  210. return;
  211. //转给谁
  212. const to = "0xB91ee630d4BaF83bBfc32d99a6536344d63cCA87"; // "0xa5f99C0E7D0C7A35D27b6F8E9881F2c9E32A937D"
  213. //转多少 这里以 1 个 USDT 举例 因为区块链没有小数 USDT 的代币精度是 18 1个 USDT 在区块链上表示为 1*10**18
  214. const value = parseUnits("0.01", 18) //库封装了方法
  215. const res = await writeContractAsync({
  216. abi: ERC20,
  217. address: USDT_ADDRESS[ChainId.MATCH],
  218. functionName: 'transfer',
  219. args: [
  220. to,
  221. value
  222. ],
  223. })
  224. console.log(res)
  225. //transferFrom
  226. // const from = "0x4AB39A1B4861b1F2996C6104ee0ED67A31cf26a8";
  227. // const res2 = await writeContractAsync({
  228. // abi: ERC20,
  229. // address: USDT_ADDRESS[ChainId.BSC],
  230. // functionName: 'transferFrom',
  231. // args: [
  232. // from,
  233. // to,
  234. // value
  235. // ],
  236. // })
  237. // console.log(res2)
  238. }
  239. //uniapp 页面钩子
  240. import {
  241. onLoad,
  242. onShow
  243. } from "@dcloudio/uni-app";
  244. // onLoad 接受 A 页面传递的参数
  245. onLoad((option) => {
  246. console.log("index 页面 onLoad:", option); //B 页面 onLoad: {id: '1', name: 'uniapp'}
  247. });
  248. onShow(() => {
  249. console.log("index 页面 onShow");
  250. });
  251. </script>
  252. <style>
  253. .content {
  254. display: flex;
  255. flex-direction: column;
  256. align-items: center;
  257. justify-content: center;
  258. background-color: aqua;
  259. }
  260. .content-text {
  261. text-align: left;
  262. width: 400rpx;
  263. height: 60rpx;
  264. font-weight: bold;
  265. margin: 20rpx 0;
  266. }
  267. .content-text2 {
  268. text-align: left;
  269. width: 400rpx;
  270. height: 80rpx;
  271. line-height: 80rpx;
  272. /* border: 1rpx solid red; */
  273. /* word-wrap: break-word; */
  274. /* font-weight: bold; */
  275. }
  276. .content-input {}
  277. .content-button {
  278. /* width: 400rpx; */
  279. /* height: 60rpx; */
  280. margin: 10rpx 0;
  281. }
  282. </style>