
Как я разделяю свои стеки 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 };
}
Синхронизация адреса договора
Ключевое инновация: Автоматический скрипт для синхронизации адресов контрактов от развертывания бэкэнд на фронта.
Как это работает
- Читает развертывание Clarinet YAML файлы
- Извлекать адреса контракта и метаданные
- Генерирует определения TypeScript для Frondend
- Сохраняет файлы 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.
Оригинал