Как я разделяю свои стеки AMM на отдельный фронт и бэкэнд с автоматическими обновлениями контрактов

Как я разделяю свои стеки AMM на отдельный фронт и бэкэнд с автоматическими обновлениями контрактов

18 августа 2025 г.

Как я мигрировал свои стеки обмена AMM из монолитной структуры для очистки разделения с помощью автоматической синхронизации контракта

Введение

Строительство децентрализованных применений часто начинается со всего в комплекте. По мере того, как проекты растут и интегрируются в более крупные экосистемы, вам нужно чистое разделение проблем.

Это руководство рассказывает о том, как я отделил свой фронт обмена стеков AMM от его бэкэнда, интегрировал его в экосистему Pasifika Web3 Tech Hub и создал автоматическую синхронизацию адреса контракта.

Примечание: Этот проект изначально был разбит изLearnWeb3dao/Stacks-Ammбыть расширенным для общин Тихоокеанского острова.

Ключевые темы:

  • Стратегии разделения фронта/бэкэнд
  • Автоматизированный адрес контракта синхронизация
  • Интеграция с существующими экосистемами
  • Оптимизация готовой к производству

Обзор архитектуры

До:Монолитная структура со всем, что связано вместе

# Backend (Contract Development)
stacks-amm/
├── contracts/
├── deployments/
├── frontend/ (Integrated Ecosystem)
├── settings 
└── tests 

После:Чистое разделение с автоматической синхронизацией

# Backend (Contract Development)
pasifika-stacks-exchange/
├── contracts/
├── deployments/
├── settings/ 
└── tests/ 

# Frontend (Integrated Ecosystem)
pasifika-web3-fe/
├── app/
├── deployed_contracts/
├── lib/
├── public/
├── scripts/
└── src/config/

Ключевые шаги миграции

1. Анализ и планирование

  • Компоненты: AMM UI (своп, ликвидность, бассейны)
  • Зависимости: Стеки библиотеки, React/next.js Различия версий
  • Стратегия: Сохранить функциональность при принятии новых тематических тем.

2. Настройка зависимостей

npm install @stacks/connect @stacks/network @stacks/transactions

3. Структура каталога

pasifika-web3-fe/app/stacks-exchange/
├── page.tsx
├── components/
├── hooks/
└── lib/

Основная реализация

Интеграция основной страницы AMM

// app/stacks-exchange/page.tsx
export default function StacksExchange() {
  const { isDarkMode } = useDarkMode();
  const [pools, setPools] = useState([]);
  const [activeTab, setActiveTab] = useState("swap");

  return (
    <div className={`container ${isDarkMode ? 'dark' : 'light'}`}>
      {/* Pasifika Header */}
      <div className="header">
        <div className="logo">
          <Image src="/pasifika.png" alt="Pasifika" />
          <span>Pasifika</span>
        </div>
      </div>

      {/* AMM Interface */}
      <div className="amm-container">
        <div className="tab-navigation">
          {["swap", "add-liquidity", "pools"].map((tab) => (
            <button onClick={() => setActiveTab(tab)}>
              {tab.toUpperCase()}
            </button>
          ))}
        </div>
        
        {/* Tab Content */}
        {activeTab === "swap" && <Swap pools={pools} />}
        {activeTab === "add-liquidity" && <AddLiquidity pools={pools} />}
        {activeTab === "pools" && <PoolsList pools={pools} />}
      </div>
    </div>
  );
}

Стек интегрирует кошелек

// hooks/use-stacks.ts
export function useStacks() {
  const [userData, setUserData] = useState(null);
  const appConfig = useMemo(() => new AppConfig(["store_write"]), []);
  const userSession = useMemo(() => new UserSession({ appConfig }), [appConfig]);

  const connectWallet = useCallback(() => {
    showConnect({ appDetails, userSession });
  }, [userSession]);

  return { userData, connectWallet, handleCreatePool, handleSwap };
}

Синхронизация адреса договора

Ключевое инновация: Автоматический скрипт для синхронизации адресов контрактов от развертывания бэкэнд на фронта.

