Initial commit: Complete MetaMask integration for ChainID 138
This commit is contained in:
95
scripts/create-proxmox-token.sh
Executable file
95
scripts/create-proxmox-token.sh
Executable file
@@ -0,0 +1,95 @@
|
||||
#!/bin/bash
|
||||
# Script to create a Proxmox API token via the Proxmox API
|
||||
#
|
||||
# Usage:
|
||||
# ./create-proxmox-token.sh <proxmox-host> <username> <password> <token-name>
|
||||
#
|
||||
# Example:
|
||||
# ./create-proxmox-token.sh 192.168.1.100 root@pam mypassword mcp-server
|
||||
#
|
||||
# Note: This requires valid Proxmox credentials and uses the Proxmox API v2
|
||||
|
||||
set -e
|
||||
|
||||
PROXMOX_HOST="${1:-}"
|
||||
USERNAME="${2:-}"
|
||||
PASSWORD="${3:-}"
|
||||
TOKEN_NAME="${4:-mcp-server}"
|
||||
PROXMOX_PORT="${PROXMOX_PORT:-8006}"
|
||||
|
||||
if [ -z "$PROXMOX_HOST" ] || [ -z "$USERNAME" ] || [ -z "$PASSWORD" ]; then
|
||||
echo "Usage: $0 <proxmox-host> <username> <password> [token-name]"
|
||||
echo ""
|
||||
echo "Example:"
|
||||
echo " $0 192.168.1.100 root@pam mypassword mcp-server"
|
||||
echo ""
|
||||
echo "Environment variables:"
|
||||
echo " PROXMOX_PORT - Proxmox port (default: 8006)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Creating Proxmox API token..."
|
||||
echo "Host: $PROXMOX_HOST:$PROXMOX_PORT"
|
||||
echo "User: $USERNAME"
|
||||
echo "Token Name: $TOKEN_NAME"
|
||||
echo ""
|
||||
|
||||
# Step 1: Get CSRF token and ticket by authenticating
|
||||
echo "Authenticating..."
|
||||
AUTH_RESPONSE=$(curl -s -k -d "username=$USERNAME&password=$PASSWORD" \
|
||||
"https://${PROXMOX_HOST}:${PROXMOX_PORT}/api2/json/access/ticket")
|
||||
|
||||
if echo "$AUTH_RESPONSE" | grep -q "data"; then
|
||||
TICKET=$(echo "$AUTH_RESPONSE" | grep -oP '"ticket":"\K[^"]+')
|
||||
CSRF_TOKEN=$(echo "$AUTH_RESPONSE" | grep -oP '"CSRFPreventionToken":"\K[^"]+')
|
||||
|
||||
if [ -z "$TICKET" ] || [ -z "$CSRF_TOKEN" ]; then
|
||||
echo "Error: Failed to authenticate. Check credentials."
|
||||
echo "Response: $AUTH_RESPONSE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✓ Authentication successful"
|
||||
else
|
||||
echo "Error: Authentication failed"
|
||||
echo "Response: $AUTH_RESPONSE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Step 2: Create API token
|
||||
echo "Creating API token..."
|
||||
TOKEN_RESPONSE=$(curl -s -k -X POST \
|
||||
-H "Cookie: PVEAuthCookie=$TICKET" \
|
||||
-H "CSRFPreventionToken: $CSRF_TOKEN" \
|
||||
-d "tokenid=${USERNAME}!${TOKEN_NAME}" \
|
||||
"https://${PROXMOX_HOST}:${PROXMOX_PORT}/api2/json/access/users/${USERNAME}/token/${TOKEN_NAME}")
|
||||
|
||||
if echo "$TOKEN_RESPONSE" | grep -q "data"; then
|
||||
TOKEN_VALUE=$(echo "$TOKEN_RESPONSE" | grep -oP '"value":"\K[^"]+')
|
||||
|
||||
if [ -z "$TOKEN_VALUE" ]; then
|
||||
echo "Error: Token created but could not extract value"
|
||||
echo "Response: $TOKEN_RESPONSE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✅ API Token created successfully!"
|
||||
echo ""
|
||||
echo "Add these to your ~/.env file:"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "PROXMOX_HOST=$PROXMOX_HOST"
|
||||
echo "PROXMOX_USER=$USERNAME"
|
||||
echo "PROXMOX_TOKEN_NAME=$TOKEN_NAME"
|
||||
echo "PROXMOX_TOKEN_VALUE=$TOKEN_VALUE"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "⚠️ IMPORTANT: Save the PROXMOX_TOKEN_VALUE immediately!"
|
||||
echo " This is the only time it will be displayed."
|
||||
echo ""
|
||||
else
|
||||
echo "Error: Failed to create token"
|
||||
echo "Response: $TOKEN_RESPONSE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
72
scripts/fix-token-reference.sh
Executable file
72
scripts/fix-token-reference.sh
Executable file
@@ -0,0 +1,72 @@
|
||||
#!/bin/bash
|
||||
# Fix token reference - checks if token needs to be updated
|
||||
# This script helps identify if the token value is still a placeholder
|
||||
|
||||
ENV_FILE="$HOME/.env"
|
||||
|
||||
if [ ! -f "$ENV_FILE" ]; then
|
||||
echo "❌ .env file not found: $ENV_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check current token value
|
||||
TOKEN_VALUE=$(grep "^PROXMOX_TOKEN_VALUE=" "$ENV_FILE" | cut -d'=' -f2- | tr -d '"' | tr -d "'")
|
||||
|
||||
PLACEHOLDERS=(
|
||||
"your-token-secret-here"
|
||||
"your-token-secret"
|
||||
"your-token-secret-value"
|
||||
""
|
||||
)
|
||||
|
||||
IS_PLACEHOLDER=false
|
||||
for placeholder in "${PLACEHOLDERS[@]}"; do
|
||||
if [ "$TOKEN_VALUE" = "$placeholder" ]; then
|
||||
IS_PLACEHOLDER=true
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$IS_PLACEHOLDER" = true ]; then
|
||||
echo "⚠️ Token value is still a placeholder"
|
||||
echo ""
|
||||
echo "Current value: $TOKEN_VALUE"
|
||||
echo ""
|
||||
echo "To fix:"
|
||||
echo " 1. Run: ./scripts/update-token.sh"
|
||||
echo " 2. Or manually edit: $ENV_FILE"
|
||||
echo " Change PROXMOX_TOKEN_VALUE to the actual token secret"
|
||||
echo ""
|
||||
echo "The token was created with ID: bff429d3-f408-4139-807a-7bf163525275"
|
||||
echo "You need the SECRET value (shown only once when token was created)"
|
||||
exit 1
|
||||
else
|
||||
TOKEN_LEN=${#TOKEN_VALUE}
|
||||
if [ $TOKEN_LEN -lt 20 ]; then
|
||||
echo "⚠️ Token value seems too short ($TOKEN_LEN chars)"
|
||||
echo " Expected: 30+ characters (UUID format)"
|
||||
else
|
||||
echo "✅ Token value appears configured ($TOKEN_LEN characters)"
|
||||
echo " Testing connection..."
|
||||
|
||||
# Test connection
|
||||
source scripts/load-env.sh
|
||||
load_env_file
|
||||
|
||||
API_RESPONSE=$(curl -k -s -w "\n%{http_code}" -m 10 \
|
||||
-H "Authorization: PVEAPIToken=${PROXMOX_USER}!${PROXMOX_TOKEN_NAME}=${PROXMOX_TOKEN_VALUE}" \
|
||||
"https://${PROXMOX_HOST}:${PROXMOX_PORT:-8006}/api2/json/version" 2>&1)
|
||||
|
||||
HTTP_CODE=$(echo "$API_RESPONSE" | tail -1)
|
||||
|
||||
if [ "$HTTP_CODE" = "200" ]; then
|
||||
echo "✅ API connection successful!"
|
||||
exit 0
|
||||
else
|
||||
echo "❌ API connection failed (HTTP $HTTP_CODE)"
|
||||
echo " Token may be incorrect or expired"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
158
scripts/host-token-list.sh
Executable file
158
scripts/host-token-list.sh
Executable file
@@ -0,0 +1,158 @@
|
||||
#!/usr/bin/env bash
|
||||
# Script to prepare token list for public hosting
|
||||
# Usage: ./host-token-list.sh [hosting-method]
|
||||
# Options: github, ipfs, local
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
TOKEN_LIST_FILE="$PROJECT_ROOT/docs/METAMASK_TOKEN_LIST.json"
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
||||
log_success() { echo -e "${GREEN}[✓]${NC} $1"; }
|
||||
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
||||
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||||
|
||||
HOSTING_METHOD="${1:-github}"
|
||||
|
||||
log_info "========================================="
|
||||
log_info "Token List Hosting Preparation"
|
||||
log_info "========================================="
|
||||
log_info ""
|
||||
log_info "Method: $HOSTING_METHOD"
|
||||
log_info "Token List: $TOKEN_LIST_FILE"
|
||||
log_info ""
|
||||
|
||||
# Validate token list JSON
|
||||
if [ ! -f "$TOKEN_LIST_FILE" ]; then
|
||||
log_error "Token list file not found: $TOKEN_LIST_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! jq empty "$TOKEN_LIST_FILE" 2>/dev/null; then
|
||||
log_error "Token list JSON is invalid"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_success "Token list JSON is valid"
|
||||
|
||||
# Extract token list info
|
||||
TOKEN_LIST_NAME=$(jq -r '.name' "$TOKEN_LIST_FILE")
|
||||
TOKEN_LIST_VERSION=$(jq -r '.version | "\(.major).\(.minor).\(.patch)"' "$TOKEN_LIST_FILE")
|
||||
TOKEN_COUNT=$(jq '.tokens | length' "$TOKEN_LIST_FILE")
|
||||
|
||||
log_info "Token List: $TOKEN_LIST_NAME v$TOKEN_LIST_VERSION"
|
||||
log_info "Tokens: $TOKEN_COUNT"
|
||||
log_info ""
|
||||
|
||||
case "$HOSTING_METHOD" in
|
||||
github)
|
||||
log_info "Preparing for GitHub Pages hosting..."
|
||||
log_info ""
|
||||
log_info "Steps to host on GitHub Pages:"
|
||||
log_info "1. Create a GitHub repository (or use existing)"
|
||||
log_info "2. Copy token-list.json to repository root"
|
||||
log_info "3. Enable GitHub Pages in repository settings"
|
||||
log_info "4. Access at: https://<username>.github.io/<repo>/token-list.json"
|
||||
log_info ""
|
||||
log_info "Creating token-list.json for GitHub..."
|
||||
|
||||
OUTPUT_FILE="$PROJECT_ROOT/token-list.json"
|
||||
cp "$TOKEN_LIST_FILE" "$OUTPUT_FILE"
|
||||
log_success "Created: $OUTPUT_FILE"
|
||||
log_info ""
|
||||
log_info "Next steps:"
|
||||
log_info "1. git add token-list.json"
|
||||
log_info "2. git commit -m 'Add MetaMask token list'"
|
||||
log_info "3. git push"
|
||||
log_info "4. Enable GitHub Pages in repo settings"
|
||||
;;
|
||||
|
||||
ipfs)
|
||||
log_info "Preparing for IPFS hosting..."
|
||||
log_info ""
|
||||
log_info "Note: Requires IPFS node running"
|
||||
log_info ""
|
||||
|
||||
if command -v ipfs &> /dev/null; then
|
||||
log_info "IPFS detected, adding file..."
|
||||
IPFS_HASH=$(ipfs add -q "$TOKEN_LIST_FILE" 2>/dev/null || echo "")
|
||||
|
||||
if [ -n "$IPFS_HASH" ]; then
|
||||
log_success "File added to IPFS"
|
||||
log_info "IPFS Hash: $IPFS_HASH"
|
||||
log_info "Access at: https://ipfs.io/ipfs/$IPFS_HASH"
|
||||
log_info "Or: https://gateway.pinata.cloud/ipfs/$IPFS_HASH"
|
||||
else
|
||||
log_warn "Could not add to IPFS (node may not be running)"
|
||||
log_info "Manual steps:"
|
||||
log_info "1. Start IPFS: ipfs daemon"
|
||||
log_info "2. Add file: ipfs add $TOKEN_LIST_FILE"
|
||||
log_info "3. Pin file: ipfs pin add <hash>"
|
||||
fi
|
||||
else
|
||||
log_warn "IPFS not installed"
|
||||
log_info "Install IPFS: https://docs.ipfs.io/install/"
|
||||
log_info "Or use IPFS web interface: https://ipfs.io"
|
||||
fi
|
||||
;;
|
||||
|
||||
local)
|
||||
log_info "Preparing for local hosting..."
|
||||
log_info ""
|
||||
log_info "For local testing or custom server hosting:"
|
||||
log_info ""
|
||||
log_info "1. Copy token-list.json to your web server"
|
||||
log_info "2. Ensure HTTPS is enabled"
|
||||
log_info "3. Set CORS headers:"
|
||||
log_info " Access-Control-Allow-Origin: *"
|
||||
log_info " Access-Control-Allow-Methods: GET, OPTIONS"
|
||||
log_info " Content-Type: application/json"
|
||||
log_info ""
|
||||
log_info "Example nginx config:"
|
||||
echo ""
|
||||
cat << 'EOF'
|
||||
location /token-list.json {
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
add_header Access-Control-Allow-Methods "GET, OPTIONS";
|
||||
add_header Content-Type application/json;
|
||||
try_files $uri =404;
|
||||
}
|
||||
EOF
|
||||
echo ""
|
||||
;;
|
||||
|
||||
*)
|
||||
log_error "Unknown hosting method: $HOSTING_METHOD"
|
||||
log_info "Available methods: github, ipfs, local"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
log_info ""
|
||||
log_info "Token List Summary:"
|
||||
log_info " Name: $TOKEN_LIST_NAME"
|
||||
log_info " Version: $TOKEN_LIST_VERSION"
|
||||
log_info " Tokens: $TOKEN_COUNT"
|
||||
log_info ""
|
||||
|
||||
# List tokens
|
||||
log_info "Tokens in list:"
|
||||
jq -r '.tokens[] | " - \(.symbol) (\(.name)): \(.address)"' "$TOKEN_LIST_FILE"
|
||||
|
||||
log_info ""
|
||||
log_success "Token list preparation complete!"
|
||||
log_info ""
|
||||
log_info "To add to MetaMask:"
|
||||
log_info "1. Settings → Security & Privacy → Token Lists"
|
||||
log_info "2. Add custom token list URL"
|
||||
log_info "3. Enter your hosted URL"
|
||||
|
||||
255
scripts/setup-metamask-integration.sh
Executable file
255
scripts/setup-metamask-integration.sh
Executable file
@@ -0,0 +1,255 @@
|
||||
#!/usr/bin/env bash
|
||||
# Set up MetaMask integration for ChainID 138 with Oracle price feeds
|
||||
# Usage: ./setup-metamask-integration.sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
|
||||
# Contract addresses
|
||||
ORACLE_PROXY="0x3304b747e565a97ec8ac220b0b6a1f6ffdb837e6"
|
||||
RPC_URL="https://rpc-core.d-bis.org"
|
||||
CHAIN_ID="138"
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
||||
log_success() { echo -e "${GREEN}[✓]${NC} $1"; }
|
||||
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
||||
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||||
|
||||
log_info "========================================="
|
||||
log_info "MetaMask Integration Setup"
|
||||
log_info "========================================="
|
||||
log_info ""
|
||||
|
||||
# Create MetaMask network configuration
|
||||
log_info "Creating MetaMask network configuration..."
|
||||
|
||||
cat > "$PROJECT_ROOT/docs/METAMASK_NETWORK_CONFIG.json" <<EOF
|
||||
{
|
||||
"chainId": "0x8a",
|
||||
"chainName": "SMOM-DBIS-138",
|
||||
"rpcUrls": [
|
||||
"$RPC_URL"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "Ether",
|
||||
"symbol": "ETH",
|
||||
"decimals": 18
|
||||
},
|
||||
"blockExplorerUrls": [
|
||||
"https://explorer.d-bis.org"
|
||||
],
|
||||
"iconUrls": [
|
||||
"https://raw.githubusercontent.com/ethereum/ethereum.org/main/static/images/eth-diamond-black.png"
|
||||
]
|
||||
}
|
||||
EOF
|
||||
|
||||
log_success "MetaMask network configuration created"
|
||||
|
||||
# Create token list for MetaMask
|
||||
log_info "Creating token list with Oracle price feed..."
|
||||
|
||||
cat > "$PROJECT_ROOT/docs/METAMASK_TOKEN_LIST.json" <<EOF
|
||||
{
|
||||
"name": "SMOM-DBIS-138 Token List",
|
||||
"version": {
|
||||
"major": 1,
|
||||
"minor": 0,
|
||||
"patch": 0
|
||||
},
|
||||
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%S.000Z)",
|
||||
"tokens": [
|
||||
{
|
||||
"chainId": 138,
|
||||
"address": "$ORACLE_PROXY",
|
||||
"name": "ETH/USD Price Feed",
|
||||
"symbol": "ETH-USD",
|
||||
"decimals": 8,
|
||||
"logoURI": "https://raw.githubusercontent.com/ethereum/ethereum.org/main/static/images/eth-diamond-black.png"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
|
||||
log_success "Token list created"
|
||||
|
||||
# Create Oracle integration guide
|
||||
log_info "Creating Oracle integration guide..."
|
||||
|
||||
cat > "$PROJECT_ROOT/docs/METAMASK_ORACLE_INTEGRATION.md" <<EOF
|
||||
# MetaMask Oracle Integration Guide
|
||||
|
||||
**Date**: $(date)
|
||||
**ChainID**: 138
|
||||
**Oracle Address**: $ORACLE_PROXY
|
||||
|
||||
---
|
||||
|
||||
## 📋 Overview
|
||||
|
||||
This guide explains how to integrate the deployed Oracle contract with MetaMask for ETH/USD price feeds.
|
||||
|
||||
---
|
||||
|
||||
## 🔗 Contract Information
|
||||
|
||||
- **Oracle Proxy Address**: \`$ORACLE_PROXY\`
|
||||
- **ChainID**: 138
|
||||
- **RPC Endpoint**: \`$RPC_URL\`
|
||||
- **Price Feed**: ETH/USD
|
||||
- **Decimals**: 8
|
||||
- **Update Frequency**: 60 seconds (heartbeat)
|
||||
|
||||
---
|
||||
|
||||
## 📝 MetaMask Network Configuration
|
||||
|
||||
### Method 1: Manual Configuration
|
||||
|
||||
1. Open MetaMask
|
||||
2. Click network dropdown → "Add Network" → "Add a network manually"
|
||||
3. Enter the following:
|
||||
- **Network Name**: SMOM-DBIS-138
|
||||
- **RPC URL**: \`$RPC_URL\`
|
||||
- **Chain ID**: 138
|
||||
- **Currency Symbol**: ETH
|
||||
- **Block Explorer**: https://explorer.d-bis.org (optional)
|
||||
|
||||
### Method 2: Import Configuration
|
||||
|
||||
Use the configuration file: \`docs/METAMASK_NETWORK_CONFIG.json\`
|
||||
|
||||
---
|
||||
|
||||
## 💰 Reading Price from Oracle
|
||||
|
||||
### Using Web3.js
|
||||
|
||||
\`\`\`javascript
|
||||
const Web3 = require('web3');
|
||||
const web3 = new Web3('$RPC_URL');
|
||||
|
||||
// Oracle Proxy ABI (simplified)
|
||||
const oracleABI = [
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "latestRoundData",
|
||||
"outputs": [
|
||||
{"name": "roundId", "type": "uint80"},
|
||||
{"name": "answer", "type": "int256"},
|
||||
{"name": "startedAt", "type": "uint256"},
|
||||
{"name": "updatedAt", "type": "uint256"},
|
||||
{"name": "answeredInRound", "type": "uint80"}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}
|
||||
];
|
||||
|
||||
const oracleAddress = '$ORACLE_PROXY';
|
||||
const oracle = new web3.eth.Contract(oracleABI, oracleAddress);
|
||||
|
||||
// Get latest price
|
||||
async function getPrice() {
|
||||
const result = await oracle.methods.latestRoundData().call();
|
||||
const price = result.answer / 1e8; // Convert from 8 decimals to USD
|
||||
console.log(\`ETH/USD Price: $\${price}\`);
|
||||
return price;
|
||||
}
|
||||
|
||||
getPrice();
|
||||
\`\`\`
|
||||
|
||||
### Using Ethers.js
|
||||
|
||||
\`\`\`javascript
|
||||
const { ethers } = require('ethers');
|
||||
|
||||
const provider = new ethers.providers.JsonRpcProvider('$RPC_URL');
|
||||
|
||||
// Oracle Proxy ABI (simplified)
|
||||
const oracleABI = [
|
||||
"function latestRoundData() external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)"
|
||||
];
|
||||
|
||||
const oracleAddress = '$ORACLE_PROXY';
|
||||
const oracle = new ethers.Contract(oracleAddress, oracleABI, provider);
|
||||
|
||||
// Get latest price
|
||||
async function getPrice() {
|
||||
const result = await oracle.latestRoundData();
|
||||
const price = result.answer.toNumber() / 1e8; // Convert from 8 decimals to USD
|
||||
console.log(\`ETH/USD Price: $\${price}\`);
|
||||
return price;
|
||||
}
|
||||
|
||||
getPrice();
|
||||
\`\`\`
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Oracle Publisher Service
|
||||
|
||||
The Oracle Publisher service (VMID 3500) automatically updates the Oracle contract with price feeds.
|
||||
|
||||
**Configuration**:
|
||||
- **Service**: Oracle Publisher
|
||||
- **VMID**: 3500
|
||||
- **Update Interval**: 60 seconds
|
||||
- **Price Source**: External API (e.g., CoinGecko, CoinMarketCap)
|
||||
|
||||
---
|
||||
|
||||
## ✅ Verification
|
||||
|
||||
### Check Oracle is Updating
|
||||
|
||||
\`\`\`bash
|
||||
# Query latest round data
|
||||
cast call $ORACLE_PROXY "latestRoundData()" --rpc-url $RPC_URL
|
||||
\`\`\`
|
||||
|
||||
### Check Update Frequency
|
||||
|
||||
The Oracle should update every 60 seconds (heartbeat). Monitor the \`updatedAt\` timestamp to verify.
|
||||
|
||||
---
|
||||
|
||||
## 📚 Additional Resources
|
||||
|
||||
- Oracle Contract: \`$ORACLE_PROXY\`
|
||||
- Network Config: \`docs/METAMASK_NETWORK_CONFIG.json\`
|
||||
- Token List: \`docs/METAMASK_TOKEN_LIST.json\`
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: $(date)
|
||||
EOF
|
||||
|
||||
log_success "Oracle integration guide created"
|
||||
|
||||
log_info ""
|
||||
log_success "========================================="
|
||||
log_success "MetaMask Integration Setup Complete!"
|
||||
log_success "========================================="
|
||||
log_info ""
|
||||
log_info "Created files:"
|
||||
log_info " - docs/METAMASK_NETWORK_CONFIG.json"
|
||||
log_info " - docs/METAMASK_TOKEN_LIST.json"
|
||||
log_info " - docs/METAMASK_ORACLE_INTEGRATION.md"
|
||||
log_info ""
|
||||
log_info "Next steps:"
|
||||
log_info "1. Add network to MetaMask using the configuration file"
|
||||
log_info "2. Verify Oracle Publisher service is updating prices"
|
||||
log_info "3. Test reading price from Oracle contract"
|
||||
log_info ""
|
||||
|
||||
188
scripts/test-metamask-integration.sh
Executable file
188
scripts/test-metamask-integration.sh
Executable file
@@ -0,0 +1,188 @@
|
||||
#!/usr/bin/env bash
|
||||
# End-to-end MetaMask integration test script
|
||||
# Tests network, RPC, tokens, and price feeds
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
||||
log_success() { echo -e "${GREEN}[✓]${NC} $1"; }
|
||||
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
||||
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||||
|
||||
RPC_URL="${RPC_URL:-https://rpc-core.d-bis.org}"
|
||||
CHAIN_ID=138
|
||||
|
||||
# Contract addresses
|
||||
ORACLE_PROXY="0x3304b747e565a97ec8ac220b0b6a1f6ffdb837e6"
|
||||
WETH9="0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
|
||||
WETH10="0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f"
|
||||
|
||||
log_info "========================================="
|
||||
log_info "MetaMask Integration Test"
|
||||
log_info "========================================="
|
||||
log_info ""
|
||||
log_info "RPC URL: $RPC_URL"
|
||||
log_info "Chain ID: $CHAIN_ID"
|
||||
log_info ""
|
||||
|
||||
PASSED=0
|
||||
FAILED=0
|
||||
|
||||
test_rpc_connection() {
|
||||
log_info "Test 1: RPC Connection"
|
||||
if cast block-number --rpc-url "$RPC_URL" &>/dev/null; then
|
||||
BLOCK=$(cast block-number --rpc-url "$RPC_URL" 2>/dev/null)
|
||||
log_success "RPC connected - Block: $BLOCK"
|
||||
((PASSED++))
|
||||
return 0
|
||||
else
|
||||
log_error "RPC connection failed"
|
||||
((FAILED++))
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
test_chain_id() {
|
||||
log_info "Test 2: Chain ID"
|
||||
ACTUAL_CHAIN_ID=$(cast chain-id --rpc-url "$RPC_URL" 2>/dev/null || echo "0")
|
||||
if [ "$ACTUAL_CHAIN_ID" = "$CHAIN_ID" ]; then
|
||||
log_success "Chain ID correct: $CHAIN_ID"
|
||||
((PASSED++))
|
||||
return 0
|
||||
else
|
||||
log_error "Chain ID mismatch - Expected: $CHAIN_ID, Got: $ACTUAL_CHAIN_ID"
|
||||
((FAILED++))
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
test_weth9_contract() {
|
||||
log_info "Test 3: WETH9 Contract"
|
||||
if cast code "$WETH9" --rpc-url "$RPC_URL" 2>/dev/null | grep -q "0x"; then
|
||||
SUPPLY=$(cast call "$WETH9" "totalSupply()" --rpc-url "$RPC_URL" 2>/dev/null | xargs -I {} cast --to-unit {} ether 2>/dev/null || echo "0")
|
||||
log_success "WETH9 contract exists - Total Supply: $SUPPLY WETH"
|
||||
((PASSED++))
|
||||
return 0
|
||||
else
|
||||
log_error "WETH9 contract not found"
|
||||
((FAILED++))
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
test_weth10_contract() {
|
||||
log_info "Test 4: WETH10 Contract"
|
||||
if cast code "$WETH10" --rpc-url "$RPC_URL" 2>/dev/null | grep -q "0x"; then
|
||||
log_success "WETH10 contract exists"
|
||||
((PASSED++))
|
||||
return 0
|
||||
else
|
||||
log_error "WETH10 contract not found"
|
||||
((FAILED++))
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
test_oracle_contract() {
|
||||
log_info "Test 5: Oracle Contract"
|
||||
if cast code "$ORACLE_PROXY" --rpc-url "$RPC_URL" 2>/dev/null | grep -q "0x"; then
|
||||
# Try to get price data
|
||||
PRICE_DATA=$(cast call "$ORACLE_PROXY" "latestRoundData()" --rpc-url "$RPC_URL" 2>/dev/null || echo "")
|
||||
if [ -n "$PRICE_DATA" ] && [ "$PRICE_DATA" != "0x" ]; then
|
||||
log_success "Oracle contract exists and responds"
|
||||
((PASSED++))
|
||||
return 0
|
||||
else
|
||||
log_warn "Oracle contract exists but may not be updating"
|
||||
((PASSED++))
|
||||
return 0
|
||||
fi
|
||||
else
|
||||
log_error "Oracle contract not found"
|
||||
((FAILED++))
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
test_token_list_json() {
|
||||
log_info "Test 6: Token List JSON"
|
||||
TOKEN_LIST="$PROJECT_ROOT/docs/METAMASK_TOKEN_LIST.json"
|
||||
if [ -f "$TOKEN_LIST" ]; then
|
||||
if jq empty "$TOKEN_LIST" 2>/dev/null; then
|
||||
TOKEN_COUNT=$(jq '.tokens | length' "$TOKEN_LIST" 2>/dev/null || echo "0")
|
||||
log_success "Token list JSON valid - $TOKEN_COUNT tokens"
|
||||
((PASSED++))
|
||||
return 0
|
||||
else
|
||||
log_error "Token list JSON is invalid"
|
||||
((FAILED++))
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
log_error "Token list JSON not found"
|
||||
((FAILED++))
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
test_network_config() {
|
||||
log_info "Test 7: Network Configuration"
|
||||
NETWORK_CONFIG="$PROJECT_ROOT/docs/METAMASK_NETWORK_CONFIG.json"
|
||||
if [ -f "$NETWORK_CONFIG" ]; then
|
||||
if jq empty "$NETWORK_CONFIG" 2>/dev/null; then
|
||||
CONFIG_CHAIN_ID=$(jq -r '.chainId' "$NETWORK_CONFIG" 2>/dev/null | sed 's/0x//' | xargs -I {} echo "ibase=16; {}" | bc 2>/dev/null || echo "0")
|
||||
if [ "$CONFIG_CHAIN_ID" = "$CHAIN_ID" ]; then
|
||||
log_success "Network config valid - Chain ID: $CHAIN_ID"
|
||||
((PASSED++))
|
||||
return 0
|
||||
else
|
||||
log_error "Network config Chain ID mismatch"
|
||||
((FAILED++))
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
log_error "Network config JSON is invalid"
|
||||
((FAILED++))
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
log_error "Network config JSON not found"
|
||||
((FAILED++))
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Run all tests
|
||||
test_rpc_connection
|
||||
test_chain_id
|
||||
test_weth9_contract
|
||||
test_weth10_contract
|
||||
test_oracle_contract
|
||||
test_token_list_json
|
||||
test_network_config
|
||||
|
||||
# Summary
|
||||
log_info ""
|
||||
log_info "========================================="
|
||||
log_info "Test Summary"
|
||||
log_info "========================================="
|
||||
log_info "Passed: $PASSED"
|
||||
if [ $FAILED -gt 0 ]; then
|
||||
log_error "Failed: $FAILED"
|
||||
exit 1
|
||||
else
|
||||
log_success "Failed: $FAILED"
|
||||
log_success "All tests passed!"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
52
scripts/update-token.sh
Executable file
52
scripts/update-token.sh
Executable file
@@ -0,0 +1,52 @@
|
||||
#!/bin/bash
|
||||
# Script to update PROXMOX_TOKEN_VALUE in .env file
|
||||
|
||||
ENV_FILE="$HOME/.env"
|
||||
|
||||
if [ ! -f "$ENV_FILE" ]; then
|
||||
echo "❌ .env file not found at $ENV_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "🔐 Update Proxmox API Token"
|
||||
echo "============================"
|
||||
echo ""
|
||||
echo "Please paste the token secret you copied from Proxmox UI:"
|
||||
echo "(The secret will be hidden as you type)"
|
||||
echo ""
|
||||
read -s TOKEN_VALUE
|
||||
|
||||
if [ -z "$TOKEN_VALUE" ]; then
|
||||
echo "❌ No token value provided"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Update the .env file
|
||||
if grep -q "^PROXMOX_TOKEN_VALUE=" "$ENV_FILE"; then
|
||||
# Use sed to update the line (works with special characters)
|
||||
sed -i "s|^PROXMOX_TOKEN_VALUE=.*|PROXMOX_TOKEN_VALUE=$TOKEN_VALUE|" "$ENV_FILE"
|
||||
echo ""
|
||||
echo "✅ Token updated in $ENV_FILE"
|
||||
else
|
||||
echo "❌ PROXMOX_TOKEN_VALUE not found in .env file"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Verifying configuration..."
|
||||
if grep -q "^PROXMOX_TOKEN_VALUE=$TOKEN_VALUE" "$ENV_FILE"; then
|
||||
echo "✅ Token successfully configured!"
|
||||
echo ""
|
||||
echo "Current configuration:"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
grep "^PROXMOX_" "$ENV_FILE" | grep -v "TOKEN_VALUE" | sed 's/=.*/=***/'
|
||||
echo "PROXMOX_TOKEN_VALUE=***configured***"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "You can now test the connection:"
|
||||
echo " ./verify-setup.sh"
|
||||
echo " pnpm test:basic"
|
||||
else
|
||||
echo "⚠️ Token may not have been updated correctly"
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user