Описание изменений
This commit is contained in:
@@ -4,9 +4,7 @@
|
||||
|
||||
<div v-if="!isConnected" class="warning">
|
||||
Пожалуйста, подключите кошелек для управления контрактом
|
||||
<button @click="handleConnect" class="connect-button">
|
||||
Подключить кошелек
|
||||
</button>
|
||||
<appkit-button />
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
@@ -39,6 +37,7 @@
|
||||
import { ref, onMounted, watch } from 'vue';
|
||||
import { ethers } from 'ethers';
|
||||
import { useAppKitAccount, useAppKitProvider, useAppKit } from '@reown/appkit/vue';
|
||||
import config from '../config';
|
||||
|
||||
export default {
|
||||
name: 'ContractInteraction',
|
||||
@@ -48,17 +47,11 @@ export default {
|
||||
const loading = ref(false);
|
||||
const { address, isConnected } = useAppKitAccount();
|
||||
const { walletProvider } = useAppKitProvider('eip155');
|
||||
const appKit = useAppKit();
|
||||
const { contractAddress, contractABI } = config.contract;
|
||||
|
||||
const contractAddress = '0x6199Ba629C85Da887dBd8Ffd8d2C75Ea24EaDe2a';
|
||||
const contractABI = [
|
||||
'function owner() view returns (address)',
|
||||
'function setOwner(address newOwner)',
|
||||
];
|
||||
const { open } = useAppKit(); // Получаем функцию открытия модала
|
||||
|
||||
const formatAddress = (addr) => {
|
||||
return addr.slice(0, 6) + '...' + addr.slice(-4);
|
||||
};
|
||||
const formatAddress = (addr) => addr.slice(0, 6) + '...' + addr.slice(-4);
|
||||
|
||||
const isValidAddress = (addr) => {
|
||||
try {
|
||||
@@ -68,14 +61,31 @@ export default {
|
||||
}
|
||||
};
|
||||
|
||||
// Добавим логирование для отладки
|
||||
watch(() => isConnected, (newValue) => {
|
||||
console.log('Состояние подключения изменилось:', newValue);
|
||||
console.log('Адрес кошелька:', address);
|
||||
}, { immediate: true });
|
||||
// Следим за изменением состояния подключения
|
||||
watch(isConnected, async (newValue) => {
|
||||
console.log('Connection state changed:', newValue);
|
||||
if (newValue) {
|
||||
await fetchOwner();
|
||||
} else {
|
||||
owner.value = '';
|
||||
}
|
||||
});
|
||||
|
||||
const handleConnect = async () => {
|
||||
try {
|
||||
console.log('Attempting to connect wallet...');
|
||||
await open(); // Используем хуки для открытия модала
|
||||
console.log('Wallet connected successfully');
|
||||
} catch (error) {
|
||||
console.error('Wallet connection error:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const fetchOwner = async () => {
|
||||
if (!isConnected) return;
|
||||
if (!isConnected.value || !walletProvider) {
|
||||
console.log('Cannot fetch owner: wallet not connected');
|
||||
return;
|
||||
}
|
||||
loading.value = true;
|
||||
try {
|
||||
console.log('Получаем владельца контракта...');
|
||||
@@ -93,7 +103,7 @@ export default {
|
||||
|
||||
const setNewOwner = async () => {
|
||||
try {
|
||||
if (!isConnected) {
|
||||
if (!isConnected.value) {
|
||||
console.log('Пожалуйста, подключите кошелек');
|
||||
return;
|
||||
}
|
||||
@@ -109,37 +119,17 @@ export default {
|
||||
const tx = await contract.setOwner(newOwner.value);
|
||||
await tx.wait();
|
||||
|
||||
// Обновляем информацию после успешной транзакции
|
||||
await fetchOwner();
|
||||
newOwner.value = ''; // Очищаем поле ввода
|
||||
newOwner.value = '';
|
||||
} catch (error) {
|
||||
console.error('Ошибка при установке нового владельца:', error);
|
||||
}
|
||||
};
|
||||
|
||||
// Обработчик подключения кошелька
|
||||
const handleConnect = async () => {
|
||||
try {
|
||||
await appKit.open();
|
||||
} catch (error) {
|
||||
console.error('Ошибка при подключении:', error);
|
||||
onMounted(async () => {
|
||||
if (isConnected.value) {
|
||||
await fetchOwner();
|
||||
}
|
||||
};
|
||||
|
||||
// Обновляем watch
|
||||
watch(() => isConnected, (newValue, oldValue) => {
|
||||
console.log('Состояние подключения изменилось:', { newValue, oldValue });
|
||||
if (newValue) {
|
||||
fetchOwner();
|
||||
} else {
|
||||
owner.value = '';
|
||||
}
|
||||
}, { immediate: true });
|
||||
|
||||
onMounted(() => {
|
||||
// Проверяем состояние подключения при монтировании
|
||||
console.log('Компонент смонтирован, isConnected:', isConnected);
|
||||
fetchOwner();
|
||||
});
|
||||
|
||||
return {
|
||||
@@ -148,7 +138,6 @@ export default {
|
||||
isConnected,
|
||||
loading,
|
||||
handleConnect,
|
||||
walletProvider,
|
||||
setNewOwner,
|
||||
formatAddress,
|
||||
isValidAddress
|
||||
|
||||
@@ -5,4 +5,32 @@ export const projectId = '9a6515f7259ebccd149fd53341e01e6b'
|
||||
|
||||
export const networks = [sepolia]
|
||||
|
||||
export const ethersAdapter = new EthersAdapter()
|
||||
export const ethersAdapter = new EthersAdapter()
|
||||
|
||||
export const config = {
|
||||
ethereum: {
|
||||
networkUrl: import.meta.env.VITE_APP_ETHEREUM_NETWORK_URL as string,
|
||||
projectId: import.meta.env.VITE_APP_PROJECT_ID as string
|
||||
},
|
||||
api: {
|
||||
baseUrl: 'http://localhost:3000', // URL бэкенда
|
||||
endpoints: {
|
||||
verify: '/api/verify'
|
||||
}
|
||||
},
|
||||
contract: {
|
||||
address: '0x6199Ba629C85Da887dBd8Ffd8d2C75Ea24EaDe2a',
|
||||
abi: [
|
||||
'function owner() view returns (address)',
|
||||
'function setOwner(address newOwner)'
|
||||
]
|
||||
},
|
||||
metadata: {
|
||||
name: 'DApp for Business',
|
||||
description: 'Управление смарт-контрактом',
|
||||
url: window.location.origin,
|
||||
icons: ['https://avatars.githubusercontent.com/u/37784886']
|
||||
}
|
||||
};
|
||||
|
||||
export default config;
|
||||
7
frontend/src/env.d.ts
vendored
Normal file
7
frontend/src/env.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
declare module '*.vue' {
|
||||
import type { DefineComponent } from 'vue'
|
||||
const component: DefineComponent<{}, {}, any>
|
||||
export default component
|
||||
}
|
||||
@@ -3,103 +3,24 @@ import App from './App.vue';
|
||||
import { createAppKit } from '@reown/appkit/vue';
|
||||
import { EthersAdapter } from '@reown/appkit-adapter-ethers';
|
||||
import { sepolia } from '@reown/appkit/networks';
|
||||
import { createSIWEConfig, formatMessage } from '@reown/appkit-siwe';
|
||||
import config from './config'; // Импортируем конфигурацию
|
||||
|
||||
// Определяем базовый URL для API
|
||||
const BASE_URL = 'http://localhost:3000';
|
||||
|
||||
// 1. Get projectId
|
||||
const projectId = '9a6515f7259ebccd149fd53341e01e6b';
|
||||
|
||||
// 2. Create SIWE config
|
||||
const siweConfig = createSIWEConfig({
|
||||
getMessageParams: async () => ({
|
||||
domain: window.location.host,
|
||||
uri: window.location.origin,
|
||||
chains: [11155111], // Sepolia chainId
|
||||
statement: 'Подпишите это сообщение для входа в DApp for Business. Это безопасно и не требует оплаты.',
|
||||
}),
|
||||
createMessage: ({ address, ...args }) => formatMessage(args, address),
|
||||
getNonce: async () => {
|
||||
try {
|
||||
const res = await fetch(`${BASE_URL}/nonce`, {
|
||||
method: 'GET',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Accept': 'text/plain'
|
||||
}
|
||||
});
|
||||
if (!res.ok) throw new Error('Failed to get nonce');
|
||||
return await res.text();
|
||||
} catch (error) {
|
||||
console.error('Ошибка получения nonce:', error);
|
||||
throw error;
|
||||
}
|
||||
const appKit = createAppKit({
|
||||
adapters: [new EthersAdapter()],
|
||||
projectId: config.ethereum.projectId,
|
||||
networks: [sepolia],
|
||||
defaultNetwork: sepolia,
|
||||
metadata: config.metadata,
|
||||
features: {
|
||||
analytics: true
|
||||
},
|
||||
getSession: async () => {
|
||||
try {
|
||||
const res = await fetch(`${BASE_URL}/session`, {
|
||||
method: 'GET',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
});
|
||||
if (!res.ok) return null;
|
||||
return await res.json();
|
||||
} catch (error) {
|
||||
console.error('Ошибка получения сессии:', error);
|
||||
return null;
|
||||
}
|
||||
},
|
||||
verifyMessage: async ({ message, signature }) => {
|
||||
try {
|
||||
const res = await fetch(`${BASE_URL}/verify`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ message, signature }),
|
||||
credentials: 'include'
|
||||
});
|
||||
return res.ok;
|
||||
} catch (error) {
|
||||
console.error('Ошибка верификации:', error);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
signOut: async () => {
|
||||
try {
|
||||
await fetch(`${BASE_URL}/signout`, {
|
||||
method: 'GET',
|
||||
credentials: 'include'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Ошибка выхода:', error);
|
||||
}
|
||||
themeMode: 'light', // Добавляем светлую тему
|
||||
themeVariables: {
|
||||
'--w3m-color-mix': '#00BB7F',
|
||||
'--w3m-color-mix-strength': 40
|
||||
}
|
||||
});
|
||||
|
||||
// 3. Create AppKit instance
|
||||
createAppKit({
|
||||
adapters: [new EthersAdapter()],
|
||||
networks: [sepolia],
|
||||
projectId,
|
||||
metadata: {
|
||||
name: 'DApp for Business',
|
||||
description: 'Smart Contract Management DApp',
|
||||
url: window.location.origin,
|
||||
icons: ['https://avatars.githubusercontent.com/u/37784886']
|
||||
},
|
||||
defaultNetwork: sepolia,
|
||||
features: {
|
||||
analytics: true,
|
||||
connectMethodsOrder: ['wallet', 'email', 'social'],
|
||||
autoConnect: false
|
||||
},
|
||||
siweConfig
|
||||
});
|
||||
|
||||
const app = createApp(App);
|
||||
app.use(appKit); // Подключаем AppKit как плагин
|
||||
app.mount('#app');
|
||||
5
frontend/src/types/index.ts
Normal file
5
frontend/src/types/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export interface ContractState {
|
||||
owner: string;
|
||||
isConnected: boolean;
|
||||
loading: boolean;
|
||||
}
|
||||
9
frontend/src/utils/contract.ts
Normal file
9
frontend/src/utils/contract.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { ethers } from 'ethers';
|
||||
|
||||
export const formatAddress = (address: string): string => {
|
||||
return `${address.slice(0, 6)}...${address.slice(-4)}`;
|
||||
};
|
||||
|
||||
export const isValidAddress = (address: string): boolean => {
|
||||
return ethers.isAddress(address);
|
||||
};
|
||||
Reference in New Issue
Block a user