Monorepo for Aesthetic.Computer
aesthetic.computer
1import { connect } from "./database.mjs";
2
3const KT1_ADDRESS_RE = /^KT1[1-9A-HJ-NP-Za-km-z]{33}$/;
4
5// Legacy fallback — real v9 production contract (deprecated, all tokens migrated to v11).
6export const LEGACY_KEEPS_CONTRACT = "KT1HoPURtwqXy58UYfZYh4ufoaMSNcsb9pCF";
7
8function pickAddressCandidate(value, network = "mainnet") {
9 if (!value) return null;
10
11 if (typeof value === "string") {
12 return value.trim();
13 }
14
15 if (typeof value !== "object" || Array.isArray(value)) {
16 return null;
17 }
18
19 const orderedKeys = [network, "mainnet", "production", "current", "default"];
20 for (const key of orderedKeys) {
21 const candidate = value[key];
22 if (typeof candidate === "string" && candidate.trim()) {
23 return candidate.trim();
24 }
25 }
26
27 return null;
28}
29
30function normalizeKt1(value) {
31 if (typeof value !== "string") return null;
32 const trimmed = value.trim();
33 return KT1_ADDRESS_RE.test(trimmed) ? trimmed : null;
34}
35
36function resolveFromSecretDoc(secretDoc, network = "mainnet") {
37 if (!secretDoc || typeof secretDoc !== "object") {
38 return null;
39 }
40
41 const rawCandidates = [
42 pickAddressCandidate(secretDoc.keepsContract, network),
43 pickAddressCandidate(secretDoc.currentKeepsContract, network),
44 pickAddressCandidate(secretDoc.keeps_contract, network),
45 pickAddressCandidate(secretDoc.keepsContracts, network),
46 pickAddressCandidate(secretDoc.contracts?.keeps, network),
47 pickAddressCandidate(secretDoc.keeps?.contract, network),
48 pickAddressCandidate(secretDoc.keeps?.contracts, network),
49 ];
50
51 for (const raw of rawCandidates) {
52 const normalized = normalizeKt1(raw);
53 if (normalized) return normalized;
54 }
55
56 return null;
57}
58
59export async function getKeepsContractAddress(options = {}) {
60 const {
61 db = null,
62 network = "mainnet",
63 secretId = "tezos-kidlisp",
64 fallback = LEGACY_KEEPS_CONTRACT,
65 } = options;
66
67 let database = null;
68 const fallbackAddress = normalizeKt1(fallback);
69
70 try {
71 const effectiveDb = db || (database = await connect()).db;
72 const secretDoc = await effectiveDb.collection("secrets").findOne({ _id: secretId });
73 const resolved = resolveFromSecretDoc(secretDoc, network);
74
75 if (resolved) {
76 return resolved;
77 }
78
79 if (fallbackAddress) {
80 console.warn(`⚠️ KEEP: secrets.${secretId} missing keeps contract; using fallback ${fallbackAddress}`);
81 return fallbackAddress;
82 }
83
84 throw new Error(`Missing valid keeps contract in secrets.${secretId}`);
85 } catch (error) {
86 if (fallbackAddress) {
87 console.warn(`⚠️ KEEP: failed to resolve keeps contract from secrets (${error.message}); using fallback ${fallbackAddress}`);
88 return fallbackAddress;
89 }
90 throw error;
91 } finally {
92 if (database) {
93 await database.disconnect();
94 }
95 }
96}