Как это работает

  1. Читает развертывание Clarinet YAML файлы
  2. Извлекать адреса контракта и метаданные
  3. Генерирует определения TypeScript для Frondend
  4. Сохраняет файлы JSON для использования во время выполнения

Скрипт ядра синхронизации

// scripts/save-contract-addresses.js
const fs = require('fs');
const yaml = require('js-yaml');

// Parse Clarinet deployment files
function extractContractInfo(deploymentPlan, network) {
  const contracts = {};
  
  deploymentPlan.genesis.plan.batches.forEach(batch => {
    batch.transactions?.forEach(transaction => {
      if (transaction['contract-publish']) {
        const contract = transaction['contract-publish'];
        contracts[contract['contract-name']] = {
          address: contract['expected-sender'],
          network: network,
          deployedAt: new Date().toISOString()
        };
      }
    });
  });
  return contracts;
}

// Generate TypeScript definitions
function generateTypeScriptDefinitions(contracts) {
  const contractNames = Object.keys(contracts);
  return `
export const DEPLOYED_CONTRACTS = ${JSON.stringify(contracts, null, 2)};

// Contract addresses
${contractNames.map(name => 
  `export const ${name.toUpperCase()}_CONTRACT = "${contracts[name].address}.${name}";`
).join('\n')}
`;
}

// Main sync function
async function main() {
  const deploymentFile = 'deployments/default.testnet-plan.yaml';
  const deploymentPlan = yaml.load(fs.readFileSync(deploymentFile, 'utf8'));
  
  const contracts = extractContractInfo(deploymentPlan, 'testnet');
  const tsContent = generateTypeScriptDefinitions(contracts);
  
  // Save to frontend
  fs.writeFileSync('deployed_contracts/contract-addresses.ts', tsContent);
  fs.writeFileSync('deployed_contracts/contracts.json', JSON.stringify(contracts, null, 2));
  
  console.log('Contract addresses synchronized!');
}

if (require.main === module) main();

Package.json Integration

{
  "scripts": {
    "sync-contracts": "node scripts/save-contract-addresses.js",
    "dev": "npm run sync-contracts && next dev",
    "build": "npm run sync-contracts && next build"
  },
  "devDependencies": {
    "js-yaml": "^4.1.0"
  }
}

Тестирование и проверка

# Run sync script
npm run sync-contracts

# Verify generated files
ls deployed_contracts/
# - contract-addresses.ts
# - contracts.json

# Test frontend integration
npm run dev

Результаты и преимущества

Чего я достиг

  • Чистое разделение: Frontend и Backend теперь должным образом разделены
  • Автоматизированная синхронизация: Адрес контракта обновляется автоматически
  • Интеграция темы: Бесплатный брендинг Pasifika
  • Тип безопасности: Полная поддержка TypeScript для адресов контракта
  • Производство готово: Zero Eslint предупреждения, оптимизированная производительность
  • Масштабируемая архитектура: Легко добавить новые контракты и функции

Заключение

Отделение вашего фронта DAPP от бэкэнда имеет решающее значение для масштабируемости, обслуживания и сотрудничества в команде. Внедряя автоматизированную синхронизацию адреса контракта, вы гарантируете, что ваш фронт всегда остается синхронизированным с вашими последними развертываниями контракта.

Подход, который я здесь обрисовал:

  • Чистая архитектурас надлежащим разделением проблем
  • Автоматизированное инструментыЧтобы уменьшить ручную работу и ошибки
  • Тип безопасности for better developer experience
  • Масштабируемые узорыкоторые растут с вашим проектом

Ресурсы

  • Живая демонстрация: Pasifika Stacks Exchange Amm
  • Stacks.js документация
  • Кларнетная документация
  • Next.js App Router
  • LearnWeb3dao/Stacks-Amm
  • Pasifika Web3 Tech Hub

Этот учебник является частью приверженности Tech Hub Pasifika Web3 по обмену знаниями и расширению возможностей разработчиков острова Тихого океана в технологии блокчейна Stacks.


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE