forked from Frankencoin-ZCHF/frankencoin-api
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathapi.config.ts
More file actions
148 lines (134 loc) · 4.68 KB
/
api.config.ts
File metadata and controls
148 lines (134 loc) · 4.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import { Address, Chain, createPublicClient, http, zeroAddress } from 'viem';
import { ADDRESS } from '@deuro/eurocoin';
import { mainnet, polygon } from 'viem/chains';
import { Logger } from '@nestjs/common';
import * as dotenv from 'dotenv';
dotenv.config();
// Verify environment
if (process.env.RPC_URL_MAINNET === undefined) throw new Error('RPC_URL_MAINNET not available');
if (process.env.RPC_URL_POLYGON === undefined) throw new Error('RPC_URL_POLYGON not available');
// COINGECKO_BASE_URL is the origin the api calls — typically the in-cluster
// pricing-proxy (https://github.com/DFXswiss/pricing-proxy), but any
// CoinGecko-compatible host works. COINGECKO_API_KEY is optional and is
// only attached as `x-cg-pro-api-key` on every request when set (proxy mode
// leaves it unset because the proxy injects its own key).
if (!process.env.COINGECKO_BASE_URL) {
throw new Error('COINGECKO_BASE_URL is not set');
}
// Config type
export type ConfigType = {
app: string;
indexer: string;
indexerFallback: string;
coingeckoBaseUrl: string;
coingeckoApiKey: string | undefined;
chain: Chain;
network: {
mainnet: string;
polygon: string;
};
telegram: {
botToken: string;
groupsJson: string;
imagesDir: string;
};
twitter: {
clientId: string;
clientSecret: string;
appKey: string;
appSecret: string;
tokenJson: string;
imagesDir: string;
};
};
// Create config
export const CONFIG: ConfigType = {
app: process.env.CONFIG_APP_URL || 'https://app.deuro.com',
indexer: process.env.CONFIG_INDEXER_URL || 'https://ponder.deuro.com/',
indexerFallback: process.env.CONFIG_INDEXER_FALLBACK_URL || 'https://dev.ponder.deuro.com/',
coingeckoBaseUrl: process.env.COINGECKO_BASE_URL,
coingeckoApiKey: process.env.COINGECKO_API_KEY || undefined,
chain: process.env.CONFIG_CHAIN === 'polygon' ? polygon : mainnet, // @dev: default mainnet
network: {
mainnet: process.env.RPC_URL_MAINNET,
polygon: process.env.RPC_URL_POLYGON,
},
telegram: {
botToken: process.env.TELEGRAM_BOT_TOKEN,
groupsJson: process.env.TELEGRAM_GROUPS_JSON,
imagesDir: process.env.TELEGRAM_IMAGES_DIR,
},
twitter: {
clientId: process.env.TWITTER_CLIENT_ID,
clientSecret: process.env.TWITTER_CLIENT_SECRET,
appKey: process.env.TWITTER_CLIENT_APP_KEY,
appSecret: process.env.TWITTER_CLIENT_APP_SECRET,
tokenJson: process.env.TWITTER_TOKEN_JSON,
imagesDir: process.env.TWITTER_IMAGES_DIR,
},
};
const SENSITIVE_KEYS = new Set<string>([
'coingeckoApiKey',
'network.mainnet',
'network.polygon',
'telegram.botToken',
'twitter.clientSecret',
'twitter.appKey',
'twitter.appSecret',
]);
function redactConfig<T>(config: T): T {
return walkRedact(config, '') as T;
}
function walkRedact(value: unknown, path: string): unknown {
if (value && typeof value === 'object' && !Array.isArray(value)) {
return Object.fromEntries(
Object.entries(value as Record<string, unknown>).map(([key, val]) => {
const childPath = path ? `${path}.${key}` : key;
if (SENSITIVE_KEYS.has(childPath) && val) return [key, '***'];
return [key, walkRedact(val, childPath)];
})
);
}
return value;
}
export function logConfig() {
const logger = new Logger('ApiConfig');
logger.log(`Starting API with this config:`);
logger.log(JSON.stringify(redactConfig(CONFIG)));
}
// Refer to https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files
process.env.NTBA_FIX_350 = 'true';
// VIEM CONFIG
export const VIEM_CHAIN = CONFIG.chain;
export const VIEM_CONFIG = createPublicClient({
chain: VIEM_CHAIN,
transport: http(process.env.CONFIG_CHAIN === 'polygon' ? CONFIG.network.polygon : CONFIG.network.mainnet),
batch: {
multicall: {
wait: 200,
},
},
});
// COINGECKO CLIENT
//
// Calls go to whatever `COINGECKO_BASE_URL` points at. When the optional
// `COINGECKO_API_KEY` is set, it is attached as the `x-cg-pro-api-key`
// header — orthogonal to the base URL, never a fallback. The recommended
// deployment is the in-cluster pricing-proxy
// (https://github.com/DFXswiss/pricing-proxy), which injects its own key
// and leaves COINGECKO_API_KEY unset on every consumer.
export const COINGECKO_CLIENT = (query: string) => {
const headers: Record<string, string> = { accept: 'application/json' };
if (CONFIG.coingeckoApiKey) {
headers['x-cg-pro-api-key'] = CONFIG.coingeckoApiKey;
}
return fetch(`${CONFIG.coingeckoBaseUrl}${query}`, { headers });
};
// Contract addresses for the active chain
export const ADDR = ADDRESS[CONFIG.chain.id];
export function isDeployed(addr: string | undefined): addr is Address {
return !!addr && addr !== zeroAddress;
}
export function isV3Hub(hubAddress: Address): boolean {
return isDeployed(ADDR.mintingHub) && hubAddress.toLowerCase() === ADDR.mintingHub.toLowerCase();
}