| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- <template>
- <view class="header-content flex-column">
- <view class="head-title flex-left justify-between">
- <view style="width: 94rpx">
- <u-icon
- v-if="false"
- name="arrow-left"
- color="#000E08"
- size="42rpx"
- @click="goBack"
- bold
- ></u-icon>
- <view v-else></view>
- </view>
- <view>{{ title }}</view>
- <image
- src="@/static/img/icon-switch.svg"
- style="width: 90rpx; height: 90rpx"
- ></image>
- </view>
- <view
- class="flex-row items-center"
- :style="back ? 'padding: 0 28rpx;' : ''"
- >
- <view style="padding-right: 20rpx" @click="goMy">
- <image
- :class="back ? 'max-head' : 'min-head'"
- src="@/static/img/head.png"
- ></image>
- </view>
- <!-- <view class="user-box">{{ address }}</view> -->
- <!-- <view class="wallet-box" @click="modal.open()">连接钱包</view> -->
-
- <view class="user-box" @click="address ? copyToClipboard() : modal.open()">
- {{ address ? formattedAddress : '连接钱包' }}
- </view>
- <view class="wallet-box" @click="address ? disconnect() : null" :class="{ disabled: !address }">
- {{ address ? '断开钱包' : '未链接钱包或未成为VIP只可观看3分钟' }}
- </view>
- </view>
- </view>
- </template>
- <script setup>
-
- import { ref,computed,onMounted } from "vue";
- // const { address } = useAccount();
- onMounted(() => {
- disconnect();
- });
- const formattedAddress = computed(() => {
- if (!address.value) return '';
- return `${address.value.slice(0, 4)}****${address.value.slice(-4)}`;
- });
- // 添加 copyToClipboard 方法
- const copyToClipboard = () => {
- const textToCopy = address.value;
- navigator.clipboard.writeText(textToCopy).then(() => {
- uni.showToast({
- title: '复制成功',
- icon: 'success'
- });
- }).catch(err => {
- console.error("Failed to copy: ", err);
- uni.showToast({
- title: '复制失败',
- icon: 'none'
- });
- });
- };
- const props = defineProps({
- back: {
- type: Boolean,
- default: false,
- },
- title: {
- type: Boolean,
- default: "首页",
- },
- });
- // 点击头像后跳转个人中心
- const goMy = () => {
- if (!props.back) {
- uni.navigateTo({
- url: "/pages/my/index",
- });
- }
- };
- const goBack = () => {
- uni.navigateBack();
- };
- //wallet
- import {
- arbitrum,
- mainnet
- } from '@wagmi/core/chains'
- import {
- createWeb3Modal,
- defaultWagmiConfig,
- useWeb3Modal,
- useWeb3ModalEvents,
- useWeb3ModalState,
- useWeb3ModalTheme
- } from '@web3modal/wagmi/vue'
- import {
- chains,
- projectId,
- wagmiConfig
- } from "../utils/config.js";
- // 3. Create modal
- createWeb3Modal({
- wagmiConfig,
- projectId,
- chains,
- themeMode: 'light'
- })
- import {
- useAccount,
- useBalance,
- useDisconnect,
- useReadContract,
- useSignMessage,
- useWriteContract
- } from "@wagmi/vue";
- import ERC20 from '../contract/abi/ERC20.json'
- import {
- ChainId,
- USDT_ADDRESS
- } from "@/contract/address";
- import {
- formatUnits,
- parseUnits
- } from "viem";
- const {
- signMessageAsync
- } = useSignMessage()
- const {
- disconnect
- } = useDisconnect()
- // 4. Use modal composable 。
- // 注意在使用“useWeb3Mode”compositable之前,请调用“createWeb3Model”
- const modal = useWeb3Modal()
- const {
- address,
- chainId,
- isConnected
- } = useAccount()
- //签名
- async function sign() {
- const signature = await signMessageAsync({
- message: 'gm wagmi frens'
- })
- console.log(signature)
- }
- // function getBalance(){
- // console.log(isConnected.value,chainId.value,address.value)
- // // 读取合约数据
- // const usdtBalance = useReadContract({
- // abi:ERC20,
- // address: USDT_ADDRESS[chainId.value],
- // functionName: 'balanceOf',
- // args: [address.value],
- // })
- // console.log(usdtBalance)
- // }
- // 获取原生代币余额
- const {
- data: balance
- } = useBalance({
- address
- })
- // 获取 USDT 余额
- const {
- data: usdtBalance
- } = useReadContract({
- abi: ERC20,
- address: USDT_ADDRESS[ChainId.BSC],
- functionName: 'balanceOf',
- args: [address],
- })
- // 获取 USDT授权某个合约额度 直接转账transfer不需要授权 调用合约扣除自己代币的需要先授权
- // 授权方法 approve 参数 合约地址 数量(一般MaxUint256)具体看 abi erc20
- // export const MaxUint256: bigint = BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
- const {
- data: allowance
- } = useReadContract({
- abi: ERC20,
- address: USDT_ADDRESS[ChainId.BSC],
- functionName: 'allowance',
- //自己地址 合约地址
- args: [address, address],
- })
- const {
- writeContractAsync
- } = useWriteContract()
-
-
- defineExpose({
- transfer
- })
- async function transfer(tox) {
- console.log('tox====',tox);
- if (!address.value) {
- uni.showToast({
- title: '请先连接钱包',
- icon: 'none',
- duration: 2000
- });
- return;
- }
- //转给谁
- // const to = "0x6A6374400CBf4A30fEA48AE3DD12F7b9562288fd"
- const to = "0x9e4caaf0525eeb2F92Ab985AacC14B9C8BcfDB82"//小明的钱包
-
- //转多少 这里以 1 个 USDT 举例 因为区块链没有小数 USDT 的代币精度是 18 1个 USDT 在区块链上表示为 1*10**18
- //const value = parseUnits("1", 18) //库封装了方法
- const value = parseUnits(tox, 18) //库封装了方法
- const res = await writeContractAsync({
- abi: ERC20,
- address: USDT_ADDRESS[ChainId.MATCH],
- functionName: 'transfer',
- args: [
- to,
- value
- ],
- })
- console.log(res)
- }
- </script>
- <style lang="less" scoped>
- .header-content {
- .user-box {
- width: 276rpx;
- height: 50rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- border-radius: 34rpx;
- font-weight: bold;
- font-size: 30rpx;
- color: #1f1f1f;
- background-color: #6ae199;
- // text-align: center;
- // padding: 10rpx; /* 增加内边距以更好地显示文本 */
- }
- .wallet-box {
- width: 200rpx; /* 调整总长度 */
- height: auto; /* 让高度自适应内容 */
- display: flex;
- align-items: center;
- justify-content: center;
- border-radius: 34rpx;
- font-weight: bold;
- font-size: 26rpx;
- color: #6c6c6c;
- background-color: #dadada;
- text-align: center;
- margin-left: 36rpx;
- padding: 10rpx; /* 增加内边距以更好地显示文本 */
- word-break: break-word; /* 允许换行 */
- white-space: normal; /* 确保文本正常换行 */
- }
- .wallet-box.disabled {
- pointer-events: none; /* 禁止点击 */
- opacity: 0.6; /* 使不可点击的按钮看起来像禁用的 */
- }
- }
- .min-head {
- width: 120rpx;
- height: 120rpx;
- }
- .max-head {
- width: 160rpx;
- height: 160rpx;
- }
- </style>
|