diff --git a/backend/src/config.ts b/backend/src/config.ts index 87954b77..7b44ab5b 100644 --- a/backend/src/config.ts +++ b/backend/src/config.ts @@ -6,7 +6,7 @@ export default { region: process.env.AWS_REGION ?? 'us-east-2' }, tokenDispenserProgramId: () => process.env.TOKEN_DISPENSER_PROGRAM_ID, - keys: { + secrets: { dispenserGuard: { /** optional. mostly for local testing */ key: process.env.DISPENSER_WALLET_KEY, @@ -21,13 +21,19 @@ export default { secretName: process.env.FUNDER_WALLET_KEY_SECRET_NAME ?? 'xli-test-secret-funder-wallet' + }, + influx: { + key: () => process.env.INFLUXDB_TOKEN, + /** required. with a default value */ + secretName: process.env.IDB_SECRET_NAME ?? 'xl-ad-idb' } }, influx: { url: () => process.env.INFLUXDB_URL ?? 'http://localhost:8086', org: () => process.env.INFLUXDB_ORG ?? 'xl', bucket: () => process.env.INFLUXDB_BUCKET ?? 'ad', - token: () => process.env.INFLUXDB_TOKEN ?? 'token', - timeout: () => parseInt(process.env.INFLUXDB_TIMEOUT_MS ?? '20500') + token: () => process.env.INFLUXDB_TOKEN, + timeout: () => parseInt(process.env.INFLUXDB_TIMEOUT_MS ?? '20500'), + isFlushEnabled: () => process.env.INFLUXDB_FLUSH_ENABLED === 'true' ?? false } } diff --git a/backend/src/utils/persistence.ts b/backend/src/utils/persistence.ts index d95be2f4..92aaeb83 100644 --- a/backend/src/utils/persistence.ts +++ b/backend/src/utils/persistence.ts @@ -1,4 +1,4 @@ -import { InfluxDB, Point } from '@influxdata/influxdb-client' +import { InfluxDB, Point, WriteApi } from '@influxdata/influxdb-client' import base32 from 'hi-base32' import { rawSecp256k1PubkeyToRawAddress } from '@cosmjs/amino' import { Secp256k1 } from '@cosmjs/crypto' @@ -6,22 +6,20 @@ import { toBech32 } from '@cosmjs/encoding' import config from '../config' import { ClaimSignature } from '../types' import { PublicKey } from '@solana/web3.js' +import { getInfluxToken } from './secrets' -const OSMOSIS_ADDRESS_PREFIX = 'osmo' const EVM_WALLET_ADDRESS_PREFIX = '0x' -const TERRA_ADDRESS_PREFIX = 'terra' const INJECTIVE_ADDRESS_PREFIX = 'inj' +let influxWriter: WriteApi + export async function saveSignedTransactions( claimSignatures: ClaimSignature[] ) { try { - const influxWriter = new InfluxDB({ - url: config.influx.url(), - token: config.influx.token(), - timeout: config.influx.timeout() - }).getWriteApi(config.influx.org(), config.influx.bucket()) - + if (!influxWriter) { + influxWriter = await initInfluxWriter() + } const points = claimSignatures.map((claimSignature) => { const { ecosystem, subEcosystem, identity } = mapIdentity(claimSignature) return new Point('ad_signatures') @@ -32,9 +30,10 @@ export async function saveSignedTransactions( .stringField('identity', identity) .floatField('amount', claimSignature.instruction?.amount?.toNumber()) }) - influxWriter.writePoints(points) - await influxWriter.close() + if (config.influx.isFlushEnabled()) { + await influxWriter.flush() + } } catch (err) { console.error('Error saving signed transactions', err) } @@ -66,26 +65,16 @@ function mapIdentity(claimSignature: ClaimSignature) { ).toString('hex') break } - case 'osmosis': { + case 'cosmwasm': { const pubkey = claimSignature.instruction?.proofOfIdentity?.cosmwasm ?.pubkey as unknown as Uint8Array const compressed = Secp256k1.compressPubkey(pubkey) - identity = toBech32( - OSMOSIS_ADDRESS_PREFIX, - rawSecp256k1PubkeyToRawAddress(compressed) - ) + const chainId = + claimSignature.instruction?.proofOfIdentity?.cosmwasm?.chainId ?? 'osmo' + identity = toBech32(chainId, rawSecp256k1PubkeyToRawAddress(compressed)) - subEcosystem = 'osmosis' - break - } - case 'terra': { - identity = - TERRA_ADDRESS_PREFIX + - Buffer.from( - claimSignature.instruction?.proofOfIdentity?.cosmwasm?.pubkey ?? [] - ).toString('hex') - subEcosystem = 'terra' + subEcosystem = chainId break } case 'injective': { @@ -125,3 +114,15 @@ function mapIdentity(claimSignature: ClaimSignature) { return { ecosystem, subEcosystem, identity } } + +async function initInfluxWriter() { + const token = await getInfluxToken() + return new InfluxDB({ + url: config.influx.url(), + token + }).getWriteApi(config.influx.org(), config.influx.bucket(), 'ms') +} + +process.on('SIGTERM', async () => { + await influxWriter.close() +}) diff --git a/backend/src/utils/secrets.ts b/backend/src/utils/secrets.ts index aabc3183..9939649c 100644 --- a/backend/src/utils/secrets.ts +++ b/backend/src/utils/secrets.ts @@ -9,11 +9,11 @@ const client = new SecretsManagerClient({ region: config.aws.region }) export async function getDispenserKey() { let key: string - if (config.keys.dispenserGuard.key) { + if (config.secrets.dispenserGuard.key) { console.log('Using dispenser guard key from config') - key = config.keys.dispenserGuard.key + key = config.secrets.dispenserGuard.key } else { - key = await getSecretKey(config.keys.dispenserGuard.secretName, 'key') + key = await getSecretKey(config.secrets.dispenserGuard.secretName, 'key') } return { key: JSON.parse(key) } @@ -21,16 +21,28 @@ export async function getDispenserKey() { export async function getFundingKey(): Promise<{ key: Uint8Array }> { let key: string - if (config.keys.funding.key()) { + if (config.secrets.funding.key()) { console.log('Using funding key from config') - key = config.keys.funding.key()! + key = config.secrets.funding.key()! } else { - key = await getSecretKey(config.keys.funding.secretName, 'key') + key = await getSecretKey(config.secrets.funding.secretName, 'key') } return { key: JSON.parse(key) } } +export async function getInfluxToken(): Promise { + let key: string + if (config.secrets.influx.key()) { + console.log('Using influx token from config') + key = config.secrets.influx.key()! + } else { + key = await getSecretKey(config.secrets.influx.secretName, 'key') + } + + return key +} + export async function getSecretKey(secretName: string, keyName: string) { const secret = await getSecret(secretName) return secret[keyName] diff --git a/backend/test/handlers/fund-transactions.test.ts b/backend/test/handlers/fund-transactions.test.ts index 6654f12e..0784df04 100644 --- a/backend/test/handlers/fund-transactions.test.ts +++ b/backend/test/handlers/fund-transactions.test.ts @@ -19,7 +19,7 @@ import { AnchorProvider, IdlTypes, Program, BN } from '@coral-xyz/anchor' import NodeWallet from '@coral-xyz/anchor/dist/cjs/nodewallet' import { IDL, TokenDispenser } from '../../src/token-dispenser' import { fundTransactions } from '../../src/handlers/fund-transactions' -import { GenericContainer, StartedTestContainer, Wait } from 'testcontainers' +import { GenericContainer, StartedTestContainer } from 'testcontainers' import { InfluxDB } from '@influxdata/influxdb-client' const RANDOM_BLOCKHASH = 'HXq5QPm883r7834LWwDpcmEM8G8uQ9Hqm1xakCHGxprV' @@ -54,10 +54,11 @@ describe('fundTransactions integration test', () => { process.env.INFLUXDB_URL = `http://${startedInflux.getHost()}:${startedInflux.getMappedPort( 8086 )}` + process.env.INFLUXDB_FLUSH_ENABLED = 'true' process.env.FUNDING_WALLET_KEY = `[${FUNDER_KEY.secretKey}]` process.env.TOKEN_DISPENSER_PROGRAM_ID = PROGRAM_ID.toString() - }, 15_000) + }, 20_000) afterAll(async () => { await startedInflux.stop()