-
Notifications
You must be signed in to change notification settings - Fork 172
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4418 from connext/sdk-server-config
Sdk server config
- Loading branch information
Showing
16 changed files
with
392 additions
and
112 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"extends": "../../../.nycrc.json", | ||
"exclude": [ | ||
"src/config.ts", | ||
"src/context.ts", | ||
"src/server.ts", | ||
"src/index.ts", | ||
"src/routes/**/*.ts", | ||
"src/types/**/*.ts", | ||
"test/**/*.ts" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
import * as fs from "fs"; | ||
|
||
import { Type, Static } from "@sinclair/typebox"; | ||
import { config as dotenvConfig } from "dotenv"; | ||
import { ajv } from "@connext/nxtp-utils"; | ||
|
||
const CACHE_EXPIRATION_SECS = 300; | ||
|
||
dotenvConfig(); | ||
|
||
export const TChainConfig = Type.Object({ | ||
providers: Type.Array(Type.String()), | ||
}); | ||
|
||
export const TServerConfig = Type.Object({ | ||
http: Type.Object({ | ||
port: Type.Integer({ minimum: 1, maximum: 65535 }), | ||
host: Type.String(), | ||
}), | ||
}); | ||
|
||
export const TRedisConfig = Type.Object({ | ||
enabled: Type.Optional(Type.Boolean()), | ||
expirationTime: Type.Optional(Type.Integer()), | ||
host: Type.Optional(Type.String()), | ||
port: Type.Optional(Type.Integer({ minimum: 1, maximum: 65535 })), | ||
}); | ||
|
||
export const SdkServerConfigSchema = Type.Object({ | ||
chains: Type.Record(Type.String(), TChainConfig), | ||
environment: Type.Union([Type.Literal("staging"), Type.Literal("production")]), | ||
network: Type.Union([Type.Literal("testnet"), Type.Literal("mainnet"), Type.Literal("local")]), | ||
logLevel: Type.Union([ | ||
Type.Literal("fatal"), | ||
Type.Literal("error"), | ||
Type.Literal("warn"), | ||
Type.Literal("info"), | ||
Type.Literal("debug"), | ||
Type.Literal("trace"), | ||
Type.Literal("silent"), | ||
]), | ||
mnemonic: Type.Optional(Type.String()), | ||
redis: TRedisConfig, | ||
server: TServerConfig, | ||
}); | ||
export type SdkServerConfig = Static<typeof SdkServerConfigSchema>; | ||
|
||
export const getEnvConfig = (): SdkServerConfig => { | ||
let configJson: Record<string, any> = {}; | ||
let configFile: any = {}; | ||
|
||
try { | ||
configJson = JSON.parse(process.env.SDK_SERVER_CONFIG || ""); | ||
} catch (e: unknown) { | ||
console.info("No SDK_SERVER_CONFIG exists, using config file and individual env vars"); | ||
} | ||
try { | ||
let json: string; | ||
|
||
const path = process.env.SDK_SERVER_CONFIG_FILE ?? "config.json"; | ||
if (fs.existsSync(path)) { | ||
json = fs.readFileSync(path, { encoding: "utf-8" }); | ||
configFile = JSON.parse(json); | ||
} | ||
} catch (e: unknown) { | ||
console.error("Error reading config file!"); | ||
process.exit(1); | ||
} | ||
|
||
const _sdkServerConfig: SdkServerConfig = { | ||
chains: process.env.SDK_SERVER_CHAIN_CONFIG | ||
? JSON.parse(process.env.SDK_SERVER_CHAIN_CONFIG) | ||
: configJson.chains | ||
? configJson.chains | ||
: configFile.chains, | ||
environment: process.env.SDK_SERVER_ENVIRONMENT || configJson.environment || configFile.environment || "production", | ||
network: process.env.SDK_SERVER_NETWORK || configJson.network || configFile.network || "mainnet", | ||
logLevel: process.env.SDK_SERVER_LOG_LEVEL || configJson.logLevel || configFile.logLevel || "info", | ||
mnemonic: process.env.SDK_SERVER_MNEMONIC || configJson.mnemonic || configFile.mnemonic, | ||
redis: { | ||
enabled: process.env.SDK_SERVER_REDIS_ENABLED || configJson.redis?.enabled || configFile.redis?.enabled || false, | ||
expirationTime: | ||
process.env.SDK_SERVER_REDIS_EXPIRATION_TIME || | ||
configJson.redis?.expirationTime || | ||
configFile.redis?.expirationTime || | ||
CACHE_EXPIRATION_SECS, | ||
host: process.env.SDK_SERVER_REDIS_HOST || configJson.redis?.host || configFile.redis?.host || "localhost", | ||
port: process.env.SDK_SERVER_REDIS_PORT || configJson.redis?.port || configFile.redis?.port || 6379, | ||
}, | ||
server: { | ||
http: { | ||
port: | ||
process.env.SDK_SERVER_HTTP_SERVER_PORT || | ||
configJson.server?.http?.port || | ||
configFile.server?.http?.port || | ||
8080, | ||
host: | ||
process.env.SDK_SERVER_HTTP_SERVER_HOST || | ||
configJson.server?.http?.host || | ||
configFile.server?.http?.host || | ||
"localhost", | ||
}, | ||
}, | ||
}; | ||
|
||
const validate = ajv.compile(SdkServerConfigSchema); | ||
const valid = validate(_sdkServerConfig); | ||
if (!valid) { | ||
throw new Error(validate.errors?.map((err: unknown) => JSON.stringify(err, null, 2)).join(",")); | ||
} | ||
|
||
return _sdkServerConfig; | ||
}; | ||
|
||
export let sdkServerConfig: SdkServerConfig | undefined; | ||
|
||
export const getConfig = async (): Promise<SdkServerConfig> => { | ||
if (!sdkServerConfig) { | ||
sdkServerConfig = getEnvConfig(); | ||
} | ||
return sdkServerConfig; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { Logger } from "@connext/nxtp-utils"; | ||
|
||
import { SdkServerConfig } from "./config"; | ||
|
||
export type SdkServerContext = { | ||
logger: Logger; | ||
config: SdkServerConfig; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,103 +1,6 @@ | ||
import * as fs from "fs"; | ||
import { SdkServerConfig } from "./config"; | ||
import { makeSdkServer } from "./server"; | ||
|
||
import fastify, { FastifyInstance } from "fastify"; | ||
import { fastifyRedis } from "@fastify/redis"; | ||
import { ethers, providers } from "ethers"; | ||
import { SdkConfig, create } from "@connext/sdk"; | ||
import { getBestProvider } from "@connext/nxtp-utils"; | ||
export { makeSdkServer, SdkServerConfig }; | ||
|
||
import { poolRoutes } from "./pool"; | ||
import { utilsRoutes } from "./utils"; | ||
import { routerRoutes } from "./router"; | ||
import { baseRoutes } from "./base"; | ||
|
||
export const sdkServer = async (): Promise<FastifyInstance> => { | ||
const server = fastify(); | ||
|
||
// Initialize SDK | ||
let configJson: Record<string, any> = {}; | ||
|
||
try { | ||
configJson = JSON.parse(process.env.NXTP_CONFIG || ""); | ||
} catch (e: unknown) { | ||
console.info("No NXTP_CONFIG exists, using config file and individual env vars"); | ||
} | ||
|
||
if (Object.keys(configJson).length === 0) { | ||
try { | ||
const path = process.env.NXTP_CONFIG_FILE ?? "config.json"; | ||
if (fs.existsSync(path)) { | ||
const json = fs.readFileSync(path, { encoding: "utf-8" }); | ||
configJson = JSON.parse(json); | ||
console.info("Using config file"); | ||
} | ||
} catch (e: unknown) { | ||
console.error("Error reading config file!"); | ||
process.exit(1); | ||
} | ||
} | ||
|
||
const signer = ethers.Wallet.createRandom(); | ||
const signerAddress = await signer.getAddress(); | ||
|
||
const configuredProviders: Record<string, providers.JsonRpcProvider> = {}; | ||
const chains = configJson.chains; | ||
for (const key in chains) { | ||
const chain = chains[key]; | ||
const url = await getBestProvider(chain.providers as string[]); | ||
const provider = new ethers.providers.JsonRpcProvider(url); | ||
configuredProviders[key] = provider; | ||
} | ||
|
||
const nxtpConfig: SdkConfig = { | ||
chains: chains, | ||
logLevel: configJson.logLevel || "info", | ||
signerAddress: signerAddress, | ||
network: configJson.network, | ||
environment: configJson.environment, | ||
cartographerUrl: configJson.cartographerUrl, | ||
}; | ||
|
||
const { sdkBase, sdkPool, sdkUtils, sdkRouter } = await create(nxtpConfig); | ||
|
||
// Register Redis plugin if enabled | ||
if (configJson.cache?.enabled) { | ||
server.register(fastifyRedis, { | ||
host: configJson.cache?.host || "localhost", | ||
port: configJson.cache?.port || 6379, | ||
}); | ||
} | ||
|
||
// Register routes | ||
server.get("/ping", async (_, reply) => { | ||
return reply.status(200).send("pong\n"); | ||
}); | ||
|
||
server.post<{ | ||
Params: { domainId: string }; | ||
Body: providers.TransactionRequest; | ||
}>("/sendTransaction/:domainId", async (request, reply) => { | ||
const feeData = await configuredProviders[request.params.domainId].getFeeData(); | ||
// request.body.gasLimit = ethers.BigNumber.from("20000"); | ||
request.body.gasPrice = feeData.gasPrice!; | ||
const txRes = await signer.connect(configuredProviders[request.params.domainId]).sendTransaction(request.body); | ||
const txRec = await txRes.wait(); | ||
reply.status(200).send(txRec); | ||
}); | ||
|
||
server.register(baseRoutes, { sdkBaseInstance: sdkBase, cacheConfig: configJson.cache }); | ||
server.register(poolRoutes, sdkPool); | ||
server.register(utilsRoutes, sdkUtils); | ||
server.register(routerRoutes, sdkRouter); | ||
|
||
server.listen({ port: 8080 }, (err, address) => { | ||
if (err) { | ||
console.error(err); | ||
process.exit(1); | ||
} | ||
console.log(`Server listening at ${address}`); | ||
}); | ||
return server; | ||
}; | ||
|
||
sdkServer(); | ||
makeSdkServer(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.