Some checks failed
CI/CD Pipeline / Solidity Contracts (push) Failing after 1m3s
CI/CD Pipeline / Security Scanning (push) Successful in 2m58s
CI/CD Pipeline / Lint and Format (push) Failing after 46s
CI/CD Pipeline / Terraform Validation (push) Failing after 26s
CI/CD Pipeline / Kubernetes Validation (push) Successful in 29s
Deploy ChainID 138 / Deploy ChainID 138 (push) Failing after 41s
HYBX OMNL TypeScript & anchor / token-aggregation build + reconcile artifact (push) Failing after 22s
OMNL reconcile anchor / Run omnl:reconcile and upload artifacts (push) Failing after 24s
Validation / validate-genesis (push) Successful in 32s
Validation / validate-terraform (push) Failing after 28s
Validation / validate-kubernetes (push) Failing after 13s
Validation / validate-smart-contracts (push) Failing after 12s
Validation / validate-security (push) Failing after 1m31s
Validation / validate-documentation (push) Failing after 23s
Verify Deployment / Verify Deployment (push) Failing after 1m4s
Add BTC L1 settle/reconcile/ledger APIs, bitcoind intake, cBTC PMM hot-LP scripts, and custody credential smoke tests (secrets stay gitignored). Enables full-prod local green health and server pull-deploy for secure.omdnl.org /btc/*. Co-authored-by: Cursor <cursoragent@cursor.com>
91 lines
3.3 KiB
JavaScript
91 lines
3.3 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Ensure cBTC DODO PMM pools exist on Chain 138 and print CHAIN138_POOL_CBTC_* env lines.
|
|
* Requires POOL_MANAGER_ROLE on DODOPMMIntegration (PRIVATE_KEY / OMNL_MINT_OPERATOR_PRIVATE_KEY).
|
|
*/
|
|
import fs from 'fs';
|
|
import path from 'path';
|
|
import { Contract, JsonRpcProvider, Wallet, ZeroAddress } from 'ethers';
|
|
|
|
const rpc = process.env.RPC_URL_138 || process.env.CHAIN_138_RPC_URL || 'https://rpc.d-bis.org';
|
|
const pk =
|
|
process.env.PRIVATE_KEY?.trim() ||
|
|
process.env.OMNL_MINT_OPERATOR_PRIVATE_KEY?.trim();
|
|
const integrationAddr =
|
|
process.env.DODO_PMM_INTEGRATION_ADDRESS ||
|
|
process.env.CHAIN_138_DODO_PMM_INTEGRATION ||
|
|
'0x86ADA6Ef91A3B450F89f2b751e93B1b7A3218895';
|
|
|
|
const CBTC = '0xe94260c555ac1d9d3cc9e1632883452ebdf0082e';
|
|
const PAIRS = [
|
|
{ env: 'CHAIN138_POOL_CBTC_CUSDT', quote: '0x93E66202A11B1772E55407B32B44e5Cd8eda7f22', sym: 'cUSDT' },
|
|
{ env: 'CHAIN138_POOL_CBTC_CUSDC', quote: '0xf22258f57794CC8E06237084b353Ab30fFfa640b', sym: 'cUSDC' },
|
|
{ env: 'CHAIN138_POOL_CBTC_CXAUC', quote: '0x290E52a8819A4fbD0714E517225429aA2B70EC6b', sym: 'cXAUC' },
|
|
];
|
|
|
|
const LP_FEE = 3n;
|
|
const INITIAL_PRICE = 10n ** 18n;
|
|
const K_FACTOR = 5n * 10n ** 17n;
|
|
const ENABLE_TWAP = false;
|
|
|
|
if (!pk) {
|
|
console.error('PRIVATE_KEY or OMNL_MINT_OPERATOR_PRIVATE_KEY required');
|
|
process.exit(1);
|
|
}
|
|
|
|
const provider = new JsonRpcProvider(rpc);
|
|
const wallet = new Wallet(pk, provider);
|
|
const abi = [
|
|
'function pools(address,address) view returns (address)',
|
|
'function createPool(address,address,uint256,uint256,uint256,bool) returns (address)',
|
|
'function POOL_MANAGER_ROLE() view returns (bytes32)',
|
|
'function hasRole(bytes32,address) view returns (bool)',
|
|
];
|
|
const integration = new Contract(integrationAddr, abi, wallet);
|
|
|
|
function upsertEnv(file, key, value) {
|
|
if (!fs.existsSync(file)) return;
|
|
let txt = fs.readFileSync(file, 'utf8');
|
|
const line = `${key}=${value}`;
|
|
if (new RegExp(`^${key}=`, 'm').test(txt)) txt = txt.replace(new RegExp(`^${key}=.*$`, 'm'), line);
|
|
else txt += `\n${line}\n`;
|
|
fs.writeFileSync(file, txt);
|
|
}
|
|
|
|
const role = await integration.POOL_MANAGER_ROLE();
|
|
const canManage = await integration.hasRole(role, wallet.address);
|
|
console.log(JSON.stringify({ operator: wallet.address, canManage, integration: integrationAddr }, null, 2));
|
|
|
|
const results = {};
|
|
for (const pair of PAIRS) {
|
|
let pool = await integration.pools(CBTC, pair.quote);
|
|
if (!pool || pool === ZeroAddress) {
|
|
pool = await integration.pools(pair.quote, CBTC);
|
|
}
|
|
if (pool && pool !== ZeroAddress) {
|
|
console.log(`EXISTS ${pair.sym} -> ${pool}`);
|
|
results[pair.env] = pool;
|
|
continue;
|
|
}
|
|
if (!canManage) {
|
|
console.error(`MISSING ${pair.sym} and operator lacks POOL_MANAGER_ROLE`);
|
|
results[pair.env] = '';
|
|
continue;
|
|
}
|
|
console.log(`CREATE ${pair.sym}...`);
|
|
const tx = await integration.createPool(CBTC, pair.quote, LP_FEE, INITIAL_PRICE, K_FACTOR, ENABLE_TWAP);
|
|
const receipt = await tx.wait(1);
|
|
pool = await integration.pools(CBTC, pair.quote);
|
|
console.log(`CREATED ${pair.sym} -> ${pool} tx=${receipt.hash}`);
|
|
results[pair.env] = pool;
|
|
}
|
|
|
|
for (const [k, v] of Object.entries(results)) {
|
|
if (!v) continue;
|
|
upsertEnv(path.resolve('.env'), k, v);
|
|
upsertEnv(path.resolve('config/deployment-omnl.production.env'), k, v);
|
|
console.log(`${k}=${v}`);
|
|
}
|
|
|
|
console.log(JSON.stringify({ results }, null, 2));
|