- Add config/non-evm-operator-binding.json (public hints only; no secrets). - Extend .env.master.example with XRPL/Tron/Solana/TRONGRID overrides. - Wire solana-gru-bridge-lineup refs; refresh non-evm lane stubs from binding. - Teach liquidity-gap planner to read binding; validate JSON in validate-config-files.sh. - Document handoff in CWUSDC_NON_MANUAL_PROVIDER_TASKS; cross-link GRU spec. Co-authored-by: Cursor <cursoragent@cursor.com>
172 lines
6.4 KiB
Python
Executable File
172 lines
6.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Write repo-side non-EVM funding and identity requirement stubs."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from datetime import datetime, timezone
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
CONFIG_OUT = ROOT / "config/non-evm-lane-requirements.json"
|
|
REPORT_JSON = ROOT / "reports/status/non-evm-lane-requirements-latest.json"
|
|
REPORT_MD = ROOT / "reports/status/non-evm-lane-requirements-latest.md"
|
|
OPERATOR_BINDING = ROOT / "config/non-evm-operator-binding.json"
|
|
|
|
|
|
def load_operator_binding_hints() -> dict[str, Any]:
|
|
if not OPERATOR_BINDING.exists():
|
|
return {}
|
|
try:
|
|
return json.loads(OPERATOR_BINDING.read_text())
|
|
except (json.JSONDecodeError, OSError):
|
|
return {}
|
|
|
|
LANES: list[dict[str, Any]] = [
|
|
{
|
|
"network": "solana",
|
|
"nativeAsset": "SOL",
|
|
"walletStatus": "bound_from_SOLANA_KEYPAIR_PATH_public_key",
|
|
"canonicalWallet": "9b4ebHVimuhMqbiCh6tUMMY2S48VyEHpqg5nxMMFe5Pf",
|
|
"requiredBindings": ["splMintAddresses", "rentReserveTarget", "venueMinimumLiquidity"],
|
|
"minimumFundingTarget": "TBD",
|
|
"claimBoundary": "Do not claim native Solana liquidity until SPL mints, rent/gas, and venue inventory are bound.",
|
|
},
|
|
{
|
|
"network": "tron",
|
|
"nativeAsset": "TRX",
|
|
"walletStatus": "derived_wallet_needs_canonical_confirmation",
|
|
"canonicalWallet": "TGkbidE5LfVJZ3QGj6DaPqzCTcTe9tJDxm",
|
|
"requiredBindings": ["canonicalWalletApproval", "energyBandwidthTarget", "trc20Inventory"],
|
|
"minimumFundingTarget": "TBD",
|
|
"claimBoundary": "Do not claim native Tron liquidity until the canonical wallet and TRC-20 inventory are confirmed.",
|
|
},
|
|
{
|
|
"network": "xrpl",
|
|
"nativeAsset": "XRP",
|
|
"walletStatus": "missing",
|
|
"canonicalWallet": None,
|
|
"requiredBindings": ["xrplAccount", "destinationTagPolicy", "trustlineIssuerPolicy", "xrpReserveTarget"],
|
|
"minimumFundingTarget": "TBD",
|
|
"claimBoundary": "Do not claim XRPL corridor readiness until account reserve, tags, trustlines, and wXRP controller evidence are closed.",
|
|
},
|
|
{
|
|
"network": "bitcoin",
|
|
"nativeAsset": "BTC",
|
|
"walletStatus": "missing",
|
|
"canonicalWallet": None,
|
|
"requiredBindings": ["btcCustodyAddress", "proofOfReservesPolicy", "wrappedAssetMapping", "venueTarget"],
|
|
"minimumFundingTarget": "TBD",
|
|
"claimBoundary": "Use BTC as a planning lane only until custody/reserve evidence and wrapping policy are bound.",
|
|
},
|
|
{
|
|
"network": "dogecoin",
|
|
"nativeAsset": "DOGE",
|
|
"walletStatus": "missing",
|
|
"canonicalWallet": None,
|
|
"requiredBindings": ["dogeCustodyAddress", "bridgeOrCustodyModel", "venueTarget"],
|
|
"minimumFundingTarget": "TBD",
|
|
"claimBoundary": "Use DOGE as a planning lane only until native custody and bridge model are bound.",
|
|
},
|
|
{
|
|
"network": "hyperliquid",
|
|
"nativeAsset": "HYPE",
|
|
"walletStatus": "research_required",
|
|
"canonicalWallet": None,
|
|
"requiredBindings": ["chainIdentifier", "assetIdentifier", "custodyPath", "venueOrApiEvidence"],
|
|
"minimumFundingTarget": "TBD",
|
|
"claimBoundary": "Use HYPE only as a market-cap watch item until identifiers and custody path are verified.",
|
|
},
|
|
]
|
|
|
|
|
|
def table(headers: list[str], rows: list[list[Any]]) -> str:
|
|
def cell(value: Any) -> str:
|
|
if isinstance(value, list):
|
|
value = "<br>".join(str(item) for item in value)
|
|
if value is None:
|
|
value = "TBD"
|
|
return str(value).replace("|", "\\|").replace("\n", "<br>")
|
|
|
|
return "\n".join(
|
|
[
|
|
f"| {' | '.join(cell(header) for header in headers)} |",
|
|
f"| {' | '.join('---' for _ in headers)} |",
|
|
*[f"| {' | '.join(cell(value) for value in row)} |" for row in rows],
|
|
]
|
|
)
|
|
|
|
|
|
def main() -> int:
|
|
generated_at = datetime.now(timezone.utc).isoformat()
|
|
bind = load_operator_binding_hints()
|
|
hints = bind.get("minimumFundingTargets") or {}
|
|
|
|
def min_tgt(network: str) -> str:
|
|
m = hints.get(network) if hints else None
|
|
if isinstance(m, dict) and m:
|
|
parts = [f"{k}={v}" for k, v in m.items() if k != "note" and v]
|
|
note = m.get("note")
|
|
base = "; ".join(parts) if parts else "TBD"
|
|
return f"{base} ({note})" if note else base
|
|
return "TBD"
|
|
|
|
lanes_out = []
|
|
for lane in LANES:
|
|
row = dict(lane)
|
|
net = row["network"]
|
|
if net == "solana":
|
|
row["minimumFundingTarget"] = min_tgt("solana")
|
|
elif net == "tron":
|
|
row["minimumFundingTarget"] = min_tgt("tron")
|
|
elif net == "xrpl":
|
|
row["minimumFundingTarget"] = min_tgt("xrpl")
|
|
lanes_out.append(row)
|
|
|
|
payload = {
|
|
"schema": "non-evm-lane-requirements/v1",
|
|
"generatedAt": generated_at,
|
|
"status": "stubs_bound_repo_side",
|
|
"lanes": lanes_out,
|
|
"operatorBindingConfig": str(OPERATOR_BINDING.relative_to(ROOT)),
|
|
"validationRule": "A lane is claimable only after canonicalWallet, asset IDs, native gas/reserve target, venue target, and evidence source are non-TBD.",
|
|
}
|
|
for path in (CONFIG_OUT, REPORT_JSON):
|
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
path.write_text(json.dumps(payload, indent=2) + "\n")
|
|
|
|
lines = [
|
|
"# Non-EVM Lane Requirement Stubs",
|
|
"",
|
|
f"- Generated: `{generated_at}`",
|
|
f"- Config source: `{CONFIG_OUT.relative_to(ROOT)}`",
|
|
"",
|
|
table(
|
|
["Network", "Native", "Wallet status", "Canonical wallet", "Required bindings", "Minimum target", "Claim boundary"],
|
|
[
|
|
[
|
|
lane["network"],
|
|
lane["nativeAsset"],
|
|
lane["walletStatus"],
|
|
lane["canonicalWallet"],
|
|
lane["requiredBindings"],
|
|
lane["minimumFundingTarget"],
|
|
lane["claimBoundary"],
|
|
]
|
|
for lane in lanes_out
|
|
],
|
|
),
|
|
]
|
|
REPORT_MD.parent.mkdir(parents=True, exist_ok=True)
|
|
REPORT_MD.write_text("\n".join(lines) + "\n")
|
|
print(f"Wrote {CONFIG_OUT.relative_to(ROOT)}")
|
|
print(f"Wrote {REPORT_JSON.relative_to(ROOT)}")
|
|
print(f"Wrote {REPORT_MD.relative_to(ROOT)}")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|