service: llama-apy package: individually: true frameworkVersion: '3' provider: name: aws runtime: nodejs16.x stage: dev region: eu-central-1 tracing: apiGateway: true lambda: true memorySize: 512 iam: role: statements: - Effect: Allow Action: - xray:PutTraceSegments - xray:PutTelemetryRecords Resource: '*' - Effect: Allow Action: - s3:ListBucket - s3:*Object* - sqs:SendMessage Resource: '*' environment: # for api handlers APIG_URL: { 'Fn::Join': [ '', [ 'https://', { Ref: 'HttpApi' }, '.execute-api.', { Ref: 'AWS::Region' }, '.', { Ref: 'AWS::URLSuffix' }, ], ], } BUCKET_DATA: { Ref: BucketData } DATABASE_URL: ${file(./env.js):DATABASE_URL} httpApi: metrics: true functions: # ---------- TRIGGER HANDLERS # --- top-lvl-entrypoint triggerEntrypoint: handler: src/handlers/triggerEntrypoint.handler description: Lambda to launch the adaptor pipeline timeout: 30 events: # every new hour - schedule: cron(0 * * * ? *) environment: ADAPTER_QUEUE_URL: { Ref: AdapterQueue } # --- adaptors triggerAdaptor: handler: src/handlers/triggerAdaptor.handler description: Lambda which runs adaptors timeout: 600 events: - sqs: arn: Fn::GetAtt: - AdapterQueue - Arn batchSize: 2 functionResponseType: ReportBatchItemFailures environment: ALCHEMY_CONNECTION_ARBITRUM: ${file(./env.js):ALCHEMY_CONNECTION_ARBITRUM} ALCHEMY_CONNECTION_ETHEREUM: ${file(./env.js):ALCHEMY_CONNECTION_ETHEREUM} ETHEREUM_RPC: ${file(./env.js):ETHEREUM_RPC} XDAI_RPC: ${file(./env.js):XDAI_RPC} CRONOS_RPC: ${file(./env.js):CRONOS_RPC} FANTOM_RPC: ${file(./env.js):FANTOM_RPC} OPTIMISM_RPC: ${file(./env.js):OPTIMISM_RPC} AVAX_RPC: ${file(./env.js):AVAX_RPC} TVL_SPIKE_WEBHOOK: ${file(./env.js):TVL_SPIKE_WEBHOOK} NEW_YIELDS_WEBHOOK: ${file(./env.js):NEW_YIELDS_WEBHOOK} # --- data enrichment triggerEnrichment: handler: src/handlers/triggerEnrichment.handler description: Lambda which runs enrichment process timeout: 300 events: # every hour at 20 past - schedule: cron(20 * * * ? *) # --- stats update triggerStat: handler: src/handlers/triggerStat.handler description: Lambda which updates the stat table timeout: 300 events: # 30min prior midnight - schedule: cron(30 23 * * ? *) # --- median insert triggerMedian: handler: src/handlers/triggerMedian.handler description: Lambda which inserts latest value into the median table timeout: 300 events: # 30min prior midnight - schedule: cron(30 23 * * ? *) # --- save poolsEnriched as CSV triggerCsv: handler: src/handlers/triggerCsv.handler description: Lambda which saves poolsEnriched as csv to s3 bucket timeout: 300 events: # every hour at 25 past - schedule: cron(25 * * * ? *) # --- trigger monitor triggerMonitor: handler: src/handlers/triggerMonitor.handler description: Lambda which triggers the monitor query for logging stale adapters timeout: 300 events: # every hour at 30 past - schedule: cron(30 * * * ? *) environment: STALE_PROJECTS_WEBHOOK: ${file(./env.js):STALE_PROJECTS_WEBHOOK} # --- trigger perpetuals triggerPerpertuals: handler: src/handlers/triggerPerpetuals.handler description: Lambda which triggers perp files timeout: 300 events: # every new hour - schedule: cron(0 * * * ? *) # ---------- GET HANDLERS getPoolsEnriched: handler: src/handlers/getPoolsEnriched.handler description: Lambda for retrieving the latest enriched data for each unique pool timeout: 20 events: - httpApi: method: get path: /poolsEnriched - httpApi: method: get path: /pools # includes old pool values getPoolsEnrichedOld: handler: src/handlers/getPoolsEnrichedOld.handler description: Lambda for retrieving the latest enriched data for each unique pool (includes old pool values) timeout: 20 events: - httpApi: method: get path: /poolsOld getChart: handler: src/handlers/getChart.handler description: Lambda for retrieving chart data for a particular pool timeout: 20 events: - httpApi: method: get path: /chart/{configID} getMedian: handler: src/handlers/getMedian.handler description: Lambda for retrieving daily median apy's timeout: 20 events: - httpApi: method: get path: /median getUrl: handler: src/handlers/getUrl.handler description: Lambda for retrieving project url's timeout: 20 events: - httpApi: method: get path: /url getDistinctID: handler: src/handlers/getDistinctID.handler description: Lambda for retrieving unique pool id's timeout: 20 events: - httpApi: method: get path: /distinctID getLendBorrow: handler: src/handlers/getLendBorrow.handler description: Lambda for retrieving lending + borrow data timeout: 20 events: - httpApi: method: get path: /lendBorrow getHistoryLendBorrow: handler: src/handlers/getHistoryLendBorrow.handler description: Lambda for retrieving chart data for a particular pool timeout: 20 events: - httpApi: method: get path: /chartLendBorrow/{configID} getConfigPool: handler: src/handlers/getConfigPool.handler description: Lambda for retrieving config data of configIDs timeout: 20 events: - httpApi: method: get path: /configPool/{configID} getPerp: handler: src/handlers/getPerp.handler description: Lambda for retrieving latest perp data timeout: 20 events: - httpApi: method: get path: /perps getLSDRates: handler: src/handlers/getLSDRates.handler description: Lambda for retrieving ETH LSD Rates timeout: 30 events: - httpApi: method: get path: /lsdRates resources: Resources: # QUEUES # --- queue for adaptor handler AdapterQueue: Type: AWS::SQS::Queue Properties: QueueName: ${self:service}-${self:custom.stage}-AdapterQueue VisibilityTimeout: 660 # setting this to 9hours MessageRetentionPeriod: 32400 RedrivePolicy: deadLetterTargetArn: Fn::GetAtt: - DeadLetterQueue - Arn # this params is requried, otherwise cloudformation error # means that after 3 failed runs, the message will be moved from the adaptor queue # to the DLQ maxReceiveCount: 3 # --- DLQ DeadLetterQueue: Type: AWS::SQS::Queue Properties: QueueName: ${self:service}-${self:custom.stage}-DeadLetterQueue # leaving this at max, 14days, after that msg in there will be deleted MessageRetentionPeriod: 1209600 # --- create bucket BucketData: Type: AWS::S3::Bucket Properties: BucketName: ${self:service}-${self:custom.stage}-data # --- alarm stuff for DLQ DlqAlarm: Type: AWS::CloudWatch::Alarm Properties: AlarmName: ${self:service}-${self:custom.stage}-AdapterDLQ AlarmDescription: There are failed messages in the dead letter queue. Namespace: AWS/SQS MetricName: ApproximateNumberOfMessagesVisible Dimensions: - Name: QueueName Value: !GetAtt DeadLetterQueue.QueueName Statistic: Sum Period: 60 EvaluationPeriods: 1 Threshold: 0 ComparisonOperator: GreaterThanThreshold AlarmActions: - !Ref DlqAlarmEmail DlqAlarmEmail: Type: AWS::SNS::Topic Properties: Subscription: - Endpoint: slasher125@protonmail.com Protocol: email custom: stage: ${opt:stage, self:provider.stage} webpack: webpackConfig: 'webpack.config.js' includeModules: true packager: 'npm' excludeFiles: src/**/*.test.js prune: automatic: true number: 5 plugins: - serverless-webpack - serverless-prune-plugin