chore: sync submodule state (parent ref update)

Made-with: Cursor
This commit is contained in:
defiQUG
2026-03-02 12:14:14 -08:00
parent b6a776e5d7
commit 25c96e210a
316 changed files with 29779 additions and 677 deletions

View File

@@ -0,0 +1,59 @@
# MetaMask ChainID 138 Vue.js Example
Complete Vue.js 3 example for integrating MetaMask with ChainID 138.
## Features
- ✅ Connect to MetaMask wallet
- ✅ Add ChainID 138 network
- ✅ Switch to ChainID 138 network
- ✅ Add tokens (cUSDT, cUSDC, WETH)
- ✅ Display wallet balance
- ✅ Error handling
- ✅ TypeScript support
## Installation
```bash
npm install
```
## Development
```bash
npm run dev
```
## Build
```bash
npm run build
```
## Usage
1. Install MetaMask browser extension
2. Open the application
3. Click "Connect Wallet"
4. Approve connection in MetaMask
5. Add ChainID 138 network if needed
6. Add tokens to MetaMask
## Code Structure
- `App.vue` - Main component with wallet connection logic
- Uses Composition API with `<script setup>`
- Uses `ethers.js` v6 for blockchain interactions
## Network Configuration
The example includes ChainID 138 network configuration:
- Chain ID: 138 (0x8a)
- RPC URLs: https://rpc.d-bis.org, https://rpc2.d-bis.org
- Explorer: https://explorer.d-bis.org
## Token Addresses
- cUSDT: `0x93E66202A11B1772E55407B32B44e5Cd8eda7f22` (6 decimals)
- cUSDC: `0xf22258f57794CC8E06237084b353Ab30fFfa640b` (6 decimals)
- WETH: `0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2` (18 decimals)

View File

@@ -0,0 +1,21 @@
{
"name": "metamask-chain138-vue-example",
"version": "1.0.0",
"description": "Vue.js example for MetaMask integration with ChainID 138",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vue-tsc && vite build",
"preview": "vite preview"
},
"dependencies": {
"vue": "^3.3.4",
"ethers": "^6.9.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.4.0",
"typescript": "^5.2.0",
"vite": "^5.0.0",
"vue-tsc": "^1.8.22"
}
}

View File

