// Generated, do not edit. sha256:52135637bc4779b2b5f755ec50fedf41d2fa7b65d90a35f911c4e68f0b093874 import { CONFIG, PREFERENCES, SOURCE_CAPABILITIES, SOURCE_ENDPOINTS, DASHBOARD } from '../../shared/config.js'; import { toSearchName } from '../../shared/search-name.js'; import { run, one, all, lastId } from './conn.mjs'; function basisMunt() { const r = one(`SELECT baseCurrency FROM Portfolio WHERE id = 1`); if (!r) throw new Error('Seeds need the Portfolio row: write the unit of account first.'); return r.baseCurrency; } function fiatAssets(basis) { const codes = [...new Set([basis, 'EUR', 'USD'])]; const namen = new Intl.DisplayNames(['nl-NL'], { type: 'currency' }); return codes.map(code => { const naam = namen.of(code); const decimals = new Intl.NumberFormat('nl-NL', { style: 'currency', currency: code }).resolvedOptions().maximumFractionDigits; return { symbol: code, name: naam.charAt(0).toUpperCase() + naam.slice(1), kind: 'fiat', unit: code, subunit: code === 'EUR' || code === 'USD' ? 'cent' : null, decimals, displayUnit: 'unit' }; }); } function startBron(symbol, basis) { if (symbol === basis) return 'fixed'; if (symbol === 'EUR' || symbol === 'USD') return 'frankfurter'; return { BTC: 'mempool', ETH: 'bitvavo', XAU: 'goldapi', XAG: 'goldapi' }[symbol] ?? null; } export function seedAssets() { for (const a of fiatAssets(basisMunt())) { if (one(`SELECT 1 AS x FROM Asset WHERE symbol = ?`, [a.symbol])) continue; run( `INSERT INTO Asset (symbol, name, searchName, kind, unit, subunit, decimals, displayUnit) VALUES (?,?,?,?,?,?,?,?)`, [a.symbol, a.name, toSearchName(a.name), a.kind, a.unit, a.subunit, a.decimals, a.displayUnit] ); } } const SEED_METAL_PRODUCTS = [ { symbol: 'XAU', name: 'Krugerrand 1 oz', form: 'coin', grams: CONFIG.METALS.GRAMS_PER_TROY_OUNCE }, { symbol: 'XAU', name: 'Maple Leaf 1 oz', form: 'coin', grams: CONFIG.METALS.GRAMS_PER_TROY_OUNCE }, { symbol: 'XAU', name: 'Wiener Philharmoniker 1 oz', form: 'coin', grams: CONFIG.METALS.GRAMS_PER_TROY_OUNCE }, { symbol: 'XAU', name: 'Baar 1 g', form: 'bar', grams: 1 }, { symbol: 'XAU', name: 'Baar 5 g', form: 'bar', grams: 5 }, { symbol: 'XAU', name: 'Baar 10 g', form: 'bar', grams: 10 }, { symbol: 'XAU', name: 'Baar 100 g', form: 'bar', grams: 100 }, { symbol: 'XAU', name: 'Baar 1 kg', form: 'bar', grams: 1000 }, { symbol: 'XAG', name: 'Maple Leaf 1 oz', form: 'coin', grams: CONFIG.METALS.GRAMS_PER_TROY_OUNCE }, { symbol: 'XAG', name: 'Wiener Philharmoniker 1 oz', form: 'coin', grams: CONFIG.METALS.GRAMS_PER_TROY_OUNCE }, { symbol: 'XAG', name: 'Baar 100 g', form: 'bar', grams: 100 }, { symbol: 'XAG', name: 'Baar 1 kg', form: 'bar', grams: 1000 }, ]; export function seedMetalProducts() { const factor = Math.pow(10, CONFIG.METALS.BASE_DECIMALS); for (const p of SEED_METAL_PRODUCTS) { const a = one(`SELECT id FROM Asset WHERE symbol = ?`, [p.symbol]); if (!a) continue; if (one(`SELECT 1 AS x FROM MetalProduct WHERE assetId = ? AND name = ?`, [a.id, p.name])) continue; run(`INSERT INTO MetalProduct (assetId, name, searchName, form, fineGrams) VALUES (?,?,?,?,?)`, [a.id, p.name, toSearchName(p.name), p.form, Math.round(p.grams * factor)]); } } const SEED_CONNECTIONS = [ { kind: 'btc_explorer', name: 'mempool.space (publiek)', url: CONFIG.PRICE_SOURCES.MEMPOOL_PUBLIC_BASE, isActive: 1, isSystem: 1 }, ]; export function seedConnections() { const now = new Date().toISOString(); for (const c of SEED_CONNECTIONS) { if (one(`SELECT 1 AS x FROM Connection WHERE kind = ? AND name = ?`, [c.kind, c.name])) continue; const hasActive = !!one(`SELECT 1 AS x FROM Connection WHERE kind = ? AND isActive = 1`, [c.kind]); run(`INSERT INTO Connection (name, searchName, url, kind, isActive, isSystem, lastStatus, lastCheckedAt, createdAt, updatedAt) VALUES (?,?,?,?,?,?,NULL,NULL,?,?)`, [c.name, toSearchName(c.name), c.url, c.kind, hasActive ? 0 : c.isActive, c.isSystem, now, now]); } } function seedProviderList(basis) { return [ { key: 'manual', name: 'Handmatig', baseUrl: '', authenticationKind: 'none', authenticationRequired: 0, isSystem: true, authenticationHeaderName: null, authenticationParameterName: null, hmac: null, endpoints: [], symbols: [], coverage: [], outputs: [] }, { key: CONFIG.MARKET_SERVICE.PROVIDER_KEY, name: 'Atreides Services', baseUrl: '', authenticationKind: 'none', authenticationRequired: 0, isSystem: true, authenticationHeaderName: null, authenticationParameterName: null, hmac: null, endpoints: [], symbols: [], coverage: [], outputs: [] }, { key: 'fixed', name: 'Vaste koers', baseUrl: '', authenticationKind: 'none', authenticationRequired: 0, isSystem: true, authenticationHeaderName: null, authenticationParameterName: null, hmac: null, fixedRate: { fiatPrice: 1 }, endpoints: [ { capability: 'spot', method: 'GET', pathTemplate: '', queryTemplate: null }, { capability: 'history_point', method: 'GET', pathTemplate: '', queryTemplate: null }, ], symbols: [], coverage: [basis], outputs: [] }, ]; } export function seedProviders() { for (const p of seedProviderList(basisMunt())) { if (one(`SELECT 1 AS x FROM Provider WHERE key = ?`, [p.key])) continue; const isActive = p.authenticationRequired ? 0 : 1; run(`INSERT INTO Provider (key, name, searchName, baseUrl, authenticationHeaderName, authenticationParameterName, authenticationKind, authenticationRequired, isActive, isSeed, isSystem, createdAt) VALUES (?,?,?,?,?,?,?,?,?,1,?,?)`, [p.key, p.name, toSearchName(p.name), p.baseUrl, p.authenticationHeaderName, p.authenticationParameterName, p.authenticationKind, p.authenticationRequired, isActive, p.isSystem ? 1 : 0, new Date().toISOString()]); const pid = lastId(); for (const symbool of p.coverage || []) { run(`INSERT INTO ProviderCoverage (providerId, symbol) VALUES (?,?)`, [pid, symbool]); } if (p.fixedRate) { run(`INSERT INTO ProviderFixedRate (providerId, fiatPrice) VALUES (?,?)`, [pid, p.fixedRate.fiatPrice]); } if (p.callsPerMonth) { run(`INSERT INTO ProviderCallLimit (providerId, callsPerMonth, createdAt) VALUES (?,?,?)`, [pid, p.callsPerMonth, new Date().toISOString()]); } if (p.hmac) { const h = p.hmac; run(`INSERT INTO ProviderAuthenticationHmac (providerId, messageParts, hashAlgorithm, encoding, keyHeader, signatureHeader, timestampHeader, windowHeader, windowMs) VALUES (?,?,?,?,?,?,?,?,?)`, [pid, h.messageParts, h.hashAlgorithm, h.encoding, h.keyHeader, h.signatureHeader, h.timestampHeader, h.windowHeader, h.windowMs]); } for (const e of p.endpoints) run(`INSERT INTO ProviderEndpoint (providerId, capability, method, pathTemplate, queryTemplate, quoteCurrency) VALUES (?,?,?,?,?,?)`, [pid, e.capability, e.method, e.pathTemplate, e.queryTemplate, e.quoteCurrency ?? null]); for (const s of p.symbols) run(`INSERT INTO ProviderInputMap (providerId, symbol, externalId, quoteUnit, isCatchAll) VALUES (?,?,?,?,?)`, [pid, s.isCatchAll ? null : s.symbol, s.externalId, s.quoteUnit ?? null, s.isCatchAll ? 1 : 0]); for (const o of p.outputs) run(`INSERT INTO ProviderOutputMap (providerId, capability, internalField, jsonPath, transform) VALUES (?,?,?,?,?)`, [pid, o.capability, o.internalField, o.jsonPath, o.transform]); } } export function seedPriceSource(assetId, status) { const assets = assetId ? all(`SELECT id, symbol FROM Asset WHERE id = ?`, [assetId]) : all(`SELECT id, symbol FROM Asset`); const basis = basisMunt(); for (const asset of assets) { const srcKey = startBron(asset.symbol, basis); if (!srcKey) continue; const provider = one(`SELECT id FROM Provider WHERE key = ?`, [srcKey]); if (!provider) continue; for (const capability of SOURCE_CAPABILITIES) { if (one(`SELECT 1 AS x FROM PriceSource WHERE assetId = ? AND capability = ?`, [asset.id, capability])) continue; const eindpunten = SOURCE_ENDPOINTS[capability]; if (!one(`SELECT 1 AS x FROM ProviderEndpoint WHERE providerId = ? AND capability IN (${eindpunten.map(() => '?').join(',')})`, [provider.id, ...eindpunten])) continue; run(`INSERT INTO PriceSource (assetId, capability, providerId, rank, status) VALUES (?,?,?,1,?)`, [asset.id, capability, provider.id, status]); } } } export function seedDashboardProfile() { if (one(`SELECT 1 AS x FROM DashboardProfile WHERE isSystem = 1`)) return false; const now = new Date().toISOString(); const hasActive = !!one(`SELECT 1 AS x FROM DashboardProfile WHERE isActive = 1`); run(`INSERT INTO DashboardProfile (name, searchName, description, sortOrder, isActive, isSystem, createdAt, updatedAt) VALUES (?,?,NULL,0,?,1,?,?)`, ['Standaard', toSearchName('Standaard'), hasActive ? 0 : 1, now, now]); const profileId = lastId(); for (const w of DASHBOARD.DEFAULT_LAYOUT) { const def = DASHBOARD.WIDGETS[w.type]; if (!def) continue; run(`INSERT INTO DashboardWidget (profileId, assetId, instanceKey, gridX, gridY, spanWidth, spanHeight, type, settings) VALUES (?,NULL,?,?,0,?,NULL,?,NULL)`, [profileId, w.instId, w.x || 0, def.defaultSpan, w.type]); } return true; } const FRESH_VALUES = Object.freeze({ app: Object.freeze({ market_spot: 'first' }) }); export function seedPreferences() { for (const [scope, keys] of Object.entries(PREFERENCES)) { for (const [key, spec] of Object.entries(keys)) { if (spec.secret) continue; run(`INSERT INTO Preference (scope, key, value) VALUES (?,?,?)`, [scope, key, JSON.stringify(FRESH_VALUES[scope]?.[key] ?? spec.initial)]); } } }