@@ -0,0 +1,277 @@
<template>
<div class="app">
<div class="container">
<h1>MetaMask ChainID 138 Vue Example</h1>
<div v-if="!isMetaMaskInstalled" class="error">
MetaMask is not installed. Please install MetaMask extension.
</div>
<div v-if="error" class="error">
{{ error }}
</div>
<div v-if="!isConnected">
<button @click="connectWallet" class="btn btn-primary">
Connect Wallet
</button>
</div>
<div v-else class="wallet-info">
<h2>Wallet Connected</h2>
<p><strong>Account:</strong> {{ account }}</p>
<p><strong>Chain ID:</strong> {{ chainId }}</p>
<p><strong>Balance:</strong> {{ balance }} ETH</p>
<div v-if="!isOnChain138" class="network-section">
<h3>Network Setup</h3>
<button @click="addChain138" class="btn btn-secondary">
Add ChainID 138
</button>
<button @click="switchToChain138" class="btn btn-secondary">
Switch to ChainID 138
</button>
</div>
<div v-if="isOnChain138" class="tokens-section">
<h3>Add Tokens</h3>
<button @click="addToken('cUSDT', tokens.cUSDT, 6)" class="btn btn-token">
Add cUSDT
</button>
<button @click="addToken('cUSDC', tokens.cUSDC, 6)" class="btn btn-token">
Add cUSDC
</button>
<button @click="addToken('WETH', tokens.WETH, 18)" class="btn btn-token">
Add WETH
</button>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue';
import { ethers } from 'ethers';
// ChainID 138 Network Configuration
const CHAIN_138_CONFIG = {
chainId: '0x8a',
chainName: 'DeFi Oracle Meta Mainnet',
nativeCurrency: {
name: 'Ether',
symbol: 'ETH',
decimals: 18,
},
rpcUrls: ['https://rpc.d-bis.org', 'https://rpc2.d-bis.org'],
blockExplorerUrls: ['https://explorer.d-bis.org'],
};
// Token addresses
const tokens = {
cUSDT: '0x93E66202A11B1772E55407B32B44e5Cd8eda7f22',
cUSDC: '0xf22258f57794CC8E06237084b353Ab30fFfa640b',
WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
};
const account = ref<string | null>(null);
const chainId = ref<string | null>(null);
const balance = ref<string>('0');
const isConnected = ref(false);
const error = ref<string | null>(null);
const isMetaMaskInstalled = typeof window.ethereum !== 'undefined';
const isOnChain138 = computed(() => chainId.value === '138');
const connectWallet = async () => {
if (!isMetaMaskInstalled) {
error.value = 'MetaMask is not installed. Please install MetaMask extension.';
return;
}
try {
const provider = new ethers.BrowserProvider(window.ethereum);
const accounts = await provider.send('eth_requestAccounts', []);
if (accounts.length > 0) {
account.value = accounts[0];
isConnected.value = true;
error.value = null;
const network = await provider.getNetwork();
chainId.value = network.chainId.toString();
const bal = await provider.getBalance(accounts[0]);
balance.value = ethers.formatEther(bal);
}
} catch (err: any) {
error.value = err.message || 'Failed to connect wallet';
}
};
const addChain138 = async () => {
if (!isMetaMaskInstalled) {
error.value = 'MetaMask is not installed';
return;
}
try {
await window.ethereum.request({
method: 'wallet_addEthereumChain',
params: [CHAIN_138_CONFIG],
});
error.value = null;
} catch (err: any) {
error.value = err.message || 'Failed to add network';
}
};
const switchToChain138 = async () => {
if (!isMetaMaskInstalled) {
error.value = 'MetaMask is not installed';
return;
}
try {
await window.ethereum.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId: CHAIN_138_CONFIG.chainId }],
});
error.value = null;
const provider = new ethers.BrowserProvider(window.ethereum);
const network = await provider.getNetwork();
chainId.value = network.chainId.toString();
} catch (err: any) {
if ((err as any).code === 4902) {
await addChain138();
} else {
error.value = (err as any).message || 'Failed to switch network';
}
}
};
const addToken = async (symbol: string, address: string, decimals: number) => {
if (!isMetaMaskInstalled) {
error.value = 'MetaMask is not installed';
return;
}
try {
await window.ethereum.request({
method: 'wallet_watchAsset',
params: {
type: 'ERC20',
options: {
address: address,
symbol: symbol,
decimals: decimals,
},
},
});
error.value = null;
} catch (err: any) {
error.value = err.message || 'Failed to add token';
}
};
</script>
<style scoped>
.app {
min-height: 100vh;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
.container {
background: white;
border-radius: 20px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
padding: 40px;
max-width: 600px;
width: 100%;
}
h1 {
color: #333;
margin-bottom: 20px;
font-size: 28px;
}
h2 {
color: #333;
margin-bottom: 15px;
font-size: 22px;
}
h3 {
color: #555;
margin-bottom: 10px;
font-size: 18px;
}
.wallet-info {
margin-top: 20px;
}
.wallet-info p {
margin: 10px 0;
color: #666;
}
.network-section,
.tokens-section {
margin-top: 30px;
padding-top: 20px;
border-top: 1px solid #eee;
}
.btn {
padding: 12px 24px;
border: none;
border-radius: 8px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s;
margin: 5px;
}
.btn-primary {
background: #667eea;
color: white;
}
.btn-primary:hover {
background: #5568d3;
}
.btn-secondary {
background: #48bb78;
color: white;
}
.btn-secondary:hover {
background: #38a169;
}
.btn-token {
background: #ed8936;
color: white;
}
.btn-token:hover {
background: #dd6b20;
}
.error {
background: #fed7d7;
color: #c53030;
padding: 15px;
border-radius: 8px;
margin-bottom: 20px;
}
</